彻底拆分

This commit is contained in:
2026-04-16 19:29:42 +08:00
parent af4ad36f6a
commit 643b26cfb2
96 changed files with 5239 additions and 1737 deletions

View File

@@ -392,10 +392,7 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx) list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx)
if(NOT _shell_cmd_idx EQUAL -1) if(NOT _shell_cmd_idx EQUAL -1)
file(GLOB _shell_cmd_shared_abs CONFIGURE_DEPENDS list(APPEND _app_specific_abs "${CMAKE_SOURCE_DIR}/cleonos/c/apps/cmd_runtime.c")
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/shell/*.c"
)
list(APPEND _app_specific_abs ${_shell_cmd_shared_abs})
endif() 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

@@ -1,6 +1,53 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_ansi(void) {
int cleonos_app_main(void) { ush_writeln("\x1B[1;36mansi color demo\x1B[0m");
return ush_command_program_main("ansi"); ush_writeln(" \x1B[30mblack\x1B[0m \x1B[31mred\x1B[0m \x1B[32mgreen\x1B[0m \x1B[33myellow\x1B[0m");
ush_writeln(" \x1B[34mblue\x1B[0m \x1B[35mmagenta\x1B[0m \x1B[36mcyan\x1B[0m \x1B[37mwhite\x1B[0m");
ush_writeln(" \x1B[90mbright-black\x1B[0m \x1B[91mbright-red\x1B[0m \x1B[92mbright-green\x1B[0m \x1B[93mbright-yellow\x1B[0m");
ush_writeln(" \x1B[94mbright-blue\x1B[0m \x1B[95mbright-magenta\x1B[0m \x1B[96mbright-cyan\x1B[0m \x1B[97mbright-white\x1B[0m");
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "ansi") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_ansi();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,5 +1,176 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_ansi(void) {
ush_writeln("\x1B[1;36mansi color demo\x1B[0m");
ush_writeln(" \x1B[30mblack\x1B[0m \x1B[31mred\x1B[0m \x1B[32mgreen\x1B[0m \x1B[33myellow\x1B[0m");
ush_writeln(" \x1B[34mblue\x1B[0m \x1B[35mmagenta\x1B[0m \x1B[36mcyan\x1B[0m \x1B[37mwhite\x1B[0m");
ush_writeln(" \x1B[90mbright-black\x1B[0m \x1B[91mbright-red\x1B[0m \x1B[92mbright-green\x1B[0m \x1B[93mbright-yellow\x1B[0m");
ush_writeln(" \x1B[94mbright-blue\x1B[0m \x1B[95mbright-magenta\x1B[0m \x1B[96mbright-cyan\x1B[0m \x1B[97mbright-white\x1B[0m");
return 1;
}
static u64 ush_ansitest_u64_to_dec(char *out, u64 out_size, u64 value) {
char rev[10];
u64 digits = 0ULL;
u64 i;
if (out == (char *)0 || out_size == 0ULL) {
return 0ULL;
}
if (value == 0U) {
if (out_size < 2ULL) {
return 0ULL;
}
out[0] = '0';
out[1] = '\0';
return 1ULL;
}
while (value > 0U && digits < (u64)sizeof(rev)) {
rev[digits++] = (char)('0' + (value % 10U));
value /= 10U;
}
if (digits + 1ULL > out_size) {
out[0] = '\0';
return 0ULL;
}
for (i = 0ULL; i < digits; i++) {
out[i] = rev[digits - 1ULL - i];
}
out[digits] = '\0';
return digits;
}
static void ush_ansitest_emit_bg256(u64 index) {
char num[4];
char seq[24];
u64 digits;
u64 p = 0ULL;
u64 i;
if (index > 255U) {
index = 255U;
}
digits = ush_ansitest_u64_to_dec(num, (u64)sizeof(num), index);
if (digits == 0ULL) {
return;
}
seq[p++] = '\x1B';
seq[p++] = '[';
seq[p++] = '4';
seq[p++] = '8';
seq[p++] = ';';
seq[p++] = '5';
seq[p++] = ';';
for (i = 0ULL; i < digits && p + 1ULL < (u64)sizeof(seq); i++) {
seq[p++] = num[i];
}
if (p + 7ULL >= (u64)sizeof(seq)) {
return;
}
seq[p++] = 'm';
seq[p++] = ' ';
seq[p++] = ' ';
seq[p++] = '\x1B';
seq[p++] = '[';
seq[p++] = '0';
seq[p++] = 'm';
seq[p] = '\0';
ush_write(seq);
}
static int ush_cmd_ansitest(void) {
u64 i;
ush_writeln("\x1B[1;96mANSI test suite\x1B[0m");
ush_writeln("styles: \x1B[1mbold\x1B[0m \x1B[7minverse\x1B[0m \x1B[4munderline\x1B[0m");
ush_writeln("16-color demo:");
(void)ush_cmd_ansi();
ush_writeln("256-color palette (0..255):");
for (i = 0ULL; i < 256ULL; i++) {
ush_ansitest_emit_bg256(i);
if ((i % 32ULL) == 31ULL) {
ush_write_char('\n');
}
}
ush_write_char('\n');
ush_writeln("truecolor demo:");
ush_writeln(" \x1B[38;2;255;64;64mRGB(255,64,64)\x1B[0m \x1B[38;2;64;255;64mRGB(64,255,64)\x1B[0m \x1B[38;2;64;128;255mRGB(64,128,255)\x1B[0m");
ush_writeln("cursor control demo:");
ush_write(" 0123456789");
ush_write("\x1B[5D");
ush_write("\x1B[93m<OK>\x1B[0m");
ush_write_char('\n');
ush_write(" save");
ush_write("\x1B[s");
ush_write("....");
ush_write("\x1B[u");
ush_write("\x1B[92m<restore>\x1B[0m");
ush_write_char('\n');
ush_writeln("erase-line demo:");
ush_write(" left|right-to-clear");
ush_write("\x1B[14D\x1B[K");
ush_write_char('\n');
ush_writeln("ansitest done");
return 1;
}
int cleonos_app_main(void) { int cleonos_app_main(void) {
return ush_command_program_main("ansitest"); ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "ansitest") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_ansitest();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,91 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_append(const ush_state *sh, const char *arg) {
char path_arg[USH_PATH_MAX];
char abs_path[USH_PATH_MAX];
const char *payload = (const char *)0;
u64 payload_len;
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("append"); ush_writeln("append: usage append <file> <text>");
return 0;
}
if (ush_split_first_and_rest(arg, path_arg, (u64)sizeof(path_arg), &payload) == 0) {
ush_writeln("append: usage append <file> <text>");
return 0;
}
if (ush_resolve_path(sh, path_arg, abs_path, (u64)sizeof(abs_path)) == 0) {
ush_writeln("append: invalid path");
return 0;
}
if (ush_path_is_under_temp(abs_path) == 0) {
ush_writeln("append: target must be under /temp");
return 0;
}
if (payload == (const char *)0 || payload[0] == '\0') {
if (ush_pipeline_stdin_text == (const char *)0) {
ush_writeln("append: usage append <file> <text>");
return 0;
}
payload = ush_pipeline_stdin_text;
payload_len = ush_pipeline_stdin_len;
} else {
payload_len = ush_strlen(payload);
}
if (cleonos_sys_fs_append(abs_path, payload, payload_len) == 0ULL) {
ush_writeln("append: failed");
return 0;
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "append") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_append(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,106 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_cat(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
char buf[USH_CAT_MAX + 1ULL];
u64 size;
u64 req;
u64 got;
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("cat"); if (ush_pipeline_stdin_text != (const char *)0 && ush_pipeline_stdin_len > 0ULL) {
ush_write(ush_pipeline_stdin_text);
return 1;
}
ush_writeln("cat: file path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("cat: invalid path");
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
ush_writeln("cat: file not found");
return 0;
}
size = cleonos_sys_fs_stat_size(path);
if (size == (u64)-1) {
ush_writeln("cat: failed to stat file");
return 0;
}
if (size == 0ULL) {
return 1;
}
req = (size < USH_CAT_MAX) ? size : USH_CAT_MAX;
got = cleonos_sys_fs_read(path, buf, req);
if (got == 0ULL) {
ush_writeln("cat: read failed");
return 0;
}
if (got > USH_CAT_MAX) {
got = USH_CAT_MAX;
}
buf[got] = '\0';
ush_writeln(buf);
if (size > got) {
ush_writeln("[cat] output truncated");
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "cat") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_cat(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,68 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_cd(ush_state *sh, const char *arg) {
const char *target = arg;
char path[USH_PATH_MAX];
int cleonos_app_main(void) { if (target == (const char *)0 || target[0] == '\0') {
return ush_command_program_main("cd"); target = "/";
}
if (ush_resolve_path(sh, target, path, (u64)sizeof(path)) == 0) {
ush_writeln("cd: invalid path");
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 2ULL) {
ush_writeln("cd: directory not found");
return 0;
}
ush_copy(sh->cwd, (u64)sizeof(sh->cwd), path);
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "cd") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_cd(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,49 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_clear(void) {
int cleonos_app_main(void) { ush_write("\x1B[2J\x1B[H");
return ush_command_program_main("clear"); return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "clear") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_clear();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -0,0 +1,588 @@
#include "cmd_runtime.h"
const char *ush_pipeline_stdin_text = (const char *)0;
u64 ush_pipeline_stdin_len = 0ULL;
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;
}
}
void ush_init_state(ush_state *sh) {
if (sh == (ush_state *)0) {
return;
}
ush_zero(sh, (u64)sizeof(*sh));
ush_copy(sh->cwd, (u64)sizeof(sh->cwd), "/");
sh->history_nav = -1;
}
u64 ush_strlen(const char *str) {
u64 len = 0ULL;
if (str == (const char *)0) {
return 0ULL;
}
while (str[len] != '\0') {
len++;
}
return len;
}
int ush_streq(const char *left, const char *right) {
u64 i = 0ULL;
if (left == (const char *)0 || right == (const char *)0) {
return 0;
}
while (left[i] != '\0' && right[i] != '\0') {
if (left[i] != right[i]) {
return 0;
}
i++;
}
return (left[i] == right[i]) ? 1 : 0;
}
int ush_is_space(char ch) {
return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') ? 1 : 0;
}
int ush_is_printable(char ch) {
return (ch >= 32 && ch <= 126) ? 1 : 0;
}
int ush_has_suffix(const char *name, const char *suffix) {
u64 name_len;
u64 suffix_len;
u64 i;
if (name == (const char *)0 || suffix == (const char *)0) {
return 0;
}
name_len = ush_strlen(name);
suffix_len = ush_strlen(suffix);
if (suffix_len > name_len) {
return 0;
}
for (i = 0ULL; i < suffix_len; i++) {
if (name[name_len - suffix_len + i] != suffix[i]) {
return 0;
}
}
return 1;
}
int ush_contains_char(const char *text, char needle) {
u64 i = 0ULL;
if (text == (const char *)0) {
return 0;
}
while (text[i] != '\0') {
if (text[i] == needle) {
return 1;
}
i++;
}
return 0;
}
int ush_parse_u64_dec(const char *text, u64 *out_value) {
u64 value = 0ULL;
u64 i = 0ULL;
if (text == (const char *)0 || out_value == (u64 *)0 || text[0] == '\0') {
return 0;
}
while (text[i] != '\0') {
u64 digit;
if (text[i] < '0' || text[i] > '9') {
return 0;
}
digit = (u64)(text[i] - '0');
if (value > ((0xFFFFFFFFFFFFFFFFULL - digit) / 10ULL)) {
return 0;
}
value = (value * 10ULL) + digit;
i++;
}
*out_value = value;
return 1;
}
void ush_copy(char *dst, u64 dst_size, const char *src) {
u64 i = 0ULL;
if (dst == (char *)0 || src == (const char *)0 || dst_size == 0ULL) {
return;
}
while (src[i] != '\0' && i + 1ULL < dst_size) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
void ush_trim_line(char *line) {
u64 start = 0ULL;
u64 i = 0ULL;
u64 len;
if (line == (char *)0) {
return;
}
while (line[start] != '\0' && ush_is_space(line[start]) != 0) {
start++;
}
if (start > 0ULL) {
while (line[start + i] != '\0') {
line[i] = line[start + i];
i++;
}
line[i] = '\0';
}
len = ush_strlen(line);
while (len > 0ULL && ush_is_space(line[len - 1ULL]) != 0) {
line[len - 1ULL] = '\0';
len--;
}
}
void ush_parse_line(const char *line, char *out_cmd, u64 cmd_size, char *out_arg, u64 arg_size) {
u64 i = 0ULL;
u64 cmd_pos = 0ULL;
u64 arg_pos = 0ULL;
if (line == (const char *)0 || out_cmd == (char *)0 || out_arg == (char *)0) {
return;
}
out_cmd[0] = '\0';
out_arg[0] = '\0';
while (line[i] != '\0' && ush_is_space(line[i]) != 0) {
i++;
}
while (line[i] != '\0' && ush_is_space(line[i]) == 0) {
if (cmd_pos + 1ULL < cmd_size) {
out_cmd[cmd_pos++] = line[i];
}
i++;
}
out_cmd[cmd_pos] = '\0';
while (line[i] != '\0' && ush_is_space(line[i]) != 0) {
i++;
}
while (line[i] != '\0') {
if (arg_pos + 1ULL < arg_size) {
out_arg[arg_pos++] = line[i];
}
i++;
}
out_arg[arg_pos] = '\0';
}
void ush_write(const char *text) {
u64 len;
if (text == (const char *)0) {
return;
}
len = ush_strlen(text);
if (len == 0ULL) {
return;
}
(void)cleonos_sys_tty_write(text, len);
}
void ush_write_char(char ch) {
(void)cleonos_sys_tty_write_char(ch);
}
void ush_writeln(const char *text) {
ush_write(text);
ush_write_char('\n');
}
void ush_write_hex_u64(u64 value) {
i64 nibble;
ush_write("0X");
for (nibble = 15; nibble >= 0; nibble--) {
u64 current = (value >> (u64)(nibble * 4)) & 0x0FULL;
char out = (current < 10ULL) ? (char)('0' + current) : (char)('A' + (current - 10ULL));
ush_write_char(out);
}
}
void ush_print_kv_hex(const char *label, u64 value) {
ush_write(label);
ush_write(": ");
ush_write_hex_u64(value);
ush_write_char('\n');
}
static int ush_path_push_component(char *path, u64 path_size, u64 *io_len, const char *component, u64 comp_len) {
u64 i;
if (path == (char *)0 || io_len == (u64 *)0 || component == (const char *)0 || comp_len == 0ULL) {
return 0;
}
if (*io_len == 1ULL) {
if (*io_len + comp_len >= path_size) {
return 0;
}
for (i = 0ULL; i < comp_len; i++) {
path[1ULL + i] = component[i];
}
*io_len = 1ULL + comp_len;
path[*io_len] = '\0';
return 1;
}
if (*io_len + 1ULL + comp_len >= path_size) {
return 0;
}
path[*io_len] = '/';
for (i = 0ULL; i < comp_len; i++) {
path[*io_len + 1ULL + i] = component[i];
}
*io_len += (1ULL + comp_len);
path[*io_len] = '\0';
return 1;
}
static void ush_path_pop_component(char *path, u64 *io_len) {
if (path == (char *)0 || io_len == (u64 *)0) {
return;
}
if (*io_len <= 1ULL) {
path[0] = '/';
path[1] = '\0';
*io_len = 1ULL;
return;
}
while (*io_len > 1ULL && path[*io_len - 1ULL] != '/') {
(*io_len)--;
}
if (*io_len > 1ULL) {
(*io_len)--;
}
path[*io_len] = '\0';
}
static int ush_path_parse_into(const char *src, char *out_path, u64 out_size, u64 *io_len) {
u64 i = 0ULL;
if (src == (const char *)0 || out_path == (char *)0 || io_len == (u64 *)0) {
return 0;
}
if (src[0] == '/') {
i = 1ULL;
}
while (src[i] != '\0') {
u64 start;
u64 len;
while (src[i] == '/') {
i++;
}
if (src[i] == '\0') {
break;
}
start = i;
while (src[i] != '\0' && src[i] != '/') {
i++;
}
len = i - start;
if (len == 1ULL && src[start] == '.') {
continue;
}
if (len == 2ULL && src[start] == '.' && src[start + 1ULL] == '.') {
ush_path_pop_component(out_path, io_len);
continue;
}
if (ush_path_push_component(out_path, out_size, io_len, src + start, len) == 0) {
return 0;
}
}
return 1;
}
int ush_resolve_path(const ush_state *sh, const char *arg, char *out_path, u64 out_size) {
u64 len = 1ULL;
if (sh == (const ush_state *)0 || out_path == (char *)0 || out_size < 2ULL) {
return 0;
}
out_path[0] = '/';
out_path[1] = '\0';
if (arg == (const char *)0 || arg[0] == '\0') {
return ush_path_parse_into(sh->cwd, out_path, out_size, &len);
}
if (arg[0] != '/') {
if (ush_path_parse_into(sh->cwd, out_path, out_size, &len) == 0) {
return 0;
}
}
return ush_path_parse_into(arg, out_path, out_size, &len);
}
int ush_resolve_exec_path(const ush_state *sh, const char *arg, char *out_path, u64 out_size) {
u64 i;
u64 cursor = 0ULL;
if (sh == (const ush_state *)0 || arg == (const char *)0 || out_path == (char *)0 || out_size == 0ULL) {
return 0;
}
if (arg[0] == '\0') {
return 0;
}
out_path[0] = '\0';
if (arg[0] == '/') {
ush_copy(out_path, out_size, arg);
} else if (ush_contains_char(arg, '/') != 0) {
if (ush_resolve_path(sh, arg, out_path, out_size) == 0) {
return 0;
}
} else {
static const char prefix[] = "/shell/";
u64 prefix_len = (u64)(sizeof(prefix) - 1U);
if (prefix_len + 1ULL >= out_size) {
return 0;
}
for (i = 0ULL; i < prefix_len; i++) {
out_path[cursor++] = prefix[i];
}
for (i = 0ULL; arg[i] != '\0'; i++) {
if (cursor + 1ULL >= out_size) {
return 0;
}
out_path[cursor++] = arg[i];
}
out_path[cursor] = '\0';
}
if (ush_has_suffix(out_path, ".elf") == 0) {
static const char suffix[] = ".elf";
cursor = ush_strlen(out_path);
for (i = 0ULL; suffix[i] != '\0'; i++) {
if (cursor + 1ULL >= out_size) {
return 0;
}
out_path[cursor++] = suffix[i];
}
out_path[cursor] = '\0';
}
return 1;
}
int ush_path_is_under_system(const char *path) {
if (path == (const char *)0) {
return 0;
}
if (path[0] != '/' || path[1] != 's' || path[2] != 'y' || path[3] != 's' || path[4] != 't' || path[5] != 'e' || path[6] != 'm') {
return 0;
}
return (path[7] == '\0' || path[7] == '/') ? 1 : 0;
}
int ush_path_is_under_temp(const char *path) {
if (path == (const char *)0) {
return 0;
}
if (path[0] != '/' || path[1] != 't' || path[2] != 'e' || path[3] != 'm' || path[4] != 'p') {
return 0;
}
return (path[5] == '\0' || path[5] == '/') ? 1 : 0;
}
int ush_split_first_and_rest(const char *arg, char *out_first, u64 out_first_size, const char **out_rest) {
u64 i = 0ULL;
u64 p = 0ULL;
if (arg == (const char *)0 || out_first == (char *)0 || out_first_size == 0ULL || out_rest == (const char **)0) {
return 0;
}
out_first[0] = '\0';
*out_rest = "";
while (arg[i] != '\0' && ush_is_space(arg[i]) != 0) {
i++;
}
if (arg[i] == '\0') {
return 0;
}
while (arg[i] != '\0' && ush_is_space(arg[i]) == 0) {
if (p + 1ULL < out_first_size) {
out_first[p++] = arg[i];
}
i++;
}
out_first[p] = '\0';
while (arg[i] != '\0' && ush_is_space(arg[i]) != 0) {
i++;
}
*out_rest = &arg[i];
return 1;
}
int ush_split_two_args(const char *arg,
char *out_first,
u64 out_first_size,
char *out_second,
u64 out_second_size) {
u64 i = 0ULL;
u64 p = 0ULL;
if (arg == (const char *)0 ||
out_first == (char *)0 || out_first_size == 0ULL ||
out_second == (char *)0 || out_second_size == 0ULL) {
return 0;
}
out_first[0] = '\0';
out_second[0] = '\0';
while (arg[i] != '\0' && ush_is_space(arg[i]) != 0) {
i++;
}
if (arg[i] == '\0') {
return 0;
}
while (arg[i] != '\0' && ush_is_space(arg[i]) == 0) {
if (p + 1ULL < out_first_size) {
out_first[p++] = arg[i];
}
i++;
}
out_first[p] = '\0';
while (arg[i] != '\0' && ush_is_space(arg[i]) != 0) {
i++;
}
if (arg[i] == '\0') {
return 0;
}
p = 0ULL;
while (arg[i] != '\0' && ush_is_space(arg[i]) == 0) {
if (p + 1ULL < out_second_size) {
out_second[p++] = arg[i];
}
i++;
}
out_second[p] = '\0';
return (out_first[0] != '\0' && out_second[0] != '\0') ? 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;
}
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;
}

View File

@@ -0,0 +1,98 @@
#ifndef CLEONOS_CMD_RUNTIME_H
#define CLEONOS_CMD_RUNTIME_H
#include <cleonos_syscall.h>
typedef long long i64;
#define USH_CMD_MAX 32ULL
#define USH_ARG_MAX 160ULL
#define USH_LINE_MAX 192ULL
#define USH_PATH_MAX 192ULL
#define USH_CAT_MAX 512ULL
#define USH_SCRIPT_MAX 1024ULL
#define USH_CLEAR_LINES 56ULL
#define USH_HISTORY_MAX 16ULL
#define USH_DMESG_DEFAULT 64ULL
#define USH_DMESG_LINE_MAX 256ULL
#define USH_COPY_MAX 65536U
#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 {
char line[USH_LINE_MAX];
u64 line_len;
u64 cursor;
u64 rendered_len;
char cwd[USH_PATH_MAX];
char history[USH_HISTORY_MAX][USH_LINE_MAX];
u64 history_count;
i64 history_nav;
char nav_saved_line[USH_LINE_MAX];
u64 nav_saved_len;
u64 nav_saved_cursor;
u64 cmd_total;
u64 cmd_ok;
u64 cmd_fail;
u64 cmd_unknown;
int exit_requested;
u64 exit_code;
} 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;
extern const char *ush_pipeline_stdin_text;
extern u64 ush_pipeline_stdin_len;
void ush_zero(void *ptr, u64 size);
void ush_init_state(ush_state *sh);
u64 ush_strlen(const char *str);
int ush_streq(const char *left, const char *right);
int ush_is_space(char ch);
int ush_is_printable(char ch);
int ush_has_suffix(const char *name, const char *suffix);
int ush_contains_char(const char *text, char needle);
int ush_parse_u64_dec(const char *text, u64 *out_value);
void ush_copy(char *dst, u64 dst_size, const char *src);
void ush_trim_line(char *line);
void ush_parse_line(const char *line, char *out_cmd, u64 cmd_size, char *out_arg, u64 arg_size);
void ush_write(const char *text);
void ush_write_char(char ch);
void ush_writeln(const char *text);
void ush_write_hex_u64(u64 value);
void ush_print_kv_hex(const char *label, u64 value);
int ush_resolve_path(const ush_state *sh, const char *arg, char *out_path, u64 out_size);
int ush_resolve_exec_path(const ush_state *sh, const char *arg, char *out_path, u64 out_size);
int ush_path_is_under_system(const char *path);
int ush_path_is_under_temp(const char *path);
int ush_split_first_and_rest(const char *arg, char *out_first, u64 out_first_size, const char **out_rest);
int ush_split_two_args(const char *arg,
char *out_first,
u64 out_first_size,
char *out_second,
u64 out_second_size);
int ush_command_ctx_read(ush_cmd_ctx *out_ctx);
int ush_command_ret_write(const ush_cmd_ret *ret);
#endif

View File

@@ -1,6 +1,120 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_copy_file(const char *src_path, const char *dst_path) {
static char copy_buf[USH_COPY_MAX];
u64 src_type;
u64 src_size;
u64 got;
int cleonos_app_main(void) { src_type = cleonos_sys_fs_stat_type(src_path);
return ush_command_program_main("cp");
if (src_type != 1ULL) {
ush_writeln("cp: source file not found");
return 0;
}
src_size = cleonos_sys_fs_stat_size(src_path);
if (src_size == (u64)-1) {
ush_writeln("cp: failed to stat source");
return 0;
}
if (src_size > (u64)USH_COPY_MAX) {
ush_writeln("cp: source too large for user shell buffer");
return 0;
}
if (src_size == 0ULL) {
got = 0ULL;
} else {
got = cleonos_sys_fs_read(src_path, copy_buf, src_size);
if (got == 0ULL || got != src_size) {
ush_writeln("cp: failed to read source");
return 0;
}
}
if (cleonos_sys_fs_write(dst_path, copy_buf, got) == 0ULL) {
ush_writeln("cp: failed to write destination");
return 0;
}
return 1;
}
static int ush_cmd_cp(const ush_state *sh, const char *arg) {
char src_arg[USH_PATH_MAX];
char dst_arg[USH_PATH_MAX];
char src_path[USH_PATH_MAX];
char dst_path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("cp: usage cp <src> <dst>");
return 0;
}
if (ush_split_two_args(arg, src_arg, (u64)sizeof(src_arg), dst_arg, (u64)sizeof(dst_arg)) == 0) {
ush_writeln("cp: usage cp <src> <dst>");
return 0;
}
if (ush_resolve_path(sh, src_arg, src_path, (u64)sizeof(src_path)) == 0 ||
ush_resolve_path(sh, dst_arg, dst_path, (u64)sizeof(dst_path)) == 0) {
ush_writeln("cp: invalid path");
return 0;
}
if (ush_path_is_under_temp(dst_path) == 0) {
ush_writeln("cp: destination must be under /temp");
return 0;
}
return ush_copy_file(src_path, dst_path);
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "cp") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_cp(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,81 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_dmesg(const char *arg) {
u64 total = cleonos_sys_log_journal_count();
u64 limit = USH_DMESG_DEFAULT;
u64 start;
u64 i;
int cleonos_app_main(void) { if (arg != (const char *)0 && arg[0] != '\0') {
return ush_command_program_main("dmesg"); if (ush_parse_u64_dec(arg, &limit) == 0 || limit == 0ULL) {
ush_writeln("dmesg: usage dmesg [positive_count]");
return 0;
}
}
if (total == 0ULL) {
ush_writeln("(journal empty)");
return 1;
}
if (limit > total) {
limit = total;
}
start = total - limit;
for (i = start; i < total; i++) {
char line[USH_DMESG_LINE_MAX];
if (cleonos_sys_log_journal_read(i, line, (u64)sizeof(line)) != 0ULL) {
ush_writeln(line);
}
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "dmesg") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_dmesg(arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,76 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_exec(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
u64 status;
int cleonos_app_main(void) { if (ush_resolve_exec_path(sh, arg, path, (u64)sizeof(path)) == 0) {
return ush_command_program_main("exec"); ush_writeln("exec: invalid target");
return 0;
}
if (ush_path_is_under_system(path) != 0) {
ush_writeln("exec: /system/*.elf is kernel-mode (KELF), not user-exec");
return 0;
}
status = cleonos_sys_exec_path(path);
if (status == (u64)-1) {
ush_writeln("exec: request failed");
return 0;
}
if (status == 0ULL) {
ush_writeln("exec: request accepted");
return 1;
}
ush_writeln("exec: returned non-zero status");
return 0;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "exec") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_exec(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,67 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_exit(ush_state *sh, const char *arg) {
u64 code = 0ULL;
int cleonos_app_main(void) { if (sh == (ush_state *)0) {
return ush_command_program_main("exit"); return 0;
}
if (arg != (const char *)0 && arg[0] != '\0') {
if (ush_parse_u64_dec(arg, &code) == 0) {
ush_writeln("exit: usage exit [code]");
return 0;
}
}
sh->exit_requested = 1;
sh->exit_code = code;
(void)cleonos_sys_exit(code);
ush_writeln("exit: shell stopping");
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "exit") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_exit(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,5 +1,213 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static u64 ush_fastfetch_u64_to_dec(char *out, u64 out_size, u64 value) {
char rev[32];
u64 digits = 0ULL;
u64 i;
if (out == (char *)0 || out_size == 0ULL) {
return 0ULL;
}
if (value == 0ULL) {
if (out_size < 2ULL) {
return 0ULL;
}
out[0] = '0';
out[1] = '\0';
return 1ULL;
}
while (value > 0ULL && digits < (u64)sizeof(rev)) {
rev[digits++] = (char)('0' + (value % 10ULL));
value /= 10ULL;
}
if (digits + 1ULL > out_size) {
out[0] = '\0';
return 0ULL;
}
for (i = 0ULL; i < digits; i++) {
out[i] = rev[digits - 1ULL - i];
}
out[digits] = '\0';
return digits;
}
static void ush_fastfetch_write_u64_dec(u64 value) {
char text[32];
if (ush_fastfetch_u64_to_dec(text, (u64)sizeof(text), value) == 0ULL) {
ush_write("0");
return;
}
ush_write(text);
}
static void ush_fastfetch_write_key(int plain, const char *key) {
ush_write(" ");
if (plain == 0) {
ush_write("\x1B[1;96m");
}
ush_write(key);
if (plain == 0) {
ush_write("\x1B[0m");
}
ush_write(": ");
}
static void ush_fastfetch_print_text(int plain, const char *key, const char *value) {
ush_fastfetch_write_key(plain, key);
ush_writeln(value);
}
static void ush_fastfetch_print_u64(int plain, const char *key, u64 value) {
ush_fastfetch_write_key(plain, key);
ush_fastfetch_write_u64_dec(value);
ush_write_char('\n');
}
static void ush_fastfetch_print_logo(int plain) {
if (plain == 0) {
ush_writeln("\x1B[1;34m $$$$$$\\ $$\\ $$$$$$\\ $$$$$$\\ \x1B[0m");
ush_writeln("\x1B[1;36m$$ __$$\\ $$ | $$ __$$\\ $$ __$$\\ \x1B[0m");
ush_writeln("\x1B[1;32m$$ / \\__|$$ | $$$$$$\\ $$$$$$\\ $$$$$$$\\ $$ / $$ |$$ / \\__|\x1B[0m");
ush_writeln("\x1B[1;33m$$ | $$ | $$ __$$\\ $$ __$$\\ $$ __$$\\ $$ | $$ |\\$$$$$$\\ \x1B[0m");
ush_writeln("\x1B[1;31m$$ | $$ | $$$$$$$$ |$$ / $$ |$$ | $$ |$$ | $$ | \\____$$\\ \x1B[0m");
ush_writeln("\x1B[1;35m$$ | $$\\ $$ | $$ ____|$$ | $$ |$$ | $$ |$$ | $$ |$$\\ $$ |\x1B[0m");
ush_writeln("\x1B[1;94m\\$$$$$$ |$$$$$$$$\\ \\$$$$$$$\\ \\$$$$$$ |$$ | $$ | $$$$$$ |\\$$$$$$ |\x1B[0m");
ush_writeln("\x1B[1;96m \\______/ \\________| \\_______| \\______/ \\__| \\__| \\______/ \\______/ \x1B[0m");
ush_writeln(" ");
ush_writeln(" ");
} else {
ush_writeln(" $$$$$$\\ $$\\ $$$$$$\\ $$$$$$\\ ");
ush_writeln("$$ __$$\\ $$ | $$ __$$\\ $$ __$$\\ ");
ush_writeln("$$ / \\__|$$ | $$$$$$\\ $$$$$$\\ $$$$$$$\\ $$ / $$ |$$ / \\__|");
ush_writeln("$$ | $$ | $$ __$$\\ $$ __$$\\ $$ __$$\\ $$ | $$ |\\$$$$$$\\ ");
ush_writeln("$$ | $$ | $$$$$$$$ |$$ / $$ |$$ | $$ |$$ | $$ | \\____$$\\ ");
ush_writeln("$$ | $$\\ $$ | $$ ____|$$ | $$ |$$ | $$ |$$ | $$ |$$\\ $$ |");
ush_writeln("\\$$$$$$ |$$$$$$$$\\ \\$$$$$$$\\ \\$$$$$$ |$$ | $$ | $$$$$$ |\\$$$$$$ |");
ush_writeln(" \\______/ \\________| \\_______| \\______/ \\__| \\__| \\______/ \\______/ ");
ush_writeln(" ");
ush_writeln(" ");
}
}
static void ush_fastfetch_print_palette(int plain) {
ush_fastfetch_write_key(plain, "Palette");
if (plain != 0) {
ush_writeln("ANSI16");
return;
}
ush_write("\x1B[40m \x1B[0m\x1B[41m \x1B[0m\x1B[42m \x1B[0m\x1B[43m \x1B[0m");
ush_write("\x1B[44m \x1B[0m\x1B[45m \x1B[0m\x1B[46m \x1B[0m\x1B[47m \x1B[0m ");
ush_write("\x1B[100m \x1B[0m\x1B[101m \x1B[0m\x1B[102m \x1B[0m\x1B[103m \x1B[0m");
ush_write("\x1B[104m \x1B[0m\x1B[105m \x1B[0m\x1B[106m \x1B[0m\x1B[107m \x1B[0m");
ush_write_char('\n');
}
static int ush_cmd_fastfetch(const char *arg) {
int plain = 0;
u64 tty_active;
u64 tty_count;
u64 exec_req;
u64 exec_ok;
if (arg != (const char *)0 && arg[0] != '\0') {
if (ush_streq(arg, "--plain") != 0) {
plain = 1;
} else if (ush_streq(arg, "--help") != 0 || ush_streq(arg, "-h") != 0) {
ush_writeln("usage: fastfetch [--plain]");
return 1;
} else {
ush_writeln("fastfetch: usage fastfetch [--plain]");
return 0;
}
}
tty_active = cleonos_sys_tty_active();
tty_count = cleonos_sys_tty_count();
exec_req = cleonos_sys_exec_request_count();
exec_ok = cleonos_sys_exec_success_count();
ush_fastfetch_print_logo(plain);
ush_write_char('\n');
ush_fastfetch_print_text(plain, "OS", "CLeonOS x86_64");
ush_fastfetch_print_text(plain, "Shell", "User Shell (/shell/shell.elf)");
ush_fastfetch_print_u64(plain, "PID", cleonos_sys_getpid());
ush_fastfetch_print_u64(plain, "UptimeTicks", cleonos_sys_timer_ticks());
ush_fastfetch_print_u64(plain, "Tasks", cleonos_sys_task_count());
ush_fastfetch_print_u64(plain, "Services", cleonos_sys_service_count());
ush_fastfetch_print_u64(plain, "SvcReady", cleonos_sys_service_ready_count());
ush_fastfetch_print_u64(plain, "CtxSwitches", cleonos_sys_context_switches());
ush_fastfetch_print_u64(plain, "KELFApps", cleonos_sys_kelf_count());
ush_fastfetch_print_u64(plain, "KELFRuns", cleonos_sys_kelf_runs());
ush_fastfetch_print_u64(plain, "FSNodes", cleonos_sys_fs_node_count());
ush_fastfetch_print_u64(plain, "RootChildren", cleonos_sys_fs_child_count("/"));
ush_fastfetch_write_key(plain, "TTY");
ush_fastfetch_write_u64_dec(tty_active);
ush_write(" / ");
ush_fastfetch_write_u64_dec(tty_count);
ush_write_char('\n');
ush_fastfetch_write_key(plain, "ExecSuccess");
ush_fastfetch_write_u64_dec(exec_ok);
ush_write(" / ");
ush_fastfetch_write_u64_dec(exec_req);
ush_write_char('\n');
ush_fastfetch_print_u64(plain, "KbdBuffered", cleonos_sys_kbd_buffered());
ush_fastfetch_print_palette(plain);
return 1;
}
int cleonos_app_main(void) { int cleonos_app_main(void) {
return ush_command_program_main("fastfetch"); ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "fastfetch") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_fastfetch(arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,55 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_fsstat(void) {
int cleonos_app_main(void) { ush_writeln("fsstat:");
return ush_command_program_main("fsstat"); ush_print_kv_hex(" NODE_COUNT", cleonos_sys_fs_node_count());
ush_print_kv_hex(" ROOT_CHILDREN", cleonos_sys_fs_child_count("/"));
ush_print_kv_hex(" SYSTEM_CHILDREN", cleonos_sys_fs_child_count("/system"));
ush_print_kv_hex(" SHELL_CHILDREN", cleonos_sys_fs_child_count("/shell"));
ush_print_kv_hex(" TEMP_CHILDREN", cleonos_sys_fs_child_count("/temp"));
ush_print_kv_hex(" DRIVER_CHILDREN", cleonos_sys_fs_child_count("/driver"));
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "fsstat") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_fsstat();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,5 +1,248 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static void ush_grep_write_u64_dec(u64 value) {
char tmp[32];
u64 len = 0ULL;
if (value == 0ULL) {
ush_write_char('0');
return;
}
while (value > 0ULL && len < (u64)sizeof(tmp)) {
tmp[len++] = (char)('0' + (value % 10ULL));
value /= 10ULL;
}
while (len > 0ULL) {
len--;
ush_write_char(tmp[len]);
}
}
static int ush_grep_line_has_pattern(const char *line, u64 line_len, const char *pattern, u64 pattern_len) {
u64 i;
if (line == (const char *)0 || pattern == (const char *)0) {
return 0;
}
if (pattern_len == 0ULL) {
return 1;
}
if (pattern_len > line_len) {
return 0;
}
for (i = 0ULL; i + pattern_len <= line_len; i++) {
u64 j = 0ULL;
while (j < pattern_len && line[i + j] == pattern[j]) {
j++;
}
if (j == pattern_len) {
return 1;
}
}
return 0;
}
static u64 ush_grep_emit_matches(const char *input, u64 input_len, const char *pattern, int with_line_number) {
u64 matches = 0ULL;
u64 line_no = 1ULL;
u64 start = 0ULL;
u64 i;
u64 pattern_len;
if (input == (const char *)0 || pattern == (const char *)0) {
return 0ULL;
}
pattern_len = ush_strlen(pattern);
for (i = 0ULL; i <= input_len; i++) {
if (i == input_len || input[i] == '\n') {
u64 line_len = i - start;
if (ush_grep_line_has_pattern(&input[start], line_len, pattern, pattern_len) != 0) {
u64 j;
matches++;
if (with_line_number != 0) {
ush_grep_write_u64_dec(line_no);
ush_write(":");
}
for (j = 0ULL; j < line_len; j++) {
ush_write_char(input[start + j]);
}
ush_write_char('\n');
}
start = i + 1ULL;
line_no++;
}
}
return matches;
}
static int ush_cmd_grep(const ush_state *sh, const char *arg) {
char first[USH_PATH_MAX];
char second[USH_PATH_MAX];
char third[USH_PATH_MAX];
char path[USH_PATH_MAX];
const char *rest = "";
const char *rest2 = "";
const char *pattern = (const char *)0;
const char *file_arg = (const char *)0;
const char *input = (const char *)0;
u64 input_len = 0ULL;
u64 size;
u64 got;
int with_line_number = 0;
static char file_buf[USH_COPY_MAX + 1U];
if (sh == (const ush_state *)0 || arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
if (ush_split_first_and_rest(arg, first, (u64)sizeof(first), &rest) == 0) {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
if (ush_streq(first, "-n") != 0) {
with_line_number = 1;
if (ush_split_first_and_rest(rest, second, (u64)sizeof(second), &rest2) == 0) {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
pattern = second;
rest = rest2;
} else {
pattern = first;
}
if (rest != (const char *)0 && rest[0] != '\0') {
if (ush_split_first_and_rest(rest, third, (u64)sizeof(third), &rest2) == 0) {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
file_arg = third;
if (rest2 != (const char *)0 && rest2[0] != '\0') {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
}
if (pattern == (const char *)0 || pattern[0] == '\0') {
ush_writeln("grep: pattern required");
return 0;
}
if (file_arg != (const char *)0) {
if (ush_resolve_path(sh, file_arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("grep: invalid path");
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
ush_writeln("grep: file not found");
return 0;
}
size = cleonos_sys_fs_stat_size(path);
if (size == (u64)-1) {
ush_writeln("grep: failed to stat file");
return 0;
}
if (size > (u64)USH_COPY_MAX) {
ush_writeln("grep: file too large for user buffer");
return 0;
}
if (size == 0ULL) {
return 1;
}
got = cleonos_sys_fs_read(path, file_buf, size);
if (got == 0ULL || got != size) {
ush_writeln("grep: read failed");
return 0;
}
file_buf[got] = '\0';
input = file_buf;
input_len = got;
} else {
if (ush_pipeline_stdin_text == (const char *)0) {
ush_writeln("grep: file path required (or pipeline input)");
return 0;
}
input = ush_pipeline_stdin_text;
input_len = ush_pipeline_stdin_len;
}
(void)ush_grep_emit_matches(input, input_len, pattern, with_line_number);
return 1;
}
int cleonos_app_main(void) { int cleonos_app_main(void) {
return ush_command_program_main("grep"); ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "grep") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_grep(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,81 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_help(void) {
int cleonos_app_main(void) { ush_writeln("commands:");
return ush_command_program_main("help"); ush_writeln(" help");
ush_writeln(" ls [-l] [-R] [path]");
ush_writeln(" cat [file] (reads pipeline input when file omitted)");
ush_writeln(" grep [-n] <pattern> [file]");
ush_writeln(" pwd");
ush_writeln(" cd [dir]");
ush_writeln(" exec|run <path|name>");
ush_writeln(" clear");
ush_writeln(" ansi / ansitest / color");
ush_writeln(" fastfetch [--plain]");
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
ush_writeln(" tty [index]");
ush_writeln(" dmesg [n]");
ush_writeln(" kbdstat");
ush_writeln(" mkdir <dir> (/temp only)");
ush_writeln(" touch <file> (/temp only)");
ush_writeln(" write <file> <text> (/temp only, or from pipeline)");
ush_writeln(" append <file> <text> (/temp only, or from pipeline)");
ush_writeln(" cp <src> <dst> (dst /temp only)");
ush_writeln(" mv <src> <dst> (/temp only)");
ush_writeln(" rm <path> (/temp only)");
ush_writeln(" pid");
ush_writeln(" spawn <path|name>");
ush_writeln(" wait <pid>");
ush_writeln(" sleep <ticks>");
ush_writeln(" yield");
ush_writeln(" shutdown / restart");
ush_writeln(" exit [code]");
ush_writeln(" rusttest / panic / elfloader (kernel shell only)");
ush_writeln("pipeline/redirection: cmd1 | cmd2 | cmd3 > /temp/out.txt");
ush_writeln("redirection append: cmd >> /temp/out.txt");
ush_writeln("edit keys: Left/Right, Home/End, Up/Down history");
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "help") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_help();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,54 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_kbdstat(void) {
int cleonos_app_main(void) { ush_writeln("kbdstat:");
return ush_command_program_main("kbdstat"); ush_print_kv_hex(" BUFFERED", cleonos_sys_kbd_buffered());
ush_print_kv_hex(" PUSHED", cleonos_sys_kbd_pushed());
ush_print_kv_hex(" POPPED", cleonos_sys_kbd_popped());
ush_print_kv_hex(" DROPPED", cleonos_sys_kbd_dropped());
ush_print_kv_hex(" HOTKEY_SWITCHES", cleonos_sys_kbd_hotkey_switches());
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "kbdstat") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_kbdstat();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,337 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_ls_join_path(const char *dir_path, const char *name, char *out_path, u64 out_size) {
u64 p = 0ULL;
u64 i;
int cleonos_app_main(void) { if (dir_path == (const char *)0 || name == (const char *)0 || out_path == (char *)0 || out_size == 0ULL) {
return ush_command_program_main("ls"); 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 i;
if (depth > 16ULL) {
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) {
ush_writeln("ls: invalid path");
return 0;
}
type = cleonos_sys_fs_stat_type(path);
if (type == 1ULL) {
u64 size = cleonos_sys_fs_stat_size(path);
ush_ls_print_one(ush_ls_basename(path), type, size, long_mode);
return 1;
}
if (type != 2ULL) {
ush_writeln("ls: path not found");
return 0;
}
return ush_ls_dir(path, long_mode, recursive, recursive, 0ULL);
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "ls") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_ls(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,53 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_memstat(void) {
int cleonos_app_main(void) { ush_writeln("memstat (user ABI limited):");
return ush_command_program_main("memstat"); ush_print_kv_hex(" SERVICE_COUNT", cleonos_sys_service_count());
ush_print_kv_hex(" SERVICE_READY_COUNT", cleonos_sys_service_ready_count());
ush_print_kv_hex(" KELF_COUNT", cleonos_sys_kelf_count());
ush_print_kv_hex(" KELF_RUNS", cleonos_sys_kelf_runs());
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "memstat") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_memstat();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,72 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_mkdir(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("mkdir"); ush_writeln("mkdir: directory path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("mkdir: invalid path");
return 0;
}
if (ush_path_is_under_temp(path) == 0) {
ush_writeln("mkdir: target must be under /temp");
return 0;
}
if (cleonos_sys_fs_mkdir(path) == 0ULL) {
ush_writeln("mkdir: failed");
return 0;
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "mkdir") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_mkdir(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,129 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_copy_file(const char *src_path, const char *dst_path) {
static char copy_buf[USH_COPY_MAX];
u64 src_type;
u64 src_size;
u64 got;
int cleonos_app_main(void) { src_type = cleonos_sys_fs_stat_type(src_path);
return ush_command_program_main("mv");
if (src_type != 1ULL) {
ush_writeln("cp: source file not found");
return 0;
}
src_size = cleonos_sys_fs_stat_size(src_path);
if (src_size == (u64)-1) {
ush_writeln("cp: failed to stat source");
return 0;
}
if (src_size > (u64)USH_COPY_MAX) {
ush_writeln("cp: source too large for user shell buffer");
return 0;
}
if (src_size == 0ULL) {
got = 0ULL;
} else {
got = cleonos_sys_fs_read(src_path, copy_buf, src_size);
if (got == 0ULL || got != src_size) {
ush_writeln("cp: failed to read source");
return 0;
}
}
if (cleonos_sys_fs_write(dst_path, copy_buf, got) == 0ULL) {
ush_writeln("cp: failed to write destination");
return 0;
}
return 1;
}
static int ush_cmd_mv(const ush_state *sh, const char *arg) {
char src_arg[USH_PATH_MAX];
char dst_arg[USH_PATH_MAX];
char src_path[USH_PATH_MAX];
char dst_path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("mv: usage mv <src> <dst>");
return 0;
}
if (ush_split_two_args(arg, src_arg, (u64)sizeof(src_arg), dst_arg, (u64)sizeof(dst_arg)) == 0) {
ush_writeln("mv: usage mv <src> <dst>");
return 0;
}
if (ush_resolve_path(sh, src_arg, src_path, (u64)sizeof(src_path)) == 0 ||
ush_resolve_path(sh, dst_arg, dst_path, (u64)sizeof(dst_path)) == 0) {
ush_writeln("mv: invalid path");
return 0;
}
if (ush_path_is_under_temp(src_path) == 0 || ush_path_is_under_temp(dst_path) == 0) {
ush_writeln("mv: source and destination must be under /temp");
return 0;
}
if (ush_copy_file(src_path, dst_path) == 0) {
return 0;
}
if (cleonos_sys_fs_remove(src_path) == 0ULL) {
ush_writeln("mv: source remove failed");
return 0;
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "mv") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_mv(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,49 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_pid(void) {
int cleonos_app_main(void) { ush_print_kv_hex("PID", cleonos_sys_getpid());
return ush_command_program_main("pid"); return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "pid") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_pid();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,49 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_pwd(const ush_state *sh) {
int cleonos_app_main(void) { ush_writeln(sh->cwd);
return ush_command_program_main("pwd"); return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "pwd") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_pwd(&sh);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,50 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_restart(void) {
int cleonos_app_main(void) { ush_writeln("restart: rebooting...");
return ush_command_program_main("restart"); (void)cleonos_sys_restart();
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "restart") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_restart();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,72 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_rm(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("rm"); ush_writeln("rm: path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("rm: invalid path");
return 0;
}
if (ush_path_is_under_temp(path) == 0) {
ush_writeln("rm: target must be under /temp");
return 0;
}
if (cleonos_sys_fs_remove(path) == 0ULL) {
ush_writeln("rm: failed (directory must be empty)");
return 0;
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "rm") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_rm(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,8 +0,0 @@
static int ush_cmd_ansi(void) {
ush_writeln("\x1B[1;36mansi color demo\x1B[0m");
ush_writeln(" \x1B[30mblack\x1B[0m \x1B[31mred\x1B[0m \x1B[32mgreen\x1B[0m \x1B[33myellow\x1B[0m");
ush_writeln(" \x1B[34mblue\x1B[0m \x1B[35mmagenta\x1B[0m \x1B[36mcyan\x1B[0m \x1B[37mwhite\x1B[0m");
ush_writeln(" \x1B[90mbright-black\x1B[0m \x1B[91mbright-red\x1B[0m \x1B[92mbright-green\x1B[0m \x1B[93mbright-yellow\x1B[0m");
ush_writeln(" \x1B[94mbright-blue\x1B[0m \x1B[95mbright-magenta\x1B[0m \x1B[96mbright-cyan\x1B[0m \x1B[97mbright-white\x1B[0m");
return 1;
}

View File

@@ -1,41 +0,0 @@
static int ush_cmd_ansitest(void) {
u64 i;
ush_writeln("\x1B[1;96mANSI test suite\x1B[0m");
ush_writeln("styles: \x1B[1mbold\x1B[0m \x1B[7minverse\x1B[0m \x1B[4munderline\x1B[0m");
ush_writeln("16-color demo:");
(void)ush_cmd_ansi();
ush_writeln("256-color palette (0..255):");
for (i = 0ULL; i < 256ULL; i++) {
ush_ansitest_emit_bg256(i);
if ((i % 32ULL) == 31ULL) {
ush_write_char('\n');
}
}
ush_write_char('\n');
ush_writeln("truecolor demo:");
ush_writeln(" \x1B[38;2;255;64;64mRGB(255,64,64)\x1B[0m \x1B[38;2;64;255;64mRGB(64,255,64)\x1B[0m \x1B[38;2;64;128;255mRGB(64,128,255)\x1B[0m");
ush_writeln("cursor control demo:");
ush_write(" 0123456789");
ush_write("\x1B[5D");
ush_write("\x1B[93m<OK>\x1B[0m");
ush_write_char('\n');
ush_write(" save");
ush_write("\x1B[s");
ush_write("....");
ush_write("\x1B[u");
ush_write("\x1B[92m<restore>\x1B[0m");
ush_write_char('\n');
ush_writeln("erase-line demo:");
ush_write(" left|right-to-clear");
ush_write("\x1B[14D\x1B[K");
ush_write_char('\n');
ush_writeln("ansitest done");
return 1;
}

View File

@@ -1,43 +0,0 @@
static void ush_ansitest_emit_bg256(u64 index) {
char num[4];
char seq[24];
u64 digits;
u64 p = 0ULL;
u64 i;
if (index > 255U) {
index = 255U;
}
digits = ush_ansitest_u64_to_dec(num, (u64)sizeof(num), index);
if (digits == 0ULL) {
return;
}
seq[p++] = '\x1B';
seq[p++] = '[';
seq[p++] = '4';
seq[p++] = '8';
seq[p++] = ';';
seq[p++] = '5';
seq[p++] = ';';
for (i = 0ULL; i < digits && p + 1ULL < (u64)sizeof(seq); i++) {
seq[p++] = num[i];
}
if (p + 7ULL >= (u64)sizeof(seq)) {
return;
}
seq[p++] = 'm';
seq[p++] = ' ';
seq[p++] = ' ';
seq[p++] = '\x1B';
seq[p++] = '[';
seq[p++] = '0';
seq[p++] = 'm';
seq[p] = '\0';
ush_write(seq);
}

View File

@@ -1,36 +0,0 @@
static u64 ush_ansitest_u64_to_dec(char *out, u64 out_size, u64 value) {
char rev[10];
u64 digits = 0ULL;
u64 i;
if (out == (char *)0 || out_size == 0ULL) {
return 0ULL;
}
if (value == 0U) {
if (out_size < 2ULL) {
return 0ULL;
}
out[0] = '0';
out[1] = '\0';
return 1ULL;
}
while (value > 0U && digits < (u64)sizeof(rev)) {
rev[digits++] = (char)('0' + (value % 10U));
value /= 10U;
}
if (digits + 1ULL > out_size) {
out[0] = '\0';
return 0ULL;
}
for (i = 0ULL; i < digits; i++) {
out[i] = rev[digits - 1ULL - i];
}
out[digits] = '\0';
return digits;
}

View File

@@ -1,44 +0,0 @@
static int ush_cmd_append(const ush_state *sh, const char *arg) {
char path_arg[USH_PATH_MAX];
char abs_path[USH_PATH_MAX];
const char *payload = (const char *)0;
u64 payload_len;
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("append: usage append <file> <text>");
return 0;
}
if (ush_split_first_and_rest(arg, path_arg, (u64)sizeof(path_arg), &payload) == 0) {
ush_writeln("append: usage append <file> <text>");
return 0;
}
if (ush_resolve_path(sh, path_arg, abs_path, (u64)sizeof(abs_path)) == 0) {
ush_writeln("append: invalid path");
return 0;
}
if (ush_path_is_under_temp(abs_path) == 0) {
ush_writeln("append: target must be under /temp");
return 0;
}
if (payload == (const char *)0 || payload[0] == '\0') {
if (ush_pipeline_stdin_text == (const char *)0) {
ush_writeln("append: usage append <file> <text>");
return 0;
}
payload = ush_pipeline_stdin_text;
payload_len = ush_pipeline_stdin_len;
} else {
payload_len = ush_strlen(payload);
}
if (cleonos_sys_fs_append(abs_path, payload, payload_len) == 0ULL) {
ush_writeln("append: failed");
return 0;
}
return 1;
}

View File

@@ -1,59 +0,0 @@
static int ush_cmd_cat(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
char buf[USH_CAT_MAX + 1ULL];
u64 size;
u64 req;
u64 got;
if (arg == (const char *)0 || arg[0] == '\0') {
if (ush_pipeline_stdin_text != (const char *)0 && ush_pipeline_stdin_len > 0ULL) {
ush_write(ush_pipeline_stdin_text);
return 1;
}
ush_writeln("cat: file path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("cat: invalid path");
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
ush_writeln("cat: file not found");
return 0;
}
size = cleonos_sys_fs_stat_size(path);
if (size == (u64)-1) {
ush_writeln("cat: failed to stat file");
return 0;
}
if (size == 0ULL) {
return 1;
}
req = (size < USH_CAT_MAX) ? size : USH_CAT_MAX;
got = cleonos_sys_fs_read(path, buf, req);
if (got == 0ULL) {
ush_writeln("cat: read failed");
return 0;
}
if (got > USH_CAT_MAX) {
got = USH_CAT_MAX;
}
buf[got] = '\0';
ush_writeln(buf);
if (size > got) {
ush_writeln("[cat] output truncated");
}
return 1;
}

View File

@@ -1,21 +0,0 @@
static int ush_cmd_cd(ush_state *sh, const char *arg) {
const char *target = arg;
char path[USH_PATH_MAX];
if (target == (const char *)0 || target[0] == '\0') {
target = "/";
}
if (ush_resolve_path(sh, target, path, (u64)sizeof(path)) == 0) {
ush_writeln("cd: invalid path");
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 2ULL) {
ush_writeln("cd: directory not found");
return 0;
}
ush_copy(sh->cwd, (u64)sizeof(sh->cwd), path);
return 1;
}

View File

@@ -1,4 +0,0 @@
static int ush_cmd_clear(void) {
ush_write("\x1B[2J\x1B[H");
return 1;
}

View File

@@ -1,43 +0,0 @@
static int ush_copy_file(const char *src_path, const char *dst_path) {
static char copy_buf[USH_COPY_MAX];
u64 src_type;
u64 src_size;
u64 got;
src_type = cleonos_sys_fs_stat_type(src_path);
if (src_type != 1ULL) {
ush_writeln("cp: source file not found");
return 0;
}
src_size = cleonos_sys_fs_stat_size(src_path);
if (src_size == (u64)-1) {
ush_writeln("cp: failed to stat source");
return 0;
}
if (src_size > (u64)USH_COPY_MAX) {
ush_writeln("cp: source too large for user shell buffer");
return 0;
}
if (src_size == 0ULL) {
got = 0ULL;
} else {
got = cleonos_sys_fs_read(src_path, copy_buf, src_size);
if (got == 0ULL || got != src_size) {
ush_writeln("cp: failed to read source");
return 0;
}
}
if (cleonos_sys_fs_write(dst_path, copy_buf, got) == 0ULL) {
ush_writeln("cp: failed to write destination");
return 0;
}
return 1;
}

View File

@@ -1,29 +0,0 @@
static int ush_cmd_cp(const ush_state *sh, const char *arg) {
char src_arg[USH_PATH_MAX];
char dst_arg[USH_PATH_MAX];
char src_path[USH_PATH_MAX];
char dst_path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("cp: usage cp <src> <dst>");
return 0;
}
if (ush_split_two_args(arg, src_arg, (u64)sizeof(src_arg), dst_arg, (u64)sizeof(dst_arg)) == 0) {
ush_writeln("cp: usage cp <src> <dst>");
return 0;
}
if (ush_resolve_path(sh, src_arg, src_path, (u64)sizeof(src_path)) == 0 ||
ush_resolve_path(sh, dst_arg, dst_path, (u64)sizeof(dst_path)) == 0) {
ush_writeln("cp: invalid path");
return 0;
}
if (ush_path_is_under_temp(dst_path) == 0) {
ush_writeln("cp: destination must be under /temp");
return 0;
}
return ush_copy_file(src_path, dst_path);
}

View File

@@ -1,34 +0,0 @@
static int ush_cmd_dmesg(const char *arg) {
u64 total = cleonos_sys_log_journal_count();
u64 limit = USH_DMESG_DEFAULT;
u64 start;
u64 i;
if (arg != (const char *)0 && arg[0] != '\0') {
if (ush_parse_u64_dec(arg, &limit) == 0 || limit == 0ULL) {
ush_writeln("dmesg: usage dmesg [positive_count]");
return 0;
}
}
if (total == 0ULL) {
ush_writeln("(journal empty)");
return 1;
}
if (limit > total) {
limit = total;
}
start = total - limit;
for (i = start; i < total; i++) {
char line[USH_DMESG_LINE_MAX];
if (cleonos_sys_log_journal_read(i, line, (u64)sizeof(line)) != 0ULL) {
ush_writeln(line);
}
}
return 1;
}

View File

@@ -1,29 +0,0 @@
static int ush_cmd_exec(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
u64 status;
if (ush_resolve_exec_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("exec: invalid target");
return 0;
}
if (ush_path_is_under_system(path) != 0) {
ush_writeln("exec: /system/*.elf is kernel-mode (KELF), not user-exec");
return 0;
}
status = cleonos_sys_exec_path(path);
if (status == (u64)-1) {
ush_writeln("exec: request failed");
return 0;
}
if (status == 0ULL) {
ush_writeln("exec: request accepted");
return 1;
}
ush_writeln("exec: returned non-zero status");
return 0;
}

View File

@@ -1,20 +0,0 @@
static int ush_cmd_exit(ush_state *sh, const char *arg) {
u64 code = 0ULL;
if (sh == (ush_state *)0) {
return 0;
}
if (arg != (const char *)0 && arg[0] != '\0') {
if (ush_parse_u64_dec(arg, &code) == 0) {
ush_writeln("exit: usage exit [code]");
return 0;
}
}
sh->exit_requested = 1;
sh->exit_code = code;
(void)cleonos_sys_exit(code);
ush_writeln("exit: shell stopping");
return 1;
}

View File

@@ -1,56 +0,0 @@
static int ush_cmd_fastfetch(const char *arg) {
int plain = 0;
u64 tty_active;
u64 tty_count;
u64 exec_req;
u64 exec_ok;
if (arg != (const char *)0 && arg[0] != '\0') {
if (ush_streq(arg, "--plain") != 0) {
plain = 1;
} else if (ush_streq(arg, "--help") != 0 || ush_streq(arg, "-h") != 0) {
ush_writeln("usage: fastfetch [--plain]");
return 1;
} else {
ush_writeln("fastfetch: usage fastfetch [--plain]");
return 0;
}
}
tty_active = cleonos_sys_tty_active();
tty_count = cleonos_sys_tty_count();
exec_req = cleonos_sys_exec_request_count();
exec_ok = cleonos_sys_exec_success_count();
ush_fastfetch_print_logo(plain);
ush_write_char('\n');
ush_fastfetch_print_text(plain, "OS", "CLeonOS x86_64");
ush_fastfetch_print_text(plain, "Shell", "User Shell (/shell/shell.elf)");
ush_fastfetch_print_u64(plain, "PID", cleonos_sys_getpid());
ush_fastfetch_print_u64(plain, "UptimeTicks", cleonos_sys_timer_ticks());
ush_fastfetch_print_u64(plain, "Tasks", cleonos_sys_task_count());
ush_fastfetch_print_u64(plain, "Services", cleonos_sys_service_count());
ush_fastfetch_print_u64(plain, "SvcReady", cleonos_sys_service_ready_count());
ush_fastfetch_print_u64(plain, "CtxSwitches", cleonos_sys_context_switches());
ush_fastfetch_print_u64(plain, "KELFApps", cleonos_sys_kelf_count());
ush_fastfetch_print_u64(plain, "KELFRuns", cleonos_sys_kelf_runs());
ush_fastfetch_print_u64(plain, "FSNodes", cleonos_sys_fs_node_count());
ush_fastfetch_print_u64(plain, "RootChildren", cleonos_sys_fs_child_count("/"));
ush_fastfetch_write_key(plain, "TTY");
ush_fastfetch_write_u64_dec(tty_active);
ush_write(" / ");
ush_fastfetch_write_u64_dec(tty_count);
ush_write_char('\n');
ush_fastfetch_write_key(plain, "ExecSuccess");
ush_fastfetch_write_u64_dec(exec_ok);
ush_write(" / ");
ush_fastfetch_write_u64_dec(exec_req);
ush_write_char('\n');
ush_fastfetch_print_u64(plain, "KbdBuffered", cleonos_sys_kbd_buffered());
ush_fastfetch_print_palette(plain);
return 1;
}

View File

@@ -1,25 +0,0 @@
static void ush_fastfetch_print_logo(int plain) {
if (plain == 0) {
ush_writeln("\x1B[1;34m $$$$$$\\ $$\\ $$$$$$\\ $$$$$$\\ \x1B[0m");
ush_writeln("\x1B[1;36m$$ __$$\\ $$ | $$ __$$\\ $$ __$$\\ \x1B[0m");
ush_writeln("\x1B[1;32m$$ / \\__|$$ | $$$$$$\\ $$$$$$\\ $$$$$$$\\ $$ / $$ |$$ / \\__|\x1B[0m");
ush_writeln("\x1B[1;33m$$ | $$ | $$ __$$\\ $$ __$$\\ $$ __$$\\ $$ | $$ |\\$$$$$$\\ \x1B[0m");
ush_writeln("\x1B[1;31m$$ | $$ | $$$$$$$$ |$$ / $$ |$$ | $$ |$$ | $$ | \\____$$\\ \x1B[0m");
ush_writeln("\x1B[1;35m$$ | $$\\ $$ | $$ ____|$$ | $$ |$$ | $$ |$$ | $$ |$$\\ $$ |\x1B[0m");
ush_writeln("\x1B[1;94m\\$$$$$$ |$$$$$$$$\\ \\$$$$$$$\\ \\$$$$$$ |$$ | $$ | $$$$$$ |\\$$$$$$ |\x1B[0m");
ush_writeln("\x1B[1;96m \\______/ \\________| \\_______| \\______/ \\__| \\__| \\______/ \\______/ \x1B[0m");
ush_writeln(" ");
ush_writeln(" ");
} else {
ush_writeln(" $$$$$$\\ $$\\ $$$$$$\\ $$$$$$\\ ");
ush_writeln("$$ __$$\\ $$ | $$ __$$\\ $$ __$$\\ ");
ush_writeln("$$ / \\__|$$ | $$$$$$\\ $$$$$$\\ $$$$$$$\\ $$ / $$ |$$ / \\__|");
ush_writeln("$$ | $$ | $$ __$$\\ $$ __$$\\ $$ __$$\\ $$ | $$ |\\$$$$$$\\ ");
ush_writeln("$$ | $$ | $$$$$$$$ |$$ / $$ |$$ | $$ |$$ | $$ | \\____$$\\ ");
ush_writeln("$$ | $$\\ $$ | $$ ____|$$ | $$ |$$ | $$ |$$ | $$ |$$\\ $$ |");
ush_writeln("\\$$$$$$ |$$$$$$$$\\ \\$$$$$$$\\ \\$$$$$$ |$$ | $$ | $$$$$$ |\\$$$$$$ |");
ush_writeln(" \\______/ \\________| \\_______| \\______/ \\__| \\__| \\______/ \\______/ ");
ush_writeln(" ");
ush_writeln(" ");
}
}

View File

@@ -1,14 +0,0 @@
static void ush_fastfetch_print_palette(int plain) {
ush_fastfetch_write_key(plain, "Palette");
if (plain != 0) {
ush_writeln("ANSI16");
return;
}
ush_write("\x1B[40m \x1B[0m\x1B[41m \x1B[0m\x1B[42m \x1B[0m\x1B[43m \x1B[0m");
ush_write("\x1B[44m \x1B[0m\x1B[45m \x1B[0m\x1B[46m \x1B[0m\x1B[47m \x1B[0m ");
ush_write("\x1B[100m \x1B[0m\x1B[101m \x1B[0m\x1B[102m \x1B[0m\x1B[103m \x1B[0m");
ush_write("\x1B[104m \x1B[0m\x1B[105m \x1B[0m\x1B[106m \x1B[0m\x1B[107m \x1B[0m");
ush_write_char('\n');
}

View File

@@ -1,4 +0,0 @@
static void ush_fastfetch_print_text(int plain, const char *key, const char *value) {
ush_fastfetch_write_key(plain, key);
ush_writeln(value);
}

View File

@@ -1,5 +0,0 @@
static void ush_fastfetch_print_u64(int plain, const char *key, u64 value) {
ush_fastfetch_write_key(plain, key);
ush_fastfetch_write_u64_dec(value);
ush_write_char('\n');
}

View File

@@ -1,34 +0,0 @@
static u64 ush_fastfetch_u64_to_dec(char *out, u64 out_size, u64 value) {
char rev[32];
u64 digits = 0ULL;
u64 i;
if (out == (char *)0 || out_size == 0ULL) {
return 0ULL;
}
if (value == 0ULL) {
if (out_size < 2ULL) {
return 0ULL;
}
out[0] = '0';
out[1] = '\0';
return 1ULL;
}
while (value > 0ULL && digits < (u64)sizeof(rev)) {
rev[digits++] = (char)('0' + (value % 10ULL));
value /= 10ULL;
}
if (digits + 1ULL > out_size) {
out[0] = '\0';
return 0ULL;
}
for (i = 0ULL; i < digits; i++) {
out[i] = rev[digits - 1ULL - i];
}
out[digits] = '\0';
return digits;
}

View File

@@ -1,11 +0,0 @@
static void ush_fastfetch_write_key(int plain, const char *key) {
ush_write(" ");
if (plain == 0) {
ush_write("\x1B[1;96m");
}
ush_write(key);
if (plain == 0) {
ush_write("\x1B[0m");
}
ush_write(": ");
}

View File

@@ -1,10 +0,0 @@
static void ush_fastfetch_write_u64_dec(u64 value) {
char text[32];
if (ush_fastfetch_u64_to_dec(text, (u64)sizeof(text), value) == 0ULL) {
ush_write("0");
return;
}
ush_write(text);
}

View File

@@ -1,10 +0,0 @@
static int ush_cmd_fsstat(void) {
ush_writeln("fsstat:");
ush_print_kv_hex(" NODE_COUNT", cleonos_sys_fs_node_count());
ush_print_kv_hex(" ROOT_CHILDREN", cleonos_sys_fs_child_count("/"));
ush_print_kv_hex(" SYSTEM_CHILDREN", cleonos_sys_fs_child_count("/system"));
ush_print_kv_hex(" SHELL_CHILDREN", cleonos_sys_fs_child_count("/shell"));
ush_print_kv_hex(" TEMP_CHILDREN", cleonos_sys_fs_child_count("/temp"));
ush_print_kv_hex(" DRIVER_CHILDREN", cleonos_sys_fs_child_count("/driver"));
return 1;
}

View File

@@ -1,109 +0,0 @@
static int ush_cmd_grep(const ush_state *sh, const char *arg) {
char first[USH_PATH_MAX];
char second[USH_PATH_MAX];
char third[USH_PATH_MAX];
char path[USH_PATH_MAX];
const char *rest = "";
const char *rest2 = "";
const char *pattern = (const char *)0;
const char *file_arg = (const char *)0;
const char *input = (const char *)0;
u64 input_len = 0ULL;
u64 size;
u64 got;
int with_line_number = 0;
static char file_buf[USH_COPY_MAX + 1U];
if (sh == (const ush_state *)0 || arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
if (ush_split_first_and_rest(arg, first, (u64)sizeof(first), &rest) == 0) {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
if (ush_streq(first, "-n") != 0) {
with_line_number = 1;
if (ush_split_first_and_rest(rest, second, (u64)sizeof(second), &rest2) == 0) {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
pattern = second;
rest = rest2;
} else {
pattern = first;
}
if (rest != (const char *)0 && rest[0] != '\0') {
if (ush_split_first_and_rest(rest, third, (u64)sizeof(third), &rest2) == 0) {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
file_arg = third;
if (rest2 != (const char *)0 && rest2[0] != '\0') {
ush_writeln("grep: usage grep [-n] <pattern> [file]");
return 0;
}
}
if (pattern == (const char *)0 || pattern[0] == '\0') {
ush_writeln("grep: pattern required");
return 0;
}
if (file_arg != (const char *)0) {
if (ush_resolve_path(sh, file_arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("grep: invalid path");
return 0;
}
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
ush_writeln("grep: file not found");
return 0;
}
size = cleonos_sys_fs_stat_size(path);
if (size == (u64)-1) {
ush_writeln("grep: failed to stat file");
return 0;
}
if (size > (u64)USH_COPY_MAX) {
ush_writeln("grep: file too large for user buffer");
return 0;
}
if (size == 0ULL) {
return 1;
}
got = cleonos_sys_fs_read(path, file_buf, size);
if (got == 0ULL || got != size) {
ush_writeln("grep: read failed");
return 0;
}
file_buf[got] = '\0';
input = file_buf;
input_len = got;
} else {
if (ush_pipeline_stdin_text == (const char *)0) {
ush_writeln("grep: file path required (or pipeline input)");
return 0;
}
input = ush_pipeline_stdin_text;
input_len = ush_pipeline_stdin_len;
}
(void)ush_grep_emit_matches(input, input_len, pattern, with_line_number);
return 1;
}

View File

@@ -1,41 +0,0 @@
static u64 ush_grep_emit_matches(const char *input, u64 input_len, const char *pattern, int with_line_number) {
u64 matches = 0ULL;
u64 line_no = 1ULL;
u64 start = 0ULL;
u64 i;
u64 pattern_len;
if (input == (const char *)0 || pattern == (const char *)0) {
return 0ULL;
}
pattern_len = ush_strlen(pattern);
for (i = 0ULL; i <= input_len; i++) {
if (i == input_len || input[i] == '\n') {
u64 line_len = i - start;
if (ush_grep_line_has_pattern(&input[start], line_len, pattern, pattern_len) != 0) {
u64 j;
matches++;
if (with_line_number != 0) {
ush_grep_write_u64_dec(line_no);
ush_write(":");
}
for (j = 0ULL; j < line_len; j++) {
ush_write_char(input[start + j]);
}
ush_write_char('\n');
}
start = i + 1ULL;
line_no++;
}
}
return matches;
}

View File

@@ -1,29 +0,0 @@
static int ush_grep_line_has_pattern(const char *line, u64 line_len, const char *pattern, u64 pattern_len) {
u64 i;
if (line == (const char *)0 || pattern == (const char *)0) {
return 0;
}
if (pattern_len == 0ULL) {
return 1;
}
if (pattern_len > line_len) {
return 0;
}
for (i = 0ULL; i + pattern_len <= line_len; i++) {
u64 j = 0ULL;
while (j < pattern_len && line[i + j] == pattern[j]) {
j++;
}
if (j == pattern_len) {
return 1;
}
}
return 0;
}

View File

@@ -1,19 +0,0 @@
static void ush_grep_write_u64_dec(u64 value) {
char tmp[32];
u64 len = 0ULL;
if (value == 0ULL) {
ush_write_char('0');
return;
}
while (value > 0ULL && len < (u64)sizeof(tmp)) {
tmp[len++] = (char)('0' + (value % 10ULL));
value /= 10ULL;
}
while (len > 0ULL) {
len--;
ush_write_char(tmp[len]);
}
}

View File

@@ -1,36 +0,0 @@
static int ush_cmd_help(void) {
ush_writeln("commands:");
ush_writeln(" help");
ush_writeln(" ls [-l] [-R] [path]");
ush_writeln(" cat [file] (reads pipeline input when file omitted)");
ush_writeln(" grep [-n] <pattern> [file]");
ush_writeln(" pwd");
ush_writeln(" cd [dir]");
ush_writeln(" exec|run <path|name>");
ush_writeln(" clear");
ush_writeln(" ansi / ansitest / color");
ush_writeln(" fastfetch [--plain]");
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
ush_writeln(" tty [index]");
ush_writeln(" dmesg [n]");
ush_writeln(" kbdstat");
ush_writeln(" mkdir <dir> (/temp only)");
ush_writeln(" touch <file> (/temp only)");
ush_writeln(" write <file> <text> (/temp only, or from pipeline)");
ush_writeln(" append <file> <text> (/temp only, or from pipeline)");
ush_writeln(" cp <src> <dst> (dst /temp only)");
ush_writeln(" mv <src> <dst> (/temp only)");
ush_writeln(" rm <path> (/temp only)");
ush_writeln(" pid");
ush_writeln(" spawn <path|name>");
ush_writeln(" wait <pid>");
ush_writeln(" sleep <ticks>");
ush_writeln(" yield");
ush_writeln(" shutdown / restart");
ush_writeln(" exit [code]");
ush_writeln(" rusttest / panic / elfloader (kernel shell only)");
ush_writeln("pipeline/redirection: cmd1 | cmd2 | cmd3 > /temp/out.txt");
ush_writeln("redirection append: cmd >> /temp/out.txt");
ush_writeln("edit keys: Left/Right, Home/End, Up/Down history");
return 1;
}

View File

@@ -1,9 +0,0 @@
static int ush_cmd_kbdstat(void) {
ush_writeln("kbdstat:");
ush_print_kv_hex(" BUFFERED", cleonos_sys_kbd_buffered());
ush_print_kv_hex(" PUSHED", cleonos_sys_kbd_pushed());
ush_print_kv_hex(" POPPED", cleonos_sys_kbd_popped());
ush_print_kv_hex(" DROPPED", cleonos_sys_kbd_dropped());
ush_print_kv_hex(" HOTKEY_SWITCHES", cleonos_sys_kbd_hotkey_switches());
return 1;
}

View File

@@ -1,32 +0,0 @@
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) {
ush_writeln("ls: invalid path");
return 0;
}
type = cleonos_sys_fs_stat_type(path);
if (type == 1ULL) {
u64 size = cleonos_sys_fs_stat_size(path);
ush_ls_print_one(ush_ls_basename(path), type, size, long_mode);
return 1;
}
if (type != 2ULL) {
ush_writeln("ls: path not found");
return 0;
}
return ush_ls_dir(path, long_mode, recursive, recursive, 0ULL);
}

View File

@@ -1,18 +0,0 @@
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;
}

View File

@@ -1,79 +0,0 @@
static int ush_ls_dir(const char *path,
int long_mode,
int recursive,
int print_header,
u64 depth) {
u64 count;
u64 i;
if (depth > 16ULL) {
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;
}

View File

@@ -1,15 +0,0 @@
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;
}

View File

@@ -1,43 +0,0 @@
static int ush_ls_join_path(const char *dir_path, const char *name, char *out_path, u64 out_size) {
u64 p = 0ULL;
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;
}

View File

@@ -1,70 +0,0 @@
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;
}

View File

@@ -1,27 +0,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');
}

View File

@@ -1,8 +0,0 @@
static int ush_cmd_memstat(void) {
ush_writeln("memstat (user ABI limited):");
ush_print_kv_hex(" SERVICE_COUNT", cleonos_sys_service_count());
ush_print_kv_hex(" SERVICE_READY_COUNT", cleonos_sys_service_ready_count());
ush_print_kv_hex(" KELF_COUNT", cleonos_sys_kelf_count());
ush_print_kv_hex(" KELF_RUNS", cleonos_sys_kelf_runs());
return 1;
}

View File

@@ -1,25 +0,0 @@
static int ush_cmd_mkdir(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("mkdir: directory path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("mkdir: invalid path");
return 0;
}
if (ush_path_is_under_temp(path) == 0) {
ush_writeln("mkdir: target must be under /temp");
return 0;
}
if (cleonos_sys_fs_mkdir(path) == 0ULL) {
ush_writeln("mkdir: failed");
return 0;
}
return 1;
}

View File

@@ -1,38 +0,0 @@
static int ush_cmd_mv(const ush_state *sh, const char *arg) {
char src_arg[USH_PATH_MAX];
char dst_arg[USH_PATH_MAX];
char src_path[USH_PATH_MAX];
char dst_path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("mv: usage mv <src> <dst>");
return 0;
}
if (ush_split_two_args(arg, src_arg, (u64)sizeof(src_arg), dst_arg, (u64)sizeof(dst_arg)) == 0) {
ush_writeln("mv: usage mv <src> <dst>");
return 0;
}
if (ush_resolve_path(sh, src_arg, src_path, (u64)sizeof(src_path)) == 0 ||
ush_resolve_path(sh, dst_arg, dst_path, (u64)sizeof(dst_path)) == 0) {
ush_writeln("mv: invalid path");
return 0;
}
if (ush_path_is_under_temp(src_path) == 0 || ush_path_is_under_temp(dst_path) == 0) {
ush_writeln("mv: source and destination must be under /temp");
return 0;
}
if (ush_copy_file(src_path, dst_path) == 0) {
return 0;
}
if (cleonos_sys_fs_remove(src_path) == 0ULL) {
ush_writeln("mv: source remove failed");
return 0;
}
return 1;
}

View File

@@ -1,6 +0,0 @@
static int ush_cmd_not_supported(const char *name, const char *why) {
ush_write(name);
ush_write(": ");
ush_writeln(why);
return 0;
}

View File

@@ -1,4 +0,0 @@
static int ush_cmd_pid(void) {
ush_print_kv_hex("PID", cleonos_sys_getpid());
return 1;
}

View File

@@ -1,4 +0,0 @@
static int ush_cmd_pwd(const ush_state *sh) {
ush_writeln(sh->cwd);
return 1;
}

View File

@@ -1,5 +0,0 @@
static int ush_cmd_restart(void) {
ush_writeln("restart: rebooting...");
(void)cleonos_sys_restart();
return 1;
}

View File

@@ -1,25 +0,0 @@
static int ush_cmd_rm(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("rm: path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("rm: invalid path");
return 0;
}
if (ush_path_is_under_temp(path) == 0) {
ush_writeln("rm: target must be under /temp");
return 0;
}
if (cleonos_sys_fs_remove(path) == 0ULL) {
ush_writeln("rm: failed (directory must be empty)");
return 0;
}
return 1;
}

View File

@@ -1,10 +0,0 @@
static int ush_cmd_shstat(const ush_state *sh) {
ush_writeln("shstat:");
ush_print_kv_hex(" CMD_TOTAL", sh->cmd_total);
ush_print_kv_hex(" CMD_OK", sh->cmd_ok);
ush_print_kv_hex(" CMD_FAIL", sh->cmd_fail);
ush_print_kv_hex(" CMD_UNKNOWN", sh->cmd_unknown);
ush_print_kv_hex(" EXIT_REQUESTED", (sh->exit_requested != 0) ? 1ULL : 0ULL);
ush_print_kv_hex(" EXIT_CODE", sh->exit_code);
return 1;
}

View File

@@ -1,5 +0,0 @@
static int ush_cmd_shutdown(void) {
ush_writeln("shutdown: powering off...");
(void)cleonos_sys_shutdown();
return 1;
}

View File

@@ -1,18 +0,0 @@
static int ush_cmd_sleep(const char *arg) {
u64 ticks;
u64 elapsed;
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("sleep: usage sleep <ticks>");
return 0;
}
if (ush_parse_u64_dec(arg, &ticks) == 0) {
ush_writeln("sleep: invalid ticks");
return 0;
}
elapsed = cleonos_sys_sleep_ticks(ticks);
ush_print_kv_hex("SLEPT_TICKS", elapsed);
return 1;
}

View File

@@ -1,25 +0,0 @@
static int ush_cmd_spawn(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
u64 pid;
if (ush_resolve_exec_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("spawn: invalid target");
return 0;
}
if (ush_path_is_under_system(path) != 0) {
ush_writeln("spawn: /system/*.elf is kernel-mode (KELF), not user-exec");
return 0;
}
pid = cleonos_sys_spawn_path(path);
if (pid == (u64)-1) {
ush_writeln("spawn: request failed");
return 0;
}
ush_writeln("spawn: completed");
ush_print_kv_hex(" PID", pid);
return 1;
}

View File

@@ -1,9 +0,0 @@
static int ush_cmd_stats(const ush_state *sh) {
(void)ush_cmd_memstat();
(void)ush_cmd_fsstat();
(void)ush_cmd_taskstat();
(void)ush_cmd_userstat();
(void)ush_cmd_kbdstat();
(void)ush_cmd_shstat(sh);
return 1;
}

View File

@@ -1,8 +0,0 @@
static int ush_cmd_taskstat(void) {
ush_writeln("taskstat:");
ush_print_kv_hex(" TASK_COUNT", cleonos_sys_task_count());
ush_print_kv_hex(" CURRENT_TASK", cleonos_syscall(CLEONOS_SYSCALL_CUR_TASK, 0ULL, 0ULL, 0ULL));
ush_print_kv_hex(" TIMER_TICKS", cleonos_sys_timer_ticks());
ush_print_kv_hex(" CONTEXT_SWITCHES", cleonos_sys_context_switches());
return 1;
}

View File

@@ -1,26 +0,0 @@
static int ush_cmd_touch(const ush_state *sh, const char *arg) {
static const char empty_data[1] = {'\0'};
char path[USH_PATH_MAX];
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("touch: file path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("touch: invalid path");
return 0;
}
if (ush_path_is_under_temp(path) == 0) {
ush_writeln("touch: target must be under /temp");
return 0;
}
if (cleonos_sys_fs_write(path, empty_data, 0ULL) == 0ULL) {
ush_writeln("touch: failed");
return 0;
}
return 1;
}

View File

@@ -1,33 +0,0 @@
static int ush_cmd_tty(const char *arg) {
u64 tty_count = cleonos_sys_tty_count();
u64 active = cleonos_sys_tty_active();
if (arg == (const char *)0 || arg[0] == '\0') {
ush_print_kv_hex("TTY_COUNT", tty_count);
ush_print_kv_hex("TTY_ACTIVE", active);
return 1;
}
{
u64 idx;
if (ush_parse_u64_dec(arg, &idx) == 0) {
ush_writeln("tty: usage tty [index]");
return 0;
}
if (idx >= tty_count) {
ush_writeln("tty: index out of range");
return 0;
}
if (cleonos_sys_tty_switch(idx) == (u64)-1) {
ush_writeln("tty: switch failed");
return 0;
}
ush_writeln("tty: switched");
ush_print_kv_hex("TTY_ACTIVE", cleonos_sys_tty_active());
return 1;
}
}

View File

@@ -1,13 +0,0 @@
static int ush_cmd_userstat(void) {
ush_writeln("userstat:");
ush_print_kv_hex(" USER_SHELL_READY", cleonos_sys_user_shell_ready());
ush_print_kv_hex(" USER_EXEC_REQUESTED", cleonos_sys_user_exec_requested());
ush_print_kv_hex(" USER_LAUNCH_TRIES", cleonos_sys_user_launch_tries());
ush_print_kv_hex(" USER_LAUNCH_OK", cleonos_sys_user_launch_ok());
ush_print_kv_hex(" USER_LAUNCH_FAIL", cleonos_sys_user_launch_fail());
ush_print_kv_hex(" EXEC_REQUESTS", cleonos_sys_exec_request_count());
ush_print_kv_hex(" EXEC_SUCCESS", cleonos_sys_exec_success_count());
ush_print_kv_hex(" TTY_COUNT", cleonos_sys_tty_count());
ush_print_kv_hex(" TTY_ACTIVE", cleonos_sys_tty_active());
return 1;
}

View File

@@ -1,31 +0,0 @@
static int ush_cmd_wait(const char *arg) {
u64 pid;
u64 status = (u64)-1;
u64 wait_ret;
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("wait: usage wait <pid>");
return 0;
}
if (ush_parse_u64_dec(arg, &pid) == 0) {
ush_writeln("wait: invalid pid");
return 0;
}
wait_ret = cleonos_sys_wait_pid(pid, &status);
if (wait_ret == (u64)-1) {
ush_writeln("wait: pid not found");
return 0;
}
if (wait_ret == 0ULL) {
ush_writeln("wait: still running");
return 1;
}
ush_writeln("wait: exited");
ush_print_kv_hex(" STATUS", status);
return 1;
}

View File

@@ -1,44 +0,0 @@
static int ush_cmd_write(const ush_state *sh, const char *arg) {
char path_arg[USH_PATH_MAX];
char abs_path[USH_PATH_MAX];
const char *payload = (const char *)0;
u64 payload_len;
if (arg == (const char *)0 || arg[0] == '\0') {
ush_writeln("write: usage write <file> <text>");
return 0;
}
if (ush_split_first_and_rest(arg, path_arg, (u64)sizeof(path_arg), &payload) == 0) {
ush_writeln("write: usage write <file> <text>");
return 0;
}
if (ush_resolve_path(sh, path_arg, abs_path, (u64)sizeof(abs_path)) == 0) {
ush_writeln("write: invalid path");
return 0;
}
if (ush_path_is_under_temp(abs_path) == 0) {
ush_writeln("write: target must be under /temp");
return 0;
}
if (payload == (const char *)0 || payload[0] == '\0') {
if (ush_pipeline_stdin_text == (const char *)0) {
ush_writeln("write: usage write <file> <text>");
return 0;
}
payload = ush_pipeline_stdin_text;
payload_len = ush_pipeline_stdin_len;
} else {
payload_len = ush_strlen(payload);
}
if (cleonos_sys_fs_write(abs_path, payload, payload_len) == 0ULL) {
ush_writeln("write: failed");
return 0;
}
return 1;
}

View File

@@ -1,4 +0,0 @@
static int ush_cmd_yield(void) {
ush_print_kv_hex("YIELD_TICK", cleonos_sys_yield());
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,5 @@
#include "shell_internal.h" #include "shell_internal.h"
static int ush_dispatch_external_enabled = 1;
static void ush_zero(void *ptr, u64 size) { static void ush_zero(void *ptr, u64 size) {
u64 i; u64 i;
char *bytes = (char *)ptr; char *bytes = (char *)ptr;
@@ -47,44 +45,6 @@ static const char *ush_alias_command(const char *cmd) {
return cmd; 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) { 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) { if (sh == (ush_state *)0 || ret == (const ush_cmd_ret *)0) {
return 0; return 0;
@@ -102,10 +62,6 @@ static int ush_cmd_ret_apply(ush_state *sh, const ush_cmd_ret *ret) {
return 1; 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) { int ush_command_ctx_write(const char *cmd, const char *arg, const char *cwd) {
ush_cmd_ctx ctx; ush_cmd_ctx ctx;
@@ -176,10 +132,6 @@ int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *
return 0; return 0;
} }
if (ush_dispatch_external_enabled == 0) {
return 0;
}
canonical = ush_alias_command(cmd); canonical = ush_alias_command(cmd);
if (canonical == (const char *)0) { if (canonical == (const char *)0) {
@@ -232,66 +184,3 @@ int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *
return 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

@@ -99,14 +99,12 @@ 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_write(const char *cmd, const char *arg, const char *cwd);
int ush_command_ctx_read(ush_cmd_ctx *out_ctx); int ush_command_ctx_read(ush_cmd_ctx *out_ctx);
void ush_command_ret_reset(void); void ush_command_ret_reset(void);
int ush_command_ret_write(const ush_cmd_ret *ret); int ush_command_ret_write(const ush_cmd_ret *ret);
int ush_command_ret_read(ush_cmd_ret *out_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); int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *out_success);
#endif #endif

View File

@@ -1,6 +1,55 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_shstat(const ush_state *sh) {
int cleonos_app_main(void) { ush_writeln("shstat:");
return ush_command_program_main("shstat"); ush_print_kv_hex(" CMD_TOTAL", sh->cmd_total);
ush_print_kv_hex(" CMD_OK", sh->cmd_ok);
ush_print_kv_hex(" CMD_FAIL", sh->cmd_fail);
ush_print_kv_hex(" CMD_UNKNOWN", sh->cmd_unknown);
ush_print_kv_hex(" EXIT_REQUESTED", (sh->exit_requested != 0) ? 1ULL : 0ULL);
ush_print_kv_hex(" EXIT_CODE", sh->exit_code);
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "shstat") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_shstat(&sh);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,50 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_shutdown(void) {
int cleonos_app_main(void) { ush_writeln("shutdown: powering off...");
return ush_command_program_main("shutdown"); (void)cleonos_sys_shutdown();
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "shutdown") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_shutdown();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,65 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_sleep(const char *arg) {
u64 ticks;
u64 elapsed;
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("sleep"); ush_writeln("sleep: usage sleep <ticks>");
return 0;
}
if (ush_parse_u64_dec(arg, &ticks) == 0) {
ush_writeln("sleep: invalid ticks");
return 0;
}
elapsed = cleonos_sys_sleep_ticks(ticks);
ush_print_kv_hex("SLEPT_TICKS", elapsed);
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "sleep") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_sleep(arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,72 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_spawn(const ush_state *sh, const char *arg) {
char path[USH_PATH_MAX];
u64 pid;
int cleonos_app_main(void) { if (ush_resolve_exec_path(sh, arg, path, (u64)sizeof(path)) == 0) {
return ush_command_program_main("spawn"); ush_writeln("spawn: invalid target");
return 0;
}
if (ush_path_is_under_system(path) != 0) {
ush_writeln("spawn: /system/*.elf is kernel-mode (KELF), not user-exec");
return 0;
}
pid = cleonos_sys_spawn_path(path);
if (pid == (u64)-1) {
ush_writeln("spawn: request failed");
return 0;
}
ush_writeln("spawn: completed");
ush_print_kv_hex(" PID", pid);
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "spawn") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_spawn(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,118 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_memstat(void) {
int cleonos_app_main(void) { ush_writeln("memstat (user ABI limited):");
return ush_command_program_main("stats"); ush_print_kv_hex(" SERVICE_COUNT", cleonos_sys_service_count());
ush_print_kv_hex(" SERVICE_READY_COUNT", cleonos_sys_service_ready_count());
ush_print_kv_hex(" KELF_COUNT", cleonos_sys_kelf_count());
ush_print_kv_hex(" KELF_RUNS", cleonos_sys_kelf_runs());
return 1;
}
static int ush_cmd_fsstat(void) {
ush_writeln("fsstat:");
ush_print_kv_hex(" NODE_COUNT", cleonos_sys_fs_node_count());
ush_print_kv_hex(" ROOT_CHILDREN", cleonos_sys_fs_child_count("/"));
ush_print_kv_hex(" SYSTEM_CHILDREN", cleonos_sys_fs_child_count("/system"));
ush_print_kv_hex(" SHELL_CHILDREN", cleonos_sys_fs_child_count("/shell"));
ush_print_kv_hex(" TEMP_CHILDREN", cleonos_sys_fs_child_count("/temp"));
ush_print_kv_hex(" DRIVER_CHILDREN", cleonos_sys_fs_child_count("/driver"));
return 1;
}
static int ush_cmd_taskstat(void) {
ush_writeln("taskstat:");
ush_print_kv_hex(" TASK_COUNT", cleonos_sys_task_count());
ush_print_kv_hex(" CURRENT_TASK", cleonos_syscall(CLEONOS_SYSCALL_CUR_TASK, 0ULL, 0ULL, 0ULL));
ush_print_kv_hex(" TIMER_TICKS", cleonos_sys_timer_ticks());
ush_print_kv_hex(" CONTEXT_SWITCHES", cleonos_sys_context_switches());
return 1;
}
static int ush_cmd_userstat(void) {
ush_writeln("userstat:");
ush_print_kv_hex(" USER_SHELL_READY", cleonos_sys_user_shell_ready());
ush_print_kv_hex(" USER_EXEC_REQUESTED", cleonos_sys_user_exec_requested());
ush_print_kv_hex(" USER_LAUNCH_TRIES", cleonos_sys_user_launch_tries());
ush_print_kv_hex(" USER_LAUNCH_OK", cleonos_sys_user_launch_ok());
ush_print_kv_hex(" USER_LAUNCH_FAIL", cleonos_sys_user_launch_fail());
ush_print_kv_hex(" EXEC_REQUESTS", cleonos_sys_exec_request_count());
ush_print_kv_hex(" EXEC_SUCCESS", cleonos_sys_exec_success_count());
ush_print_kv_hex(" TTY_COUNT", cleonos_sys_tty_count());
ush_print_kv_hex(" TTY_ACTIVE", cleonos_sys_tty_active());
return 1;
}
static int ush_cmd_kbdstat(void) {
ush_writeln("kbdstat:");
ush_print_kv_hex(" BUFFERED", cleonos_sys_kbd_buffered());
ush_print_kv_hex(" PUSHED", cleonos_sys_kbd_pushed());
ush_print_kv_hex(" POPPED", cleonos_sys_kbd_popped());
ush_print_kv_hex(" DROPPED", cleonos_sys_kbd_dropped());
ush_print_kv_hex(" HOTKEY_SWITCHES", cleonos_sys_kbd_hotkey_switches());
return 1;
}
static int ush_cmd_shstat(const ush_state *sh) {
ush_writeln("shstat:");
ush_print_kv_hex(" CMD_TOTAL", sh->cmd_total);
ush_print_kv_hex(" CMD_OK", sh->cmd_ok);
ush_print_kv_hex(" CMD_FAIL", sh->cmd_fail);
ush_print_kv_hex(" CMD_UNKNOWN", sh->cmd_unknown);
ush_print_kv_hex(" EXIT_REQUESTED", (sh->exit_requested != 0) ? 1ULL : 0ULL);
ush_print_kv_hex(" EXIT_CODE", sh->exit_code);
return 1;
}
static int ush_cmd_stats(const ush_state *sh) {
(void)ush_cmd_memstat();
(void)ush_cmd_fsstat();
(void)ush_cmd_taskstat();
(void)ush_cmd_userstat();
(void)ush_cmd_kbdstat();
(void)ush_cmd_shstat(sh);
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "stats") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_stats(&sh);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,53 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_taskstat(void) {
int cleonos_app_main(void) { ush_writeln("taskstat:");
return ush_command_program_main("taskstat"); ush_print_kv_hex(" TASK_COUNT", cleonos_sys_task_count());
ush_print_kv_hex(" CURRENT_TASK", cleonos_syscall(CLEONOS_SYSCALL_CUR_TASK, 0ULL, 0ULL, 0ULL));
ush_print_kv_hex(" TIMER_TICKS", cleonos_sys_timer_ticks());
ush_print_kv_hex(" CONTEXT_SWITCHES", cleonos_sys_context_switches());
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "taskstat") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_taskstat();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,73 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_touch(const ush_state *sh, const char *arg) {
static const char empty_data[1] = {'\0'};
char path[USH_PATH_MAX];
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("touch"); ush_writeln("touch: file path required");
return 0;
}
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
ush_writeln("touch: invalid path");
return 0;
}
if (ush_path_is_under_temp(path) == 0) {
ush_writeln("touch: target must be under /temp");
return 0;
}
if (cleonos_sys_fs_write(path, empty_data, 0ULL) == 0ULL) {
ush_writeln("touch: failed");
return 0;
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "touch") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_touch(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,80 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_tty(const char *arg) {
u64 tty_count = cleonos_sys_tty_count();
u64 active = cleonos_sys_tty_active();
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("tty"); ush_print_kv_hex("TTY_COUNT", tty_count);
ush_print_kv_hex("TTY_ACTIVE", active);
return 1;
}
{
u64 idx;
if (ush_parse_u64_dec(arg, &idx) == 0) {
ush_writeln("tty: usage tty [index]");
return 0;
}
if (idx >= tty_count) {
ush_writeln("tty: index out of range");
return 0;
}
if (cleonos_sys_tty_switch(idx) == (u64)-1) {
ush_writeln("tty: switch failed");
return 0;
}
ush_writeln("tty: switched");
ush_print_kv_hex("TTY_ACTIVE", cleonos_sys_tty_active());
return 1;
}
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "tty") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_tty(arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,58 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_userstat(void) {
int cleonos_app_main(void) { ush_writeln("userstat:");
return ush_command_program_main("userstat"); ush_print_kv_hex(" USER_SHELL_READY", cleonos_sys_user_shell_ready());
ush_print_kv_hex(" USER_EXEC_REQUESTED", cleonos_sys_user_exec_requested());
ush_print_kv_hex(" USER_LAUNCH_TRIES", cleonos_sys_user_launch_tries());
ush_print_kv_hex(" USER_LAUNCH_OK", cleonos_sys_user_launch_ok());
ush_print_kv_hex(" USER_LAUNCH_FAIL", cleonos_sys_user_launch_fail());
ush_print_kv_hex(" EXEC_REQUESTS", cleonos_sys_exec_request_count());
ush_print_kv_hex(" EXEC_SUCCESS", cleonos_sys_exec_success_count());
ush_print_kv_hex(" TTY_COUNT", cleonos_sys_tty_count());
ush_print_kv_hex(" TTY_ACTIVE", cleonos_sys_tty_active());
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "userstat") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_userstat();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,78 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_wait(const char *arg) {
u64 pid;
u64 status = (u64)-1;
u64 wait_ret;
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("wait"); ush_writeln("wait: usage wait <pid>");
return 0;
}
if (ush_parse_u64_dec(arg, &pid) == 0) {
ush_writeln("wait: invalid pid");
return 0;
}
wait_ret = cleonos_sys_wait_pid(pid, &status);
if (wait_ret == (u64)-1) {
ush_writeln("wait: pid not found");
return 0;
}
if (wait_ret == 0ULL) {
ush_writeln("wait: still running");
return 1;
}
ush_writeln("wait: exited");
ush_print_kv_hex(" STATUS", status);
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "wait") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_wait(arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,91 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_write(const ush_state *sh, const char *arg) {
char path_arg[USH_PATH_MAX];
char abs_path[USH_PATH_MAX];
const char *payload = (const char *)0;
u64 payload_len;
int cleonos_app_main(void) { if (arg == (const char *)0 || arg[0] == '\0') {
return ush_command_program_main("write"); ush_writeln("write: usage write <file> <text>");
return 0;
}
if (ush_split_first_and_rest(arg, path_arg, (u64)sizeof(path_arg), &payload) == 0) {
ush_writeln("write: usage write <file> <text>");
return 0;
}
if (ush_resolve_path(sh, path_arg, abs_path, (u64)sizeof(abs_path)) == 0) {
ush_writeln("write: invalid path");
return 0;
}
if (ush_path_is_under_temp(abs_path) == 0) {
ush_writeln("write: target must be under /temp");
return 0;
}
if (payload == (const char *)0 || payload[0] == '\0') {
if (ush_pipeline_stdin_text == (const char *)0) {
ush_writeln("write: usage write <file> <text>");
return 0;
}
payload = ush_pipeline_stdin_text;
payload_len = ush_pipeline_stdin_len;
} else {
payload_len = ush_strlen(payload);
}
if (cleonos_sys_fs_write(abs_path, payload, payload_len) == 0ULL) {
ush_writeln("write: failed");
return 0;
}
return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
const char *arg = "";
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "write") != 0) {
has_context = 1;
arg = ctx.arg;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_write(&sh, arg);
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }

View File

@@ -1,6 +1,49 @@
#include "shell/shell_internal.h" #include "cmd_runtime.h"
static int ush_cmd_yield(void) {
int cleonos_app_main(void) { ush_print_kv_hex("YIELD_TICK", cleonos_sys_yield());
return ush_command_program_main("yield"); return 1;
}
int cleonos_app_main(void) {
ush_cmd_ctx ctx;
ush_cmd_ret ret;
ush_state sh;
char initial_cwd[USH_PATH_MAX];
int has_context = 0;
int success = 0;
ush_zero(&ctx, (u64)sizeof(ctx));
ush_zero(&ret, (u64)sizeof(ret));
ush_init_state(&sh);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
if (ush_command_ctx_read(&ctx) != 0) {
if (ctx.cmd[0] != '\0' && ush_streq(ctx.cmd, "yield") != 0) {
has_context = 1;
if (ctx.cwd[0] == '/') {
ush_copy(sh.cwd, (u64)sizeof(sh.cwd), ctx.cwd);
ush_copy(initial_cwd, (u64)sizeof(initial_cwd), sh.cwd);
}
}
}
success = ush_cmd_yield();
if (has_context != 0) {
if (ush_streq(sh.cwd, initial_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);
}
return (success != 0) ? 0 : 1;
} }