diff options
| author | Ron Yorston <rmy@pobox.com> | 2023-01-23 10:40:57 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2023-01-23 10:40:57 +0000 |
| commit | 1a88782fd33db4ad3531b63c9fb744c64282fee2 (patch) | |
| tree | 65e826528ab2f57ebfb12c74e9b13898157de783 | |
| parent | afbf21c45d2e6a710aa27cb2784a540bb3ceedea (diff) | |
| download | busybox-w32-1a88782fd33db4ad3531b63c9fb744c64282fee2.tar.gz busybox-w32-1a88782fd33db4ad3531b63c9fb744c64282fee2.tar.bz2 busybox-w32-1a88782fd33db4ad3531b63c9fb744c64282fee2.zip | |
win32: only count subdirectories if necessary
Commit 7fb95a2a5 (win32: try to get link count for directories)
allowed stat(2) to report accurate values of st_nlink for
directories.
There are only a couple of places in busybox-w32 where these values
are required. Disable counting of subdirectories by default and
only enable it when necessary.
Microsoft kindly provide directories to test edge cases like this:
C:/Windows/WinSxS (contains many subdirectories)
C:/Windows/WinSxS/Manifests (contains many files)
Adds 84-112 bytes.
| -rw-r--r-- | coreutils/ls.c | 6 | ||||
| -rw-r--r-- | coreutils/stat.c | 4 | ||||
| -rw-r--r-- | include/mingw.h | 1 | ||||
| -rw-r--r-- | win32/mingw.c | 18 |
4 files changed, 26 insertions, 3 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index d8cfe27d3..3c659294c 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -1241,6 +1241,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
| 1241 | option_mask32 |= OPT_dirs_first; | 1241 | option_mask32 |= OPT_dirs_first; |
| 1242 | } | 1242 | } |
| 1243 | 1243 | ||
| 1244 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | ||
| 1245 | /* Enable accurate link counts for directories */ | ||
| 1246 | if (opt & OPT_l) | ||
| 1247 | count_subdirs(NULL); | ||
| 1248 | #endif | ||
| 1249 | |||
| 1244 | argv += optind; | 1250 | argv += optind; |
| 1245 | if (!argv[0]) | 1251 | if (!argv[0]) |
| 1246 | *--argv = (char*)"."; | 1252 | *--argv = (char*)"."; |
diff --git a/coreutils/stat.c b/coreutils/stat.c index 940ade89a..dc20c2356 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c | |||
| @@ -785,6 +785,10 @@ int stat_main(int argc UNUSED_PARAM, char **argv) | |||
| 785 | selinux_or_die(); | 785 | selinux_or_die(); |
| 786 | } | 786 | } |
| 787 | #endif | 787 | #endif |
| 788 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | ||
| 789 | /* Enable accurate link counts for directories */ | ||
| 790 | count_subdirs(NULL); | ||
| 791 | #endif | ||
| 788 | ok = 1; | 792 | ok = 1; |
| 789 | argv += optind; | 793 | argv += optind; |
| 790 | for (i = 0; argv[i]; ++i) | 794 | for (i = 0; argv[i]; ++i) |
diff --git a/include/mingw.h b/include/mingw.h index 4c3354864..6259bc2c6 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
| @@ -349,6 +349,7 @@ struct mingw_stat { | |||
| 349 | #define st_mtime st_mtim.tv_sec | 349 | #define st_mtime st_mtim.tv_sec |
| 350 | #define st_ctime st_ctim.tv_sec | 350 | #define st_ctime st_ctim.tv_sec |
| 351 | 351 | ||
| 352 | int count_subdirs(const char *pathname); | ||
| 352 | int mingw_lstat(const char *file_name, struct mingw_stat *buf); | 353 | int mingw_lstat(const char *file_name, struct mingw_stat *buf); |
| 353 | int mingw_stat(const char *file_name, struct mingw_stat *buf); | 354 | int mingw_stat(const char *file_name, struct mingw_stat *buf); |
| 354 | int mingw_fstat(int fd, struct mingw_stat *buf); | 355 | int mingw_fstat(int fd, struct mingw_stat *buf); |
diff --git a/win32/mingw.c b/win32/mingw.c index 79bcaa47d..75e6c3f24 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
| @@ -619,13 +619,25 @@ static int mingw_is_directory(const char *path) | |||
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | 621 | #if ENABLE_FEATURE_EXTRA_FILE_DATA |
| 622 | static int count_subdirs(const char *pathname) | 622 | /* |
| 623 | * By default we don't count subdirectories. Counting can be enabled | ||
| 624 | * in specific cases by calling 'count_subdirs(NULL)' before making | ||
| 625 | * any calls to stat(2) or lstat(2) that require accurate values of | ||
| 626 | * st_nlink for directories. | ||
| 627 | */ | ||
| 628 | int count_subdirs(const char *pathname) | ||
| 623 | { | 629 | { |
| 624 | int count = 0; | 630 | int count = 0; |
| 625 | DIR *dirp = opendir(pathname); | 631 | DIR *dirp; |
| 626 | struct dirent *dp; | 632 | struct dirent *dp; |
| 633 | static int do_count = FALSE; | ||
| 634 | |||
| 635 | if (pathname == NULL) { | ||
| 636 | do_count = TRUE; | ||
| 637 | return 0; | ||
| 638 | } | ||
| 627 | 639 | ||
| 628 | if (dirp) { | 640 | if (do_count && (dirp = opendir(pathname))) { |
| 629 | while ((dp = readdir(dirp)) != NULL) { | 641 | while ((dp = readdir(dirp)) != NULL) { |
| 630 | if (dp->d_type == DT_DIR) | 642 | if (dp->d_type == DT_DIR) |
| 631 | count++; | 643 | count++; |
