diff options
Diffstat (limited to 'coreutils/ls.c')
-rw-r--r-- | coreutils/ls.c | 80 |
1 files changed, 78 insertions, 2 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index b69b80460..df4277fbd 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -109,8 +109,11 @@ | |||
109 | //usage:#define ls_full_usage "\n\n" | 109 | //usage:#define ls_full_usage "\n\n" |
110 | //usage: "List directory contents\n" | 110 | //usage: "List directory contents\n" |
111 | //usage: "\n -1 One column output" | 111 | //usage: "\n -1 One column output" |
112 | //usage: "\n -a Include names starting with ." | 112 | //usage: "\n -a Include names starting with ." IF_PLATFORM_MINGW32(" and hidden files") |
113 | //usage: "\n -A Like -a, but exclude . and .." | 113 | //usage: "\n -A Like -a, but exclude . and .." |
114 | //usage: IF_PLATFORM_MINGW32( | ||
115 | //usage: "\n -aa,-AA Like -a,-A but omit hidden system files" | ||
116 | //usage: ) | ||
114 | ////usage: "\n -C List by columns" - don't show, this is a default anyway | 117 | ////usage: "\n -C List by columns" - don't show, this is a default anyway |
115 | //usage: "\n -x List by lines" | 118 | //usage: "\n -x List by lines" |
116 | //usage: "\n -d List directory names, not contents" | 119 | //usage: "\n -d List directory names, not contents" |
@@ -316,6 +319,9 @@ struct dnode { | |||
316 | int dn_rdev_min; | 319 | int dn_rdev_min; |
317 | // dev_t dn_dev; | 320 | // dev_t dn_dev; |
318 | // blksize_t dn_blksize; | 321 | // blksize_t dn_blksize; |
322 | #if ENABLE_PLATFORM_MINGW32 | ||
323 | DWORD dn_attr; | ||
324 | #endif | ||
319 | }; | 325 | }; |
320 | 326 | ||
321 | struct globals { | 327 | struct globals { |
@@ -337,6 +343,10 @@ struct globals { | |||
337 | /* Do time() just once. Saves one syscall per file for "ls -l" */ | 343 | /* Do time() just once. Saves one syscall per file for "ls -l" */ |
338 | time_t current_time_t; | 344 | time_t current_time_t; |
339 | #endif | 345 | #endif |
346 | #if ENABLE_PLATFORM_MINGW32 | ||
347 | int a_count, A_count; | ||
348 | # define HIDSYS (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) | ||
349 | #endif | ||
340 | } FIX_ALIASING; | 350 | } FIX_ALIASING; |
341 | #define G (*(struct globals*)bb_common_bufsiz1) | 351 | #define G (*(struct globals*)bb_common_bufsiz1) |
342 | #define INIT_G() do { \ | 352 | #define INIT_G() do { \ |
@@ -497,7 +507,11 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
497 | lpath = xmalloc_readlink_or_warn(dn->fullname); | 507 | lpath = xmalloc_readlink_or_warn(dn->fullname); |
498 | 508 | ||
499 | if (opt & OPT_i) /* show inode# */ | 509 | if (opt & OPT_i) /* show inode# */ |
500 | column += printf("%7llu ", (long long) dn->dn_ino); | 510 | #if !ENABLE_FEATURE_EXTRA_FILE_DATA |
511 | column += printf("%7"LL_FMT"u ", (long long) dn->dn_ino); | ||
512 | #else | ||
513 | column += printf("%19"LL_FMT"u ", (long long) dn->dn_ino); | ||
514 | #endif | ||
501 | if (opt & OPT_s) { /* show allocated blocks */ | 515 | if (opt & OPT_s) { /* show allocated blocks */ |
502 | if (opt & OPT_h) { | 516 | if (opt & OPT_h) { |
503 | column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", | 517 | column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", |
@@ -659,7 +673,11 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
659 | } | 673 | } |
660 | column_width += 2 | 674 | column_width += 2 |
661 | + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */ | 675 | + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */ |
676 | #if !ENABLE_FEATURE_EXTRA_FILE_DATA | ||
662 | + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */ | 677 | + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */ |
678 | #else | ||
679 | + ((option_mask32 & OPT_i) ? 20 : 0) /* inode# width */ | ||
680 | #endif | ||
663 | + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */ | 681 | + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */ |
664 | ; | 682 | ; |
665 | ncols = (unsigned)G_terminal_width / column_width; | 683 | ncols = (unsigned)G_terminal_width / column_width; |
@@ -740,6 +758,9 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f | |||
740 | 758 | ||
741 | /* cur->dstat = statbuf: */ | 759 | /* cur->dstat = statbuf: */ |
742 | cur->dn_mode = statbuf.st_mode ; | 760 | cur->dn_mode = statbuf.st_mode ; |
761 | #if ENABLE_PLATFORM_MINGW32 | ||
762 | cur->dn_attr = statbuf.st_attr ; | ||
763 | #endif | ||
743 | cur->dn_size = statbuf.st_size ; | 764 | cur->dn_size = statbuf.st_size ; |
744 | #if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES | 765 | #if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES |
745 | cur->dn_time = statbuf.st_mtime ; | 766 | cur->dn_time = statbuf.st_mtime ; |
@@ -920,6 +941,15 @@ static void sort_and_display_files(struct dnode **dn, unsigned nfiles) | |||
920 | # define sort_and_display_files(dn, nfiles) display_files(dn, nfiles) | 941 | # define sort_and_display_files(dn, nfiles) display_files(dn, nfiles) |
921 | #endif | 942 | #endif |
922 | 943 | ||
944 | #if ENABLE_PLATFORM_MINGW32 | ||
945 | static int hide_file(DWORD attr) | ||
946 | { | ||
947 | return | ||
948 | ((attr & FILE_ATTRIBUTE_HIDDEN) && !(option_mask32 & (OPT_a|OPT_A))) || | ||
949 | (((attr & HIDSYS) == HIDSYS) && MAX(G.a_count, G.A_count) > 1); | ||
950 | } | ||
951 | #endif | ||
952 | |||
923 | /* Returns NULL-terminated malloced vector of pointers (or NULL) */ | 953 | /* Returns NULL-terminated malloced vector of pointers (or NULL) */ |
924 | static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) | 954 | static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) |
925 | { | 955 | { |
@@ -927,6 +957,9 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) | |||
927 | struct dirent *entry; | 957 | struct dirent *entry; |
928 | DIR *dir; | 958 | DIR *dir; |
929 | unsigned i, nfiles; | 959 | unsigned i, nfiles; |
960 | #if ENABLE_PLATFORM_MINGW32 | ||
961 | struct stat statbuf; | ||
962 | #endif | ||
930 | 963 | ||
931 | *nfiles_p = 0; | 964 | *nfiles_p = 0; |
932 | dir = warn_opendir(path); | 965 | dir = warn_opendir(path); |
@@ -949,9 +982,29 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) | |||
949 | continue; /* if only -A, skip . and .. but show other dotfiles */ | 982 | continue; /* if only -A, skip . and .. but show other dotfiles */ |
950 | } | 983 | } |
951 | } | 984 | } |
985 | #if ENABLE_PLATFORM_MINGW32 | ||
986 | if (has_dos_drive_prefix(path) && path[2] == '\0') | ||
987 | fullname = xasprintf("%s%s", path, entry->d_name); | ||
988 | else | ||
989 | #endif | ||
952 | fullname = concat_path_file(path, entry->d_name); | 990 | fullname = concat_path_file(path, entry->d_name); |
991 | #if ENABLE_PLATFORM_MINGW32 | ||
992 | /* When showing link targets we must first check the | ||
993 | * attributes of the link itself to see if it's hidden. */ | ||
994 | if ((option_mask32 & OPT_L) && !lstat(fullname, &statbuf)) { | ||
995 | if (hide_file(statbuf.st_attr)) { | ||
996 | free(fullname); | ||
997 | continue; | ||
998 | } | ||
999 | } | ||
1000 | #endif | ||
953 | cur = my_stat(fullname, bb_basename(fullname), 0); | 1001 | cur = my_stat(fullname, bb_basename(fullname), 0); |
1002 | #if !ENABLE_PLATFORM_MINGW32 | ||
954 | if (!cur) { | 1003 | if (!cur) { |
1004 | #else | ||
1005 | if (!cur || hide_file(cur->dn_attr)) { | ||
1006 | /* skip invalid or hidden files */ | ||
1007 | #endif | ||
955 | free(fullname); | 1008 | free(fullname); |
956 | continue; | 1009 | continue; |
957 | } | 1010 | } |
@@ -1060,6 +1113,18 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first) | |||
1060 | } | 1113 | } |
1061 | } | 1114 | } |
1062 | 1115 | ||
1116 | #if ENABLE_PLATFORM_MINGW32 | ||
1117 | static char *fix_backslash(char *p) | ||
1118 | { | ||
1119 | const char *flag = getenv("BB_FIX_BACKSLASH"); | ||
1120 | int value = flag ? atoi(flag) : 0; | ||
1121 | |||
1122 | if (value == 1) | ||
1123 | bs_to_slash(p); | ||
1124 | return p; | ||
1125 | } | ||
1126 | #endif | ||
1127 | |||
1063 | 1128 | ||
1064 | int ls_main(int argc UNUSED_PARAM, char **argv) | 1129 | int ls_main(int argc UNUSED_PARAM, char **argv) |
1065 | { /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */ | 1130 | { /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */ |
@@ -1129,9 +1194,11 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1129 | IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ | 1194 | IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ |
1130 | /* -w NUM: */ | 1195 | /* -w NUM: */ |
1131 | IF_FEATURE_LS_WIDTH(":w+") | 1196 | IF_FEATURE_LS_WIDTH(":w+") |
1197 | IF_PLATFORM_MINGW32(":aa:AA") | ||
1132 | , ls_longopts | 1198 | , ls_longopts |
1133 | IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width) | 1199 | IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width) |
1134 | IF_FEATURE_LS_COLOR(, &color_opt) | 1200 | IF_FEATURE_LS_COLOR(, &color_opt) |
1201 | IF_PLATFORM_MINGW32(, &G.a_count, &G.A_count) | ||
1135 | ); | 1202 | ); |
1136 | #if 0 /* option bits debug */ | 1203 | #if 0 /* option bits debug */ |
1137 | bb_error_msg("opt:0x%08x l:%x H:%x color:%x dirs:%x", opt, OPT_l, OPT_H, OPT_color, OPT_dirs_first); | 1204 | bb_error_msg("opt:0x%08x l:%x H:%x color:%x dirs:%x", opt, OPT_l, OPT_H, OPT_color, OPT_dirs_first); |
@@ -1204,6 +1271,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1204 | option_mask32 |= OPT_dirs_first; | 1271 | option_mask32 |= OPT_dirs_first; |
1205 | } | 1272 | } |
1206 | 1273 | ||
1274 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | ||
1275 | /* Enable accurate link counts for directories */ | ||
1276 | if (opt & OPT_l) | ||
1277 | count_subdirs(NULL); | ||
1278 | #endif | ||
1279 | |||
1207 | argv += optind; | 1280 | argv += optind; |
1208 | if (!argv[0]) | 1281 | if (!argv[0]) |
1209 | *--argv = (char*)"."; | 1282 | *--argv = (char*)"."; |
@@ -1215,6 +1288,9 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1215 | dn = NULL; | 1288 | dn = NULL; |
1216 | nfiles = 0; | 1289 | nfiles = 0; |
1217 | do { | 1290 | do { |
1291 | #if ENABLE_PLATFORM_MINGW32 | ||
1292 | *argv = fix_backslash(*argv); | ||
1293 | #endif | ||
1218 | cur = my_stat(*argv, *argv, | 1294 | cur = my_stat(*argv, *argv, |
1219 | /* follow links on command line unless -l, -i, -s or -F: */ | 1295 | /* follow links on command line unless -l, -i, -s or -F: */ |
1220 | !(option_mask32 & (OPT_l|OPT_i|OPT_s|OPT_F)) | 1296 | !(option_mask32 & (OPT_l|OPT_i|OPT_s|OPT_F)) |