⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 du.c

📁 Linux.Programming.by example 的源代码绝对经典
💻 C
📖 第 1 页 / 共 2 页
字号:
	  && 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;}static intis_symlink_to_dir (char const *file){  char *f;  struct stat sb;  ASSIGN_STRDUPA (f, file);  strip_trailing_slashes (f);  return (lstat (f, &sb) == 0 && S_ISLNK (sb.st_mode)	  && stat (f, &sb) == 0 && S_ISDIR (sb.st_mode));}/* Recursively print the sizes of the directories (and, if selected, files)   named in FILES, the last entry of which is NULL.   FTW_FLAGS controls how nftw works.   Return nonzero upon error.  */static intdu_files (char **files, int ftw_flags){  int fail = 0;  int i;  for (i = 0; files[i]; i++)    {      char *file = files[i];      char *orig = file;      int err;      arg_length = 0;      if (!print_totals)	hash_clear (htab);      /* When dereferencing only command line arguments, we're using	 nftw's FTW_PHYS flag, so a symlink-to-directory specified on	 the command line wouldn't normally be dereferenced.  To work	 around that, we incur the overhead of appending `/.' (or `.')	 now, and later removing it each time we output the name of	 a derived file or directory name.  */      if (opt_dereference_arguments && is_symlink_to_dir (file))	{	  size_t len = strlen (file);	  /* Append `/.', but if there's already a trailing slash,	     append only the `.'.  */	  char const *suffix = (file[len - 1] == '/' ? "." : "/.");	  char *new_file;	  suffix_length = strlen (suffix);	  new_file = xmalloc (len + suffix_length + 1);	  memcpy (mempcpy (new_file, file, len), suffix, suffix_length + 1);	  arg_length = len;	  file = new_file;	}      err = nftw (file, process_file, MAX_N_DESCRIPTORS, ftw_flags);      if (err)	error (0, errno, "%s", quote (orig));      fail |= err;      if (arg_length)	free (file);    }  if (print_totals)    print_size (tot_size, _("total"));  return fail;}intmain (int argc, char **argv){  int c;  char *cwd_only[2];  int max_depth_specified = 0;  char **files;  int fail;  /* Bit flags that control how nftw works.  */  int ftw_flags = FTW_DEPTH | FTW_PHYS | FTW_CHDIR;  /* If nonzero, display only a total for each argument. */  int opt_summarize_only = 0;  cwd_only[0] = ".";  cwd_only[1] = NULL;  program_name = argv[0];  setlocale (LC_ALL, "");  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  atexit (close_stdout);  exclude = new_exclude ();  human_output_opts = human_options (getenv ("DU_BLOCK_SIZE"), false,				     &output_block_size);  fail = 0;  while ((c = getopt_long (argc, argv, "abchHklmsxB:DLSX:", long_options, NULL))	 != -1)    {      long int tmp_long;      switch (c)	{	case 0:			/* Long option. */	  break;	case 'a':	  opt_all = 1;	  break;	case APPARENT_SIZE_OPTION:	  apparent_size = 1;	  break;	case 'b':	  apparent_size = 1;	  human_output_opts = 0;	  output_block_size = 1;	  break;	case 'c':	  print_totals = 1;	  break;	case 'h':	  human_output_opts = human_autoscale | human_SI | human_base_1024;	  output_block_size = 1;	  break;	case 'H':	  human_output_opts = human_autoscale | human_SI;	  output_block_size = 1;	  break;	case 'k':	  human_output_opts = 0;	  output_block_size = 1024;	  break;	case MAX_DEPTH_OPTION:		/* --max-depth=N */	  if (xstrtol (optarg, NULL, 0, &tmp_long, NULL) == LONGINT_OK	      && 0 <= tmp_long && tmp_long <= INT_MAX)	    {	      max_depth_specified = 1;	      max_depth = (int) tmp_long;	    }	  else	    {	      error (0, 0, _("invalid maximum depth %s"),		     quote (optarg));	      fail = 1;	    } 	  break;	case 'm': /* obsolescent */	  human_output_opts = 0;	  output_block_size = 1024 * 1024;	  break;	case 'l':	  opt_count_all = 1;	  break;	case 's':	  opt_summarize_only = 1;	  break;	case 'x':	  ftw_flags |= FTW_MOUNT;	  break;	case 'B':	  human_output_opts = human_options (optarg, true, &output_block_size);	  break;	case 'D':	  opt_dereference_arguments = 1;	  break;	case 'L':	  ftw_flags &= ~FTW_PHYS;	  break;	case 'S':	  opt_separate_dirs = 1;	  break;	case 'X':	  if (add_exclude_file (add_exclude, exclude, optarg,				EXCLUDE_WILDCARDS, '\n'))	    {	      error (0, errno, "%s", quotearg_colon (optarg));	      fail = 1;	    }	  break;	case EXCLUDE_OPTION:	  add_exclude (exclude, optarg, EXCLUDE_WILDCARDS);	  break;	case_GETOPT_HELP_CHAR;	case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);	default:	  fail = 1;	}    }  if (fail)    usage (EXIT_FAILURE);  if (opt_all && opt_summarize_only)    {      error (0, 0, _("cannot both summarize and show all entries"));      usage (EXIT_FAILURE);    }  if (opt_summarize_only && max_depth_specified && max_depth == 0)    {      error (0, 0,	     _("warning: summarizing is the same as using --max-depth=0"));    }  if (opt_summarize_only && max_depth_specified && max_depth != 0)    {      error (0, 0,	     _("warning: summarizing conflicts with --max-depth=%d"),	       max_depth);      usage (EXIT_FAILURE);    }  if (opt_summarize_only)    max_depth = 0;  files = (optind == argc ? cwd_only : argv + optind);  /* Initialize the hash structure for inode numbers.  */  hash_init ();  exit (du_files (files, ftw_flags) || G_fail	? EXIT_FAILURE : EXIT_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -