增强ls命令

This commit is contained in:
2026-04-14 20:19:21 +08:00
parent 46a6dadba8
commit 91a975ad6c

View File

@@ -110,7 +110,7 @@ static int ush_split_two_args(const char *arg,
static int ush_cmd_help(void) { static int ush_cmd_help(void) {
ush_writeln("commands:"); ush_writeln("commands:");
ush_writeln(" help"); ush_writeln(" help");
ush_writeln(" ls [dir]"); ush_writeln(" ls [-l] [-R] [path]");
ush_writeln(" cat <file>"); ush_writeln(" cat <file>");
ush_writeln(" pwd"); ush_writeln(" pwd");
ush_writeln(" cd [dir]"); ush_writeln(" cd [dir]");
@@ -139,14 +139,274 @@ static int ush_cmd_help(void) {
return 1; return 1;
} }
static int ush_cmd_ls(const ush_state *sh, const char *arg) { static int ush_ls_join_path(const char *dir_path, const char *name, char *out_path, u64 out_size) {
const char *target = arg; u64 p = 0ULL;
char path[USH_PATH_MAX]; u64 i;
if (dir_path == (const char *)0 || name == (const char *)0 || out_path == (char *)0 || out_size == 0ULL) {
return 0;
}
if (dir_path[0] == '/' && dir_path[1] == '\0') {
if (out_size < 2ULL) {
return 0;
}
out_path[p++] = '/';
} else {
for (i = 0ULL; dir_path[i] != '\0'; i++) {
if (p + 1ULL >= out_size) {
return 0;
}
out_path[p++] = dir_path[i];
}
if (p == 0ULL || out_path[p - 1ULL] != '/') {
if (p + 1ULL >= out_size) {
return 0;
}
out_path[p++] = '/';
}
}
for (i = 0ULL; name[i] != '\0'; i++) {
if (p + 1ULL >= out_size) {
return 0;
}
out_path[p++] = name[i];
}
out_path[p] = '\0';
return 1;
}
static const char *ush_ls_basename(const char *path) {
const char *name = path;
u64 i = 0ULL;
if (path == (const char *)0 || path[0] == '\0') {
return "";
}
while (path[i] != '\0') {
if (path[i] == '/' && path[i + 1ULL] != '\0') {
name = &path[i + 1ULL];
}
i++;
}
return name;
}
static int ush_ls_is_dot_entry(const char *name) {
if (name == (const char *)0) {
return 0;
}
if (name[0] == '.' && name[1] == '\0') {
return 1;
}
if (name[0] == '.' && name[1] == '.' && name[2] == '\0') {
return 1;
}
return 0;
}
static void ush_ls_print_one(const char *name, u64 type, u64 size, int long_mode) {
if (long_mode == 0) {
ush_writeln(name);
return;
}
if (type == 2ULL) {
ush_write("d ");
} else if (type == 1ULL) {
ush_write("f ");
} else {
ush_write("? ");
}
ush_write(name);
if (type == 1ULL) {
ush_write(" size=");
ush_write_hex_u64(size);
} else if (type == 2ULL) {
ush_write(" <DIR>");
} else {
ush_write(" <UNKNOWN>");
}
ush_write_char('\n');
}
static int ush_ls_parse_args(const char *arg,
int *out_long_mode,
int *out_recursive,
char *out_target,
u64 out_target_size) {
char token[USH_PATH_MAX];
u64 i = 0ULL;
int path_set = 0;
if (out_long_mode == (int *)0 ||
out_recursive == (int *)0 ||
out_target == (char *)0 ||
out_target_size == 0ULL) {
return 0;
}
*out_long_mode = 0;
*out_recursive = 0;
ush_copy(out_target, out_target_size, ".");
if (arg == (const char *)0 || arg[0] == '\0') {
return 1;
}
while (arg[i] != '\0') {
u64 p = 0ULL;
u64 j;
while (arg[i] != '\0' && ush_is_space(arg[i]) != 0) {
i++;
}
if (arg[i] == '\0') {
break;
}
while (arg[i] != '\0' && ush_is_space(arg[i]) == 0) {
if (p + 1ULL < (u64)sizeof(token)) {
token[p++] = arg[i];
}
i++;
}
token[p] = '\0';
if (token[0] == '-' && token[1] != '\0') {
for (j = 1ULL; token[j] != '\0'; j++) {
if (token[j] == 'l') {
*out_long_mode = 1;
} else if (token[j] == 'R') {
*out_recursive = 1;
} else {
return 0;
}
}
continue;
}
if (path_set != 0) {
return 0;
}
ush_copy(out_target, out_target_size, token);
path_set = 1;
}
return 1;
}
static int ush_ls_dir(const char *path,
int long_mode,
int recursive,
int print_header,
u64 depth) {
u64 count; u64 count;
u64 i; u64 i;
if (target == (const char *)0 || target[0] == '\0') { if (depth > 16ULL) {
target = "."; ush_writeln("ls: recursion depth limit reached");
return 0;
}
count = cleonos_sys_fs_child_count(path);
if (print_header != 0) {
ush_write(path);
ush_writeln(":");
}
if (count == 0ULL) {
ush_writeln("(empty)");
}
for (i = 0ULL; i < count; i++) {
char name[CLEONOS_FS_NAME_MAX];
char child_path[USH_PATH_MAX];
u64 type;
u64 size = 0ULL;
name[0] = '\0';
if (cleonos_sys_fs_get_child_name(path, i, name) == 0ULL) {
continue;
}
if (ush_ls_join_path(path, name, child_path, (u64)sizeof(child_path)) == 0) {
continue;
}
type = cleonos_sys_fs_stat_type(child_path);
if (type == 1ULL) {
size = cleonos_sys_fs_stat_size(child_path);
}
ush_ls_print_one(name, type, size, long_mode);
}
if (recursive == 0) {
return 1;
}
for (i = 0ULL; i < count; i++) {
char name[CLEONOS_FS_NAME_MAX];
char child_path[USH_PATH_MAX];
name[0] = '\0';
if (cleonos_sys_fs_get_child_name(path, i, name) == 0ULL) {
continue;
}
if (ush_ls_is_dot_entry(name) != 0) {
continue;
}
if (ush_ls_join_path(path, name, child_path, (u64)sizeof(child_path)) == 0) {
continue;
}
if (cleonos_sys_fs_stat_type(child_path) == 2ULL) {
ush_write_char('\n');
(void)ush_ls_dir(child_path, long_mode, recursive, 1, depth + 1ULL);
}
}
return 1;
}
static int ush_cmd_ls(const ush_state *sh, const char *arg) {
char target[USH_PATH_MAX];
char path[USH_PATH_MAX];
u64 type;
int long_mode;
int recursive;
if (ush_ls_parse_args(arg, &long_mode, &recursive, target, (u64)sizeof(target)) == 0) {
ush_writeln("ls: usage ls [-l] [-R] [path]");
return 0;
} }
if (ush_resolve_path(sh, target, path, (u64)sizeof(path)) == 0) { if (ush_resolve_path(sh, target, path, (u64)sizeof(path)) == 0) {
@@ -154,28 +414,20 @@ static int ush_cmd_ls(const ush_state *sh, const char *arg) {
return 0; return 0;
} }
if (cleonos_sys_fs_stat_type(path) != 2ULL) { type = cleonos_sys_fs_stat_type(path);
ush_writeln("ls: directory not found");
return 0;
}
count = cleonos_sys_fs_child_count(path); if (type == 1ULL) {
u64 size = cleonos_sys_fs_stat_size(path);
if (count == 0ULL) { ush_ls_print_one(ush_ls_basename(path), type, size, long_mode);
ush_writeln("(empty)");
return 1; return 1;
} }
for (i = 0ULL; i < count; i++) { if (type != 2ULL) {
char name[CLEONOS_FS_NAME_MAX]; ush_writeln("ls: path not found");
name[0] = '\0'; return 0;
if (cleonos_sys_fs_get_child_name(path, i, name) != 0ULL) {
ush_writeln(name);
}
} }
return 1; return ush_ls_dir(path, long_mode, recursive, recursive, 0ULL);
} }
static int ush_cmd_cat(const ush_state *sh, const char *arg) { static int ush_cmd_cat(const ush_state *sh, const char *arg) {
@@ -955,3 +1207,4 @@ finalize_stats:
sh->cmd_unknown++; sh->cmd_unknown++;
} }
} }