Project/Real_code/gnu/coreutils-5.0/src/du.c
static int
process_file (const char *file, const struct stat *sb, int file_type,
	      struct FTW *info)
{
  uintmax_t size;
  uintmax_t size_to_print;
  static int first_call = 1;
  static size_t prev_level;
  static size_t n_alloc;
  static uintmax_t *sum_ent;
  static uintmax_t *sum_subdir;
  int print = 1;

  /* Always define info->skip before returning.  */
  info->skip = excluded_filename (exclude, file + info->base);

  switch (file_type)
    {
    case FTW_NS:
      error (0, errno, _("cannot access %s"), quote (file));
      G_fail = 1;
      return 0;

    case FTW_DCHP:
      error (0, errno, _("cannot change to parent of directory %s"),
	     quote (file));
      G_fail = 1;
      return 0;

    case FTW_DCH:
      /* Don't return just yet, since although nftw couldn't chdir into the
	 directory, it was able to stat it, so we do have a size.  */
      error (0, errno, _("cannot change to directory %s"), quote (file));
      G_fail = 1;
      break;

    case FTW_DNR:
      /* Don't return just yet, since although nftw couldn't read the
	 directory, it was able to stat it, so we do have a size.  */
      error (0, errno, _("cannot read directory %s"), quote (file));
      G_fail = 1;
      break;

    default:
      break;
    }

  /* If this is the first (pre-order) encounter with a directory,
     return right away.  */
  if (file_type == FTW_DPRE)
    return 0;

  /* If the file is being excluded or if it has already been counted
     via a hard link, then don't let it contribute to the sums.  */
  if (info->skip
      || (!opt_count_all
	  && 1 < sb->st_nlink
	  && hash_ins (sb->st_ino, sb->st_dev)))
    {
      /* Note that we must not simply return here.
	 We still have to update prev_level and maybe propagate
	 some sums up the hierarchy.  */
      size = 0;
      print = 0;
    }
  else
    {
      size = (apparent_size
	      ? sb->st_size
	      : ST_NBLOCKS (*sb) * ST_NBLOCKSIZE);
    }

  if (first_call)
    {
      n_alloc = info->level + 10;
      sum_ent = XCALLOC (uintmax_t, n_alloc);
      sum_subdir = XCALLOC (uintmax_t, n_alloc);
    }
  else
    {
      /* FIXME: it's a shame that we need these `size_t' casts to avoid
	 warnings from gcc about `comparison between signed and unsigned'.
	 Probably unavoidable, assuming that the members of struct FTW
	 are of type `int' (historical), since I want variables like
	 n_alloc and prev_level to have types that make sense.  */
      if (n_alloc <= (size_t) info->level)
	{
	  n_alloc = info->level * 2;
	  sum_ent = XREALLOC (sum_ent, uintmax_t, n_alloc);
	  sum_subdir = XREALLOC (sum_subdir, uintmax_t, n_alloc);
	}
    }

  size_to_print = size;

  if (! first_call)
    {
      if ((size_t) info->level == prev_level)
	{
	  /* This is usually the most common case.  Do nothing.  */
	}
      else if ((size_t) info->level > prev_level)
	{
	  /* Descending the hierarchy.
	     Clear the accumulators for *all* levels between prev_level
	     and the current one.  The depth may change dramatically,
	     e.g., from 1 to 10.  */
	  int i;
	  for (i = prev_level + 1; i <= info->level; i++)
	    sum_ent[i] = sum_subdir[i] = 0;
	}
      else /* info->level < prev_level */
	{
	  /* Ascending the hierarchy.
	     nftw processes a directory only after all entries in that
	     directory have been processed.  When the depth decreases,
	     propagate sums from the children (prev_level) to the parent.
	     Here, the current level is always one smaller than the
	     previous one.  */
	  assert ((size_t) info->level == prev_level - 1);
	  size_to_print += sum_ent[prev_level];
	  if (!opt_separate_dirs)
	    size_to_print += sum_subdir[prev_level];
	  sum_subdir[info->level] += (sum_ent[prev_level]
				      + sum_subdir[prev_level]);
	}
    }

