From: bde@runx.oz.AU (Bruce Evans)
Subject: du in fileutils-3.4 is confused by bad file system
Organization: RUNX Un*x Timeshare.  Sydney, Australia.
Distribution: gnu
Date: Sun, 8 Nov 1992 15:36:11 GMT

du in fileutils-3.4 does not check the value returned by some chdir system
calls.  This leads to irrelevant error messages when chdir("..") fails due
to a missing `..' entry.  There is no point in continuing, but du continues
and prints messages about directories that have become inaccessible.

du could continue if it avoided descending into directories which have no
`..' entry, but I don't think that's worth doing.  My fix justs adds some
error checking and reporting.  The error reports could be improved.  They
are now as follows.  (1) When the directory z is missing `..' but contains
`.':

    du: cannot change to `..' from directory ./z/: No such file or directory

It would be better to print `./z'.  (2)  When the directory z is missing
both `.' and `..':

    du: ./z: No such file or directory
    du: cannot change to `..' from directory ./z: No such file or directory

The first line has to do with `./z/.' being missing and is very misleading
(the error is detected at a lower level and the higher level doesn't
really know which path caused the problem).  The second line is OK except
./z should probably be quoted.

The diff below contains some other minor fixes for fileutils-3.4.

In eaccess.c, #undef NGROUPS_MAX in case it is being redefined.
In eaccess.c, NGROUPS_MAX has type long if it has been defined using sysconf,
and otherwise it has an unknown (?) integral type, so it may have too large
a type for calling xmalloc and/or getgroups.

diff -Nrc2 fileutils-3.4/lib/eaccess.c fileu/lib/eaccess.c
*** fileutils-3.4/lib/eaccess.c	Fri Sep 11 09:46:21 1992
--- fileu/lib/eaccess.c	Fri Nov  6 20:28:46 1992
***************
*** 28,31 ****
--- 28,32 ----
  #include <limits.h>
  #if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
+ #undef NGROUPS_MAX
  #define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
  #endif /* NGROUPS_MAX */
***************
*** 129,134 ****
        egid = getegid ();
  #ifdef NGROUPS_MAX
!       groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
!       ngroups = getgroups (NGROUPS_MAX, groups);
  #endif
      }
--- 130,136 ----
        egid = getegid ();
  #ifdef NGROUPS_MAX
!       groups = (GETGROUPS_T *)
! 	       xmalloc ((unsigned) (NGROUPS_MAX * sizeof (GETGROUPS_T)));
!       ngroups = getgroups ((int) NGROUPS_MAX, groups);
  #endif
      }
diff -Nrc2 fileutils-3.4/src/du.c fileu/src/du.c
*** fileutils-3.4/src/du.c	Fri May  1 03:55:02 1992
--- fileu/src/du.c	Fri Nov  6 20:53:25 1992
***************
*** 401,405 ****
  	    {
  	      error (0, errno, "%s", path->text);
! 	      chdir ("..");	/* Try to return to previous directory.  */
  	      exit_status = 1;
  	      return 0;
--- 401,407 ----
  	    {
  	      error (0, errno, "%s", path->text);
! 	      if (chdir (".."))	/* Try to return to previous directory.  */
! 		error (1, errno, "cannot change to `..' from directory %s",
! 		       path->text);
  	      exit_status = 1;
  	      return 0;
***************
*** 425,429 ****
  	}
        free (name_space);
!       chdir ("..");
  
        str_trunc (path, pathlen - 1); /* Remove the "/" we added.  */
--- 427,432 ----
  	}
        free (name_space);
!       if (chdir ("..") < 0)
!         error (1, errno, "cannot change to `..' from directory %s", path->text);
  
        str_trunc (path, pathlen - 1); /* Remove the "/" we added.  */
-- 
Bruce Evans  (bde@runx.oz.au)

Newsgroups: gnu.utils.bug