?? du.c
字號:
&& 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 + -