  prev_level = info->level;
  first_call = 0;

  /* Let the size of a directory entry contribute to the total for the
     containing directory, unless --separate-dirs (-S) is specified.  */
  if ( ! (opt_separate_dirs && IS_FTW_DIR_TYPE (file_type)))
    sum_ent[info->level] += size;

  /* Even if this directory is unreadable or we can't chdir into it,
     do let its size contribute to the total, ... */
  tot_size += size;

  /* ... but don't print out a total for it, since without the size(s)
     of any potential entries, it could be very misleading.  */
  if (file_type == FTW_DNR || file_type == FTW_DCH)
    return 0;

  /* If we're not counting an entry, e.g., because it's a hard link
     to a file we've already counted (and --count-links), then don't
     print a line for it.  */
  if (!print)
    return 0;

  /* FIXME: This looks suspiciously like it could be simplified.  */
  if ((IS_FTW_DIR_TYPE (file_type) &&
		     (info->level <= max_depth || info->level == 0))
      || ((opt_all && info->level <= max_depth) || info->level == 0))
    {
      print_only_size (size_to_print);
      fputc ('\t', stdout);
      if (arg_length)
	{
	  /* Print the file name, but without the `.' or `/.'
	     directory suffix that we may have added in main.  */
	  /* Print everything before the part we appended.  */
	  fwrite (file, arg_length, 1, stdout);
	  /* Print everything after what we appended.  */
	  fputs (file + arg_length + suffix_length
		 + (file[arg_length + suffix_length] == '/'), stdout);
	}
      else
	{
	  fputs (file, stdout);
	}
      fputc ('\n', stdout);
      fflush (stdout);
    }

  return 0;
}
/* This function is called once for every file system object that nftw
   encounters.  nftw does a depth-first traversal.  This function knows
   that and accumulates per-directory totals based on changes in
   the depth of the current entry.  */
