components/gzip/patches/gzip.c.patch
branchs11-update
changeset 2402 21ebf6c9a4fa
parent 2401 33c6af6b572f
child 2403 a4a5919f480b
equal deleted inserted replaced
2401:33c6af6b572f 2402:21ebf6c9a4fa
     1 --- gzip-1.4/gzip.c.orig	2012-04-16 11:27:08.478456051 -0700
       
     2 +++ gzip-1.4/gzip.c	2012-04-23 13:06:53.395234301 -0700
       
     3 @@ -1699,36 +1699,25 @@
       
     4      int fd;
       
     5      char *dir;
       
     6  {
       
     7 +    struct dirent **namelist;
       
     8      struct dirent *dp;
       
     9 -    DIR      *dirp;
       
    10      char     nbuf[MAX_PATH_LEN];
       
    11 -    int      len;
       
    12 +    int      len, n;
       
    13  
       
    14 -    dirp = fdopendir (fd);
       
    15 -
       
    16 -    if (dirp == NULL) {
       
    17 +    /* Adjusted to use scandir to prevent compressing files multiple times
       
    18 +     * on file systems that use a hash lookup for directory entries (such
       
    19 +     * as btrfs and ZFS.
       
    20 +     */
       
    21 +    if ((n = scandir(dir, &namelist, 0, NULL)) < 0) {
       
    22  	progerror(dir);
       
    23  	close (fd);
       
    24  	return ;
       
    25      }
       
    26 -    /*
       
    27 -     ** WARNING: the following algorithm could occasionally cause
       
    28 -     ** compress to produce error warnings of the form "<filename>.gz
       
    29 -     ** already has .gz suffix - ignored". This occurs when the
       
    30 -     ** .gz output file is inserted into the directory below
       
    31 -     ** readdir's current pointer.
       
    32 -     ** These warnings are harmless but annoying, so they are suppressed
       
    33 -     ** with option -r (except when -v is on). An alternative
       
    34 -     ** to allowing this would be to store the entire directory
       
    35 -     ** list in memory, then compress the entries in the stored
       
    36 -     ** list. Given the depth-first recursive algorithm used here,
       
    37 -     ** this could use up a tremendous amount of memory. I don't
       
    38 -     ** think it's worth it. -- Dave Mack
       
    39 -     ** (An other alternative might be two passes to avoid depth-first.)
       
    40 -     */
       
    41 -
       
    42 -    while ((errno = 0, dp = readdir(dirp)) != NULL) {
       
    43  
       
    44 +    while (n--) {
       
    45 +	if (errno != 0)
       
    46 +	    break;
       
    47 +	dp = namelist[n];
       
    48  	if (strequ(dp->d_name,".") || strequ(dp->d_name,"..")) {
       
    49  	    continue;
       
    50  	}
       
    51 @@ -1747,6 +1736,7 @@
       
    52  	    }
       
    53  	    strcpy(nbuf+len, dp->d_name);
       
    54  	    treat_file(nbuf);
       
    55 +	    free(dp);
       
    56  	} else {
       
    57  	    fprintf(stderr,"%s: %s/%s: pathname too long\n",
       
    58  		    program_name, dir, dp->d_name);
       
    59 @@ -1755,8 +1745,8 @@
       
    60      }
       
    61      if (errno != 0)
       
    62  	progerror(dir);
       
    63 -    if (CLOSEDIR(dirp) != 0)
       
    64 -	progerror(dir);
       
    65 +
       
    66 +    free(namelist);
       
    67  }
       
    68  #endif /* ! NO_DIR */
       
    69