X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fdu.c;h=a1ca5b59b6cd73c2bedc9667ca471451ff6b05fa;hb=bbe514683a43e81cab1d5ccc0436b9aaf984294b;hp=1c16cfbd4e9a835a223a138000bc3e368bb2ec9f;hpb=393183dccc4d100366972bdbbdc6e03a77839120;p=oweals%2Fbusybox.git diff --git a/coreutils/du.c b/coreutils/du.c index 1c16cfbd4..a1ca5b59b 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -6,20 +6,7 @@ * Copyright (C) 1999,2000,2001 by John Beppu * Copyright (C) 2002 Edward Betts * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ /* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */ @@ -36,33 +23,24 @@ * 4) Fixed busybox bug #1284 involving long overflow with human_readable. */ -#include -#include -#include -#include -#include #include "busybox.h" -#ifdef CONFIG_FEATURE_HUMAN_READABLE -# ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K -static unsigned long disp_hr = KILOBYTE; +#if ENABLE_FEATURE_HUMAN_READABLE +# if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K +static unsigned long disp_hr = 1024; # else static unsigned long disp_hr = 512; # endif -#elif defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K -static unsigned int disp_k = 1; +#elif ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K +static unsigned disp_k = 1; #else -static unsigned int disp_k; /* bss inits to 0 */ +static unsigned disp_k; /* bss inits to 0 */ #endif static int max_print_depth = INT_MAX; -static int count_hardlinks = INT_MAX; +static nlink_t count_hardlinks = 1; -static int status -#if EXIT_SUCCESS == 0 - = EXIT_SUCCESS -#endif - ; +static int status; static int print_files; static int slink_depth; static int du_depth; @@ -70,24 +48,28 @@ static int one_file_system; static dev_t dir_dev; -static void print(long size, char *filename) +static void print(long size, const char * const filename) { /* TODO - May not want to defer error checking here. */ -#ifdef CONFIG_FEATURE_HUMAN_READABLE - bb_printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr), - filename); +#if ENABLE_FEATURE_HUMAN_READABLE + printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr), + filename); #else - bb_printf("%ld\t%s\n", size >> disp_k, filename); + if (disp_k) { + size++; + size >>= 1; + } + printf("%ld\t%s\n", size, filename); #endif } /* tiny recursive du */ -static long du(char *filename) +static long du(const char * const filename) { struct stat statbuf; long sum; - if ((lstat(filename, &statbuf)) != 0) { + if (lstat(filename, &statbuf) != 0) { bb_perror_msg("%s", filename); status = EXIT_FAILURE; return 0; @@ -105,7 +87,7 @@ static long du(char *filename) if (S_ISLNK(statbuf.st_mode)) { if (slink_depth > du_depth) { /* -H or -L */ - if ((stat(filename, &statbuf)) != 0) { + if (stat(filename, &statbuf) != 0) { bb_perror_msg("%s", filename); status = EXIT_FAILURE; return 0; @@ -130,9 +112,8 @@ static long du(char *filename) struct dirent *entry; char *newfile; - dir = opendir(filename); + dir = warn_opendir(filename); if (!dir) { - bb_perror_msg("%s", filename); status = EXIT_FAILURE; return sum; } @@ -145,7 +126,7 @@ static long du(char *filename) char *name = entry->d_name; newfile = concat_subpath_file(filename, name); - if(newfile == NULL) + if (newfile == NULL) continue; ++du_depth; sum += du(newfile); @@ -166,76 +147,77 @@ int du_main(int argc, char **argv) { long total; int slink_depth_save; - int print_final_total = 0; - int c; + int print_final_total; + char *smax_print_depth; + unsigned opt; -#ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K +#if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K if (getenv("POSIXLY_CORRECT")) { /* TODO - a new libbb function? */ -#ifdef CONFIG_FEATURE_HUMAN_READABLE +#if ENABLE_FEATURE_HUMAN_READABLE disp_hr = 512; #else disp_k = 0; #endif - } + } #endif - /* Note: SUSv3 specifies that -a and -s options can not be used together + /* Note: SUSv3 specifies that -a and -s options cannot be used together * in strictly conforming applications. However, it also says that some * du implementations may produce output when -a and -s are used together. * gnu du exits with an error code in this case. We choose to simply * ignore -a. This is consistent with -s being equivalent to -d 0. */ - - while ((c = getopt(argc, argv, "aHkLsx" "d:" "lc" -#ifdef CONFIG_FEATURE_HUMAN_READABLE - "hm" -#endif - )) > 0) { - switch (c) { - case 'a': - print_files = INT_MAX; - break; - case 'H': - slink_depth = 1; - break; - case 'k': -#ifdef CONFIG_FEATURE_HUMAN_READABLE - disp_hr = KILOBYTE; -#elif !defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K - disp_k = 1; +#if ENABLE_FEATURE_HUMAN_READABLE + opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; + opt = getopt32(argc, argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth); + if (opt & (1 << 9)) { + /* -h opt */ + disp_hr = 0; + } + if (opt & (1 << 10)) { + /* -m opt */ + disp_hr = 1024*1024; + } + if (opt & (1 << 2)) { + /* -k opt */ + disp_hr = 1024; + } +#else + opt_complementary = "H-L:L-H:s-d:d-s"; + opt = getopt32(argc, argv, "aHkLsx" "d:" "lc", &smax_print_depth); +#if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K + if (opt & (1 << 2)) { + /* -k opt */ + disp_k = 1; + } #endif - break; - case 'L': - slink_depth = INT_MAX; - break; - case 's': - max_print_depth = 0; - break; - case 'x': - one_file_system = 1; - break; - - case 'd': - max_print_depth = bb_xgetularg10_bnd(optarg, 0, INT_MAX); - break; - case 'l': - count_hardlinks = 1; - break; - case 'c': - print_final_total = 1; - break; -#ifdef CONFIG_FEATURE_HUMAN_READABLE - case 'h': - disp_hr = 0; - break; - case 'm': - disp_hr = MEGABYTE; - break; #endif - default: - bb_show_usage(); - } + if (opt & (1 << 0)) { + /* -a opt */ + print_files = INT_MAX; + } + if (opt & (1 << 1)) { + /* -H opt */ + slink_depth = 1; } + if (opt & (1 << 3)) { + /* -L opt */ + slink_depth = INT_MAX; + } + if (opt & (1 << 4)) { + /* -s opt */ + max_print_depth = 0; + } + one_file_system = opt & (1 << 5); /* -x opt */ + if (opt & (1 << 6)) { + /* -d opt */ + max_print_depth = xatoi_u(smax_print_depth); + } + if (opt & (1 << 7)) { + /* -l opt */ + count_hardlinks = MAXINT(nlink_t); + } + print_final_total = opt & (1 << 8); /* -c opt */ /* go through remaining args (if any) */ argv += optind; @@ -252,11 +234,13 @@ int du_main(int argc, char **argv) total += du(*argv); slink_depth = slink_depth_save; } while (*++argv); +#if ENABLE_FEATURE_CLEAN_UP reset_ino_dev_hashtable(); +#endif if (print_final_total) { print(total, "total"); } - bb_fflush_stdout_and_exit(status); + fflush_stdout_and_exit(status); }