This function is called once for every file system object that nftw
encounters.  nftw does a depth-first traversal.  This function knows
that and accumulates per-directory totals based on changes in
the depth of the current entry.
This function is called once for every file system object that nftw encounters . nftw does a depth - first traversal . This function knows that and accumulates per - directory totals based on changes in the depth of the current entry .
static int
process_file (const char *file, const struct stat *sb, int file_type,
	      struct FTW *info)
{
  uintmax_t size;
  uintmax_t size_to_print;
  static int first_call = 1;
  static size_t prev_level;
  static size_t n_alloc;
  static uintmax_t *sum_ent;
  static uintmax_t *sum_subdir;
  int print = 1;
  info->skip = excluded_filename (exclude, file + info->base);
  switch (file_type)
    {
    case FTW_NS:
      error (0, errno, _("cannot access %s"), quote (file));
      G_fail = 1;
      return 0;
    case FTW_DCHP:
      error (0, errno, _("cannot change to parent of directory %s"),
	     quote (file));
      G_fail = 1;
      return 0;
    case FTW_DCH:
      error (0, errno, _("cannot change to directory %s"), quote (file));
      G_fail = 1;
      break;
    case FTW_DNR:
      error (0, errno, _("cannot read directory %s"), quote (file));
      G_fail = 1;
      break;
    default:
      break;
    }
  if (file_type == FTW_DPRE)
    return 0;
  if (info->skip
      || (!opt_count_all
	  && 1 < sb->st_nlink
	  && hash_ins (sb->st_ino, sb->st_dev)))
    {
      size = 0;
      print = 0;
    }
  else
    {
      size = (apparent_size
	      ? sb->st_size
	      : ST_NBLOCKS (*sb) * ST_NBLOCKSIZE);
    }
  if (first_call)
    {
      n_alloc = info->level + 10;
      sum_ent = XCALLOC (uintmax_t, n_alloc);
      sum_subdir = XCALLOC (uintmax_t, n_alloc);
    }
  else
    {
      if (n_alloc <= (size_t) info->level)
	{
	  n_alloc = info->level * 2;
	  sum_ent = XREALLOC (sum_ent, uintmax_t, n_alloc);
	  sum_subdir = XREALLOC (sum_subdir, uintmax_t, n_alloc);
	}
    }
  size_to_print = size;
  if (! first_call)
    {
      if ((size_t) info->level == prev_level)
	{
	}
      else if ((size_t) info->level > prev_level)
	{
	  int i;
	  for (i = prev_level + 1; i <= info->level; i++)
	    sum_ent[i] = sum_subdir[i] = 0;
	}
      else 
	{
	  assert ((size_t) info->level == prev_level - 1);
	  size_to_print += sum_ent[prev_level];
	  if (!opt_separate_dirs)
	    size_to_print += sum_subdir[prev_level];
	  sum_subdir[info->level] += (sum_ent[prev_level]
				      + sum_subdir[prev_level]);
	}
    }
  prev_level = info->level;
  first_call = 0;
  if ( ! (opt_separate_dirs && IS_FTW_DIR_TYPE (file_type)))
    sum_ent[info->level] += size;
  tot_size += size;
  if (file_type == FTW_DNR || file_type == FTW_DCH)
    return 0;
  if (!print)
    return 0;
  if ((IS_FTW_DIR_TYPE (file_type) &&
		     (info->level <= max_depth || info->level == 0))
      || ((opt_all && info->level <= max_depth) || info->level == 0))
    {
      print_only_size (size_to_print);
      fputc ('\t', stdout);
      if (arg_length)
	{
	  fwrite (file, arg_length, 1, stdout);
	  fputs (file + arg_length + suffix_length
		 + (file[arg_length + suffix_length] == '/'), stdout);
	}
      else
	{
	  fputs (file, stdout);
	}
      fputc ('\n', stdout);
      fflush (stdout);
    }
  return 0;
}
static int process_file ( const char * file , const struct stat * sb , int file_type , struct FTW * info ) { uintmax_t size ; uintmax_t size_to_print ; static int first_call = 1 ; static size_t prev_level ; static size_t n_alloc ; static uintmax_t * sum_ent ; static uintmax_t * sum_subdir ; int print = 1 ; info -> skip = excluded_filename ( exclude , file + info -> base ) ; switch ( file_type ) { case FTW_NS : error ( 0 , errno , _ ( " " ) , quote ( file ) ) ; G_fail = 1 ; return 0 ; case FTW_DCHP : error ( 0 , errno , _ ( " " ) , quote ( file ) ) ; G_fail = 1 ; return 0 ; case FTW_DCH : error ( 0 , errno , _ ( " " ) , quote ( file ) ) ; G_fail = 1 ; break ; case FTW_DNR : error ( 0 , errno , _ ( " " ) , quote ( file ) ) ; G_fail = 1 ; break ; default : break ; } if ( file_type == FTW_DPRE ) return 0 ; if ( info -> skip || ( ! opt_count_all && 1 < sb -> st_nlink && hash_ins ( sb -> st_ino , sb -> st_dev ) ) ) { size = 0 ; print = 0 ; } else { size = ( apparent_size ? sb -> st_size : ST_NBLOCKS ( * sb ) * ST_NBLOCKSIZE ) ; } if ( first_call ) { n_alloc = info -> level + 10 ; sum_ent = XCALLOC ( uintmax_t , n_alloc ) ; sum_subdir = XCALLOC ( uintmax_t , n_alloc ) ; } else { if ( n_alloc <= ( size_t ) info -> level ) { n_alloc = info -> level * 2 ; sum_ent = XREALLOC ( sum_ent , uintmax_t , n_alloc ) ; sum_subdir = XREALLOC ( sum_subdir , uintmax_t , n_alloc ) ; } } size_to_print = size ; if ( ! first_call ) { if ( ( size_t ) info -> level == prev_level ) { } else if ( ( size_t ) info -> level > prev_level ) { int i ; for ( i = prev_level + 1 ; i <= info -> level ; i ++ ) sum_ent [ i ] = sum_subdir [ i ] = 0 ; } else { assert ( ( size_t ) info -> level == prev_level - 1 ) ; size_to_print += sum_ent [ prev_level ] ; if ( ! opt_separate_dirs ) size_to_print += sum_subdir [ prev_level ] ; sum_subdir [ info -> level ] += ( sum_ent [ prev_level ] + sum_subdir [ prev_level ] ) ; } } prev_level = info -> level ; first_call = 0 ; if ( ! ( opt_separate_dirs && IS_FTW_DIR_TYPE ( file_type ) ) ) sum_ent [ info -> level ] += size ; tot_size += size ; if ( file_type == FTW_DNR || file_type == FTW_DCH ) return 0 ; if ( ! print ) return 0 ; if ( ( IS_FTW_DIR_TYPE ( file_type ) && ( info -> level <= max_depth || info -> level == 0 ) ) || ( ( opt_all && info -> level <= max_depth ) || info -> level == 0 ) ) { print_only_size ( size_to_print ) ; fputc ( ' \t ' , stdout ) ; if ( arg_length ) { fwrite ( file , arg_length , 1 , stdout ) ; fputs ( file + arg_length + suffix_length + ( file [ arg_length + suffix_length ] == ' ' ) , stdout ) ; } else { fputs ( file , stdout ) ; } fputc ( ' \n ' , stdout ) ; fflush ( stdout ) ; } return 0 ; }
This function is called once for every file system object that nftw
encounters.
This function is called once for every file system object that nftw encounters .
/* Always define info->skip before returning.  */ /* Don't return just yet, since although nftw couldn't chdir into the
	 directory, it was able to stat it, so we do have a size.  */ /* Don't return just yet, since although nftw couldn't read the
	 directory, it was able to stat it, so we do have a size.  */ /* If this is the first (pre-order) encounter with a directory,
     return right away.  */ /* If the file is being excluded or if it has already been counted
     via a hard link, then don't let it contribute to the sums.  */ /* Note that we must not simply return here.
	 We still have to update prev_level and maybe propagate
	 some sums up the hierarchy.  */ /* FIXME: it's a shame that we need these `size_t' casts to avoid
	 warnings from gcc about `comparison between signed and unsigned'.
	 Probably unavoidable, assuming that the members of struct FTW
	 are of type `int' (historical), since I want variables like
	 n_alloc and prev_level to have types that make sense.  */ /* This is usually the most common case.  Do nothing.  */ /* Descending the hierarchy.
	     Clear the accumulators for *all* levels between prev_level
	     and the current one.  The depth may change dramatically,
	     e.g., from 1 to 10.  */ /* info->level < prev_level */ /* Ascending the hierarchy.
	     nftw processes a directory only after all entries in that
	     directory have been processed.  When the depth decreases,
	     propagate sums from the children (prev_level) to the parent.
	     Here, the current level is always one smaller than the
	     previous one.  */ /* Let the size of a directory entry contribute to the total for the
     containing directory, unless --separate-dirs (-S) is specified.  */ /* Even if this directory is unreadable or we can't chdir into it,
     do let its size contribute to the total, ... */ /* ... but don't print out a total for it, since without the size(s)
     of any potential entries, it could be very misleading.  */ /* If we're not counting an entry, e.g., because it's a hard link
     to a file we've already counted (and --count-links), then don't
     print a line for it.  */ /* FIXME: This looks suspiciously like it could be simplified.  */ /* Print the file name, but without the `.' or `/.'
	     directory suffix that we may have added in main.  */ /* Print everything before the part we appended.  */ /* Print everything after what we appended.  */