一堆elf

This commit is contained in:
2026-04-14 20:08:53 +08:00
parent cf77037aff
commit edb4393844
37 changed files with 581 additions and 12 deletions

View File

@@ -347,6 +347,12 @@ set(RAMDISK_DRIVER_APPS)
set(RAMDISK_SYSTEM_APPS) set(RAMDISK_SYSTEM_APPS)
set(RAMDISK_ROOT_APPS) set(RAMDISK_ROOT_APPS)
set(USER_SHELL_COMMAND_APPS
help ls cat pwd cd exec pid spawn wait sleep yield
shutdown restart exit clear ansi memstat fsstat taskstat userstat
shstat stats tty dmesg kbdstat mkdir touch write append cp mv rm
)
foreach(SRC IN LISTS USER_APP_MAIN_SOURCES) foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
get_filename_component(_stem "${SRC}" NAME_WE) get_filename_component(_stem "${SRC}" NAME_WE)
string(REGEX REPLACE "_main$" "" _app_name "${_stem}") string(REGEX REPLACE "_main$" "" _app_name "${_stem}")
@@ -370,6 +376,14 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/${_app_name}_*.c" "${CMAKE_SOURCE_DIR}/cleonos/c/apps/${_app_name}_*.c"
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/${_app_name}/*.c" "${CMAKE_SOURCE_DIR}/cleonos/c/apps/${_app_name}/*.c"
) )
list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx)
if(NOT _shell_cmd_idx EQUAL -1)
file(GLOB _shell_cmd_shared_abs CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/shell/*.c"
)
list(APPEND _app_specific_abs ${_shell_cmd_shared_abs})
endif()
foreach(_extra_abs IN LISTS _app_specific_abs) foreach(_extra_abs IN LISTS _app_specific_abs)
file(RELATIVE_PATH _extra_rel "${CMAKE_SOURCE_DIR}" "${_extra_abs}") file(RELATIVE_PATH _extra_rel "${CMAKE_SOURCE_DIR}" "${_extra_abs}")

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("ansi");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("append");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("cat");
}

6
cleonos/c/apps/cd_main.c Normal file
View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("cd");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("clear");
}

6
cleonos/c/apps/cp_main.c Normal file
View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("cp");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("dmesg");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("exec");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("exit");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("fsstat");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("help");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("kbdstat");
}

6
cleonos/c/apps/ls_main.c Normal file
View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("ls");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("memstat");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("mkdir");
}

6
cleonos/c/apps/mv_main.c Normal file
View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("mv");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("pid");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("pwd");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("restart");
}

6
cleonos/c/apps/rm_main.c Normal file
View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("rm");
}

View File

@@ -866,6 +866,10 @@ void ush_execute_line(ush_state *sh, const char *line) {
ush_parse_line(line_buf, cmd, (u64)sizeof(cmd), arg, (u64)sizeof(arg)); ush_parse_line(line_buf, cmd, (u64)sizeof(cmd), arg, (u64)sizeof(arg));
ush_trim_line(arg); ush_trim_line(arg);
if (ush_try_exec_external(sh, cmd, arg, &success) != 0) {
goto finalize_stats;
}
if (ush_streq(cmd, "help") != 0) { if (ush_streq(cmd, "help") != 0) {
success = ush_cmd_help(); success = ush_cmd_help();
} else if (ush_streq(cmd, "ls") != 0 || ush_streq(cmd, "dir") != 0) { } else if (ush_streq(cmd, "ls") != 0 || ush_streq(cmd, "dir") != 0) {
@@ -938,6 +942,7 @@ void ush_execute_line(ush_state *sh, const char *line) {
ush_writeln("unknown command; type 'help'"); ush_writeln("unknown command; type 'help'");
} }
finalize_stats:
sh->cmd_total++; sh->cmd_total++;
if (success != 0) { if (success != 0) {

View File

@@ -0,0 +1,297 @@
#include "shell_internal.h"
static int ush_dispatch_external_enabled = 1;
static void ush_zero(void *ptr, u64 size) {
u64 i;
char *bytes = (char *)ptr;
if (bytes == (char *)0) {
return;
}
for (i = 0ULL; i < size; i++) {
bytes[i] = 0;
}
}
static const char *ush_alias_command(const char *cmd) {
if (cmd == (const char *)0) {
return (const char *)0;
}
if (ush_streq(cmd, "dir") != 0) {
return "ls";
}
if (ush_streq(cmd, "run") != 0) {
return "exec";
}
if (ush_streq(cmd, "poweroff") != 0) {
return "shutdown";
}
if (ush_streq(cmd, "reboot") != 0) {
return "restart";
}
if (ush_streq(cmd, "cls") != 0) {
return "clear";
}
if (ush_streq(cmd, "color") != 0) {
return "ansi";
}
return cmd;
}
static int ush_build_command_line(const char *cmd, const char *arg, char *out_line, u64 out_size) {
u64 p = 0ULL;
u64 i;
if (cmd == (const char *)0 || out_line == (char *)0 || out_size == 0ULL) {
return 0;
}
out_line[0] = '\0';
for (i = 0ULL; cmd[i] != '\0'; i++) {
if (p + 1ULL >= out_size) {
return 0;
}
out_line[p++] = cmd[i];
}
if (arg != (const char *)0 && arg[0] != '\0') {
if (p + 1ULL >= out_size) {
return 0;
}
out_line[p++] = ' ';
for (i = 0ULL; arg[i] != '\0'; i++) {
if (p + 1ULL >= out_size) {
return 0;
}
out_line[p++] = arg[i];
}
}
out_line[p] = '\0';
return 1;
}
static int ush_cmd_ret_apply(ush_state *sh, const ush_cmd_ret *ret) {
if (sh == (ush_state *)0 || ret == (const ush_cmd_ret *)0) {
return 0;
}
if ((ret->flags & USH_CMD_RET_FLAG_CWD) != 0ULL && ret->cwd[0] == '/') {
ush_copy(sh->cwd, (u64)sizeof(sh->cwd), ret->cwd);
}
if ((ret->flags & USH_CMD_RET_FLAG_EXIT) != 0ULL) {
sh->exit_requested = 1;
sh->exit_code = ret->exit_code;
}
return 1;
}
void ush_set_external_dispatch(int enabled) {
ush_dispatch_external_enabled = (enabled != 0) ? 1 : 0;
}
int ush_command_ctx_write(const char *cmd, const char *arg, const char *cwd) {
ush_cmd_ctx ctx;
ush_zero(&ctx, (u64)sizeof(ctx));
if (cmd != (const char *)0) {
ush_copy(ctx.cmd, (u64)sizeof(ctx.cmd), cmd);
}
if (arg != (const char *)0) {
ush_copy(ctx.arg, (u64)sizeof(ctx.arg), arg);
}
if (cwd != (const char *)0) {
ush_copy(ctx.cwd, (u64)sizeof(ctx.cwd), cwd);
}
return (cleonos_sys_fs_write(USH_CMD_CTX_PATH, (const char *)&ctx, (u64)sizeof(ctx)) != 0ULL) ? 1 : 0;
}
int ush_command_ctx_read(ush_cmd_ctx *out_ctx) {
u64 got;
if (out_ctx == (ush_cmd_ctx *)0) {
return 0;
}
ush_zero(out_ctx, (u64)sizeof(*out_ctx));
got = cleonos_sys_fs_read(USH_CMD_CTX_PATH, (char *)out_ctx, (u64)sizeof(*out_ctx));
return (got == (u64)sizeof(*out_ctx)) ? 1 : 0;
}
void ush_command_ret_reset(void) {
(void)cleonos_sys_fs_remove(USH_CMD_RET_PATH);
}
int ush_command_ret_write(const ush_cmd_ret *ret) {
if (ret == (const ush_cmd_ret *)0) {
return 0;
}
return (cleonos_sys_fs_write(USH_CMD_RET_PATH, (const char *)ret, (u64)sizeof(*ret)) != 0ULL) ? 1 : 0;
}
int ush_command_ret_read(ush_cmd_ret *out_ret) {
u64 got;
if (out_ret == (ush_cmd_ret *)0) {
return 0;
}
ush_zero(out_ret, (u64)sizeof(*out_ret));
got = cleonos_sys_fs_read(USH_CMD_RET_PATH, (char *)out_ret, (u64)sizeof(*out_ret));
return (got == (u64)sizeof(*out_ret)) ? 1 : 0;
}
int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *out_success) {
const char *canonical;
char path[USH_PATH_MAX];
u64 status;
ush_cmd_ret ret;
if (out_success != (int *)0) {
*out_success = 0;
}
if (sh == (ush_state *)0 || cmd == (const char *)0 || cmd[0] == '\0') {
return 0;
}
if (ush_dispatch_external_enabled == 0) {
return 0;
}
canonical = ush_alias_command(cmd);
if (canonical == (const char *)0) {
return 0;
}
if (ush_resolve_exec_path(sh, canonical, path, (u64)sizeof(path)) == 0) {
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
return 0;
}
ush_command_ret_reset();
if (ush_command_ctx_write(canonical, arg, sh->cwd) == 0) {
ush_writeln("exec: command context write failed");
return 1;
}
status = cleonos_sys_exec_path(path);
if (status == (u64)-1) {
ush_writeln("exec: request failed");
(void)cleonos_sys_fs_remove(USH_CMD_CTX_PATH);
return 1;
}
if (ush_command_ret_read(&ret) != 0) {
(void)ush_cmd_ret_apply(sh, &ret);
}
(void)cleonos_sys_fs_remove(USH_CMD_CTX_PATH);
(void)cleonos_sys_fs_remove(USH_CMD_RET_PATH);
if (status != 0ULL) {
ush_writeln("exec: returned non-zero status");
if (out_success != (int *)0) {
*out_success = 0;
}
return 1;
}
if (out_success != (int *)0) {
*out_success = 1;
}
return 1;
}
int ush_command_program_main(const char *command_name) {
ush_cmd_ctx ctx;
ush_state sh;
ush_cmd_ret ret;
char line[USH_LINE_MAX];
u64 ok_before;
int success;
int has_context = 0;
int use_ctx_cwd = 0;
if (command_name == (const char *)0 || command_name[0] == '\0') {
return 1;
}
ush_zero(&ctx, (u64)sizeof(ctx));
if (ush_command_ctx_read(&ctx) != 0) {
if (ush_streq(ctx.cmd, command_name) != 0) {
has_context = 1;
use_ctx_cwd = 1;
} else if (ctx.cwd[0] == '/') {
use_ctx_cwd = 1;
ctx.arg[0] = '\0';
}
}
ush_init_state(&sh);
ush_set_external_dispatch(0);
if (use_ctx_cwd != 0 && ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
}
if (ush_build_command_line(command_name, ctx.arg, line, (u64)sizeof(line)) == 0) {
ush_set_external_dispatch(1);
ush_writeln("command line too long");
return 1;
}
ok_before = sh.cmd_ok;
ush_execute_line(&sh, line);
success = (sh.cmd_ok > ok_before) ? 1 : 0;
if (has_context != 0) {
ush_zero(&ret, (u64)sizeof(ret));
if (ush_streq(sh.cwd, ctx.cwd) == 0) {
ret.flags |= USH_CMD_RET_FLAG_CWD;
ush_copy(ret.cwd, (u64)sizeof(ret.cwd), sh.cwd);
}
if (sh.exit_requested != 0) {
ret.flags |= USH_CMD_RET_FLAG_EXIT;
ret.exit_code = sh.exit_code;
}
(void)ush_command_ret_write(&ret);
}
ush_set_external_dispatch(1);
return (success != 0) ? 0 : 1;
}

View File

@@ -22,6 +22,11 @@ typedef long long i64;
#define USH_KEY_END ((char)0x06) #define USH_KEY_END ((char)0x06)
#define USH_KEY_DELETE ((char)0x07) #define USH_KEY_DELETE ((char)0x07)
#define USH_CMD_CTX_PATH "/temp/.ush_cmd_ctx.bin"
#define USH_CMD_RET_PATH "/temp/.ush_cmd_ret.bin"
#define USH_CMD_RET_FLAG_CWD 0x1ULL
#define USH_CMD_RET_FLAG_EXIT 0x2ULL
typedef struct ush_state { typedef struct ush_state {
char line[USH_LINE_MAX]; char line[USH_LINE_MAX];
u64 line_len; u64 line_len;
@@ -45,6 +50,18 @@ typedef struct ush_state {
u64 exit_code; u64 exit_code;
} ush_state; } ush_state;
typedef struct ush_cmd_ctx {
char cmd[USH_CMD_MAX];
char arg[USH_ARG_MAX];
char cwd[USH_PATH_MAX];
} ush_cmd_ctx;
typedef struct ush_cmd_ret {
u64 flags;
u64 exit_code;
char cwd[USH_PATH_MAX];
} ush_cmd_ret;
void ush_init_state(ush_state *sh); void ush_init_state(ush_state *sh);
u64 ush_strlen(const char *str); u64 ush_strlen(const char *str);
@@ -72,5 +89,14 @@ int ush_path_is_under_system(const char *path);
void ush_read_line(ush_state *sh, char *out_line, u64 out_size); void ush_read_line(ush_state *sh, char *out_line, u64 out_size);
int ush_run_script_file(ush_state *sh, const char *path); int ush_run_script_file(ush_state *sh, const char *path);
void ush_execute_line(ush_state *sh, const char *line); void ush_execute_line(ush_state *sh, const char *line);
void ush_set_external_dispatch(int enabled);
int ush_command_ctx_write(const char *cmd, const char *arg, const char *cwd);
int ush_command_ctx_read(ush_cmd_ctx *out_ctx);
void ush_command_ret_reset(void);
int ush_command_ret_write(const ush_cmd_ret *ret);
int ush_command_ret_read(ush_cmd_ret *out_ret);
int ush_command_program_main(const char *command_name);
int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *out_success);
#endif #endif

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("shstat");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("shutdown");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("sleep");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("spawn");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("stats");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("taskstat");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("touch");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("tty");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("userstat");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("wait");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("write");
}

View File

@@ -0,0 +1,6 @@
#include "shell/shell_internal.h"
int cleonos_app_main(void) {
return ush_command_program_main("yield");
}

View File

@@ -5,6 +5,7 @@
#include <clks/heap.h> #include <clks/heap.h>
#include <clks/interrupts.h> #include <clks/interrupts.h>
#include <clks/log.h> #include <clks/log.h>
#include <clks/serial.h>
#include <clks/string.h> #include <clks/string.h>
#include <clks/types.h> #include <clks/types.h>
#include <clks/tty.h> #include <clks/tty.h>
@@ -51,6 +52,39 @@ static clks_bool clks_exec_exit_requested_stack[CLKS_EXEC_MAX_DEPTH];
static u64 clks_exec_exit_status_stack[CLKS_EXEC_MAX_DEPTH]; static u64 clks_exec_exit_status_stack[CLKS_EXEC_MAX_DEPTH];
static u32 clks_exec_pid_stack_depth = 0U; static u32 clks_exec_pid_stack_depth = 0U;
static void clks_exec_serial_write_hex64(u64 value) {
int nibble;
clks_serial_write("0X");
for (nibble = 15; nibble >= 0; nibble--) {
u8 current = (u8)((value >> (nibble * 4)) & 0x0FULL);
char out = (current < 10U) ? (char)('0' + current) : (char)('A' + (current - 10U));
clks_serial_write_char(out);
}
}
static void clks_exec_log_info_serial(const char *message) {
clks_serial_write("[INFO][EXEC] ");
if (message != CLKS_NULL) {
clks_serial_write(message);
}
clks_serial_write("\n");
}
static void clks_exec_log_hex_serial(const char *label, u64 value) {
clks_serial_write("[INFO][EXEC] ");
if (label != CLKS_NULL) {
clks_serial_write(label);
}
clks_serial_write(": ");
clks_exec_serial_write_hex64(value);
clks_serial_write("\n");
}
static clks_bool clks_exec_has_prefix(const char *text, const char *prefix) { static clks_bool clks_exec_has_prefix(const char *text, const char *prefix) {
usize i = 0U; usize i = 0U;
@@ -322,10 +356,10 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
goto fail; goto fail;
} }
clks_log(CLKS_LOG_INFO, "EXEC", "EXEC RUN START"); clks_exec_log_info_serial("EXEC RUN START");
clks_log(CLKS_LOG_INFO, "EXEC", proc->path); clks_exec_log_info_serial(proc->path);
clks_log_hex(CLKS_LOG_INFO, "EXEC", "ENTRY", info.entry); clks_exec_log_hex_serial("ENTRY", info.entry);
clks_log_hex(CLKS_LOG_INFO, "EXEC", "PHNUM", (u64)info.phnum); clks_exec_log_hex_serial("PHNUM", (u64)info.phnum);
clks_exec_running_depth++; clks_exec_running_depth++;
depth_counted = CLKS_TRUE; depth_counted = CLKS_TRUE;
@@ -345,9 +379,9 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
run_ret = clks_exec_exit_status_stack[(u32)depth_index]; run_ret = clks_exec_exit_status_stack[(u32)depth_index];
} }
clks_log(CLKS_LOG_INFO, "EXEC", "RUN RETURNED"); clks_exec_log_info_serial("RUN RETURNED");
clks_log(CLKS_LOG_INFO, "EXEC", proc->path); clks_exec_log_info_serial(proc->path);
clks_log_hex(CLKS_LOG_INFO, "EXEC", "RET", run_ret); clks_exec_log_hex_serial("RET", run_ret);
clks_exec_success++; clks_exec_success++;
@@ -477,7 +511,7 @@ void clks_exec_init(void) {
clks_memset(clks_exec_exit_requested_stack, 0, sizeof(clks_exec_exit_requested_stack)); clks_memset(clks_exec_exit_requested_stack, 0, sizeof(clks_exec_exit_requested_stack));
clks_memset(clks_exec_exit_status_stack, 0, sizeof(clks_exec_exit_status_stack)); clks_memset(clks_exec_exit_status_stack, 0, sizeof(clks_exec_exit_status_stack));
clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table)); clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table));
clks_log(CLKS_LOG_INFO, "EXEC", "PATH EXEC FRAMEWORK ONLINE"); clks_exec_log_info_serial("PATH EXEC FRAMEWORK ONLINE");
} }
clks_bool clks_exec_run_path(const char *path, u64 *out_status) { clks_bool clks_exec_run_path(const char *path, u64 *out_status) {
@@ -518,9 +552,9 @@ clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid) {
*out_pid = pid; *out_pid = pid;
} }
clks_log(CLKS_LOG_INFO, "EXEC", "SPAWN QUEUED"); clks_exec_log_info_serial("SPAWN QUEUED");
clks_log(CLKS_LOG_INFO, "EXEC", path); clks_exec_log_info_serial(path);
clks_log_hex(CLKS_LOG_INFO, "EXEC", "PID", pid); clks_exec_log_hex_serial("PID", pid);
return CLKS_TRUE; return CLKS_TRUE;
} }
@@ -683,3 +717,4 @@ clks_bool clks_exec_current_path_is_user(void) {
proc = &clks_exec_proc_table[(u32)slot]; proc = &clks_exec_proc_table[(u32)slot];
return clks_exec_path_is_user_program(proc->path); return clks_exec_path_is_user_program(proc->path);
} }