summaryrefslogtreecommitdiffstats
path: root/commands/ls.c
diff options
context:
space:
mode:
Diffstat (limited to 'commands/ls.c')
-rw-r--r--commands/ls.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/commands/ls.c b/commands/ls.c
index b0d6808390..112e1245a3 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -48,12 +48,12 @@ int ls(const char *path, ulong flags)
string_list_init(&sl);
- if (flags & LS_SHOWARG)
- printf("%s:\n", path);
-
if (stat(path, &s))
return errno;
+ if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
+ printf("%s:\n", path);
+
if (!(s.st_mode & S_IFDIR)) {
ls_one(path, &s);
return 0;
@@ -113,8 +113,10 @@ out:
static int do_ls (cmd_tbl_t *cmdtp, int argc, char *argv[])
{
- int ret, opt;
+ int ret, opt, o;
+ struct stat s;
ulong flags = LS_COLUMN;
+ struct string_list sl;
getopt_reset();
@@ -140,13 +142,53 @@ static int do_ls (cmd_tbl_t *cmdtp, int argc, char *argv[])
return ret ? 1 : 0;
}
- while (optind < argc) {
- ret = ls(argv[optind], flags);
+ string_list_init(&sl);
+
+ o = optind;
+
+ /* first pass: all files */
+ while (o < argc) {
+ ret = stat(argv[o], &s);
+ if (ret) {
+ optind++;
+ continue;
+ }
+
+ if (!(s.st_mode & S_IFDIR)) {
+ if (flags & LS_COLUMN)
+ string_list_add(&sl, argv[o]);
+ else
+ ls_one(argv[o], &s);
+ }
+
+ o++;
+ }
+
+ if (flags & LS_COLUMN)
+ string_list_print_by_column(&sl);
+
+ string_list_free(&sl);
+
+ o = optind;
+
+ /* second pass: directories */
+ while (o < argc) {
+ ret = stat(argv[o], &s);
if (ret) {
- perror("ls");
- return 1;
+ o++;
+ continue;
+ }
+
+ if (s.st_mode & S_IFDIR) {
+ ret = ls(argv[o], flags);
+ if (ret) {
+ perror("ls");
+ o++;
+ continue;
+ }
}
- optind++;
+
+ o++;
}
return 0;