[comp.unix.i386] Unofficial patch for GNU tar 1.07, and advice

pcg@aber-cs.UUCP (Piercarlo Grandi) (01/06/90)

GNU tar seemed to have a problem whereby it would run out of file
descriptors after having visited a number of directories just under the
number of file desfriptors available.

I have checked therefore the source for cases where after na opendir() the
corresponding closedir() is not executed, and there seemed to be none.

Eventually I have determined that the problem is that under System V and ina
few other cases the closedir() procedure will first free the DIR struct and
then close the file descriptor whose number is contained in that struct.
This is very unsafe, because if the free() procedure munges the contents of
the freed area, which happens when it coalesces free blocks immediately,
instead of leaving the job to malloc(), the file descriptor number is
munged, and the close() call will fail.

To fix, either get a fixed version of closedir(), or, in desperation, use a
malloc() package where free() does not coalesce free blocks.

In the meantime I have found one real file descriptor leak, which occurs
when the header of a regular file cannot be obtained. Here is a suitable
patch.

A second patch is where "./" is stripped off pathnames. The existing code, I
think, will also strip patch names of the type dot followed by a single
nondot character, which are legal. Correction is easy.

===================================================================
RCS file: create.c,v
retrieving revision 1.1
diff -c -r1.1 create.c
*** /tmp/,RCSt1a22731	Sun Dec 24 20:04:54 1989
--- create.c	Sun Dec 24 19:57:08 1989
***************
*** 311,317 ****
  		}
  
  		header = start_header(p, &hstat);
! 		if (header == NULL) goto badfile;
  #ifdef S_IFCTG
  		/* Mark contiguous files, if we support them */
  		if (f_standard && (hstat.st_mode & S_IFMT) == S_IFCTG) {
--- 311,322 ----
  		}
  
  		header = start_header(p, &hstat);
! 		if (header == NULL)
! 		{
! 			if (f >= 0) (void) close(f);
! 			goto badfile;
! 		}
! 
  #ifdef S_IFCTG
  		/* Mark contiguous files, if we support them */
  		if (f_standard && (hstat.st_mode & S_IFMT) == S_IFCTG) {
***************
*** 446,452 ****
  		}
  
  		/* Hack to remove "./" from the front of all the file names */
! 		if (len == 2 && namebuf[0] == '.') {
  			len = 0;
  		}
  
--- 451,457 ----
  		}
  
  		/* Hack to remove "./" from the front of all the file names */
! 		if (len == 2 && namebuf[0] == '.' && namebuf[1] == '/') {
  			len = 0;
  		}


-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk