mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-24 19:34:01 +00:00
移除内建命令
This commit is contained in:
@@ -7,7 +7,7 @@ static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
u64 fd;
|
||||
|
||||
if (arg == (const char *)0 || arg[0] == '\0') {
|
||||
if (ush_pipeline_stdin_text != (const char *)0 && ush_pipeline_stdin_len > 0ULL) {
|
||||
if (ush_pipeline_stdin_text != (const char *)0) {
|
||||
(void)fputs(ush_pipeline_stdin_text, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,87 @@
|
||||
|
||||
const char *ush_pipeline_stdin_text = (const char *)0;
|
||||
u64 ush_pipeline_stdin_len = 0ULL;
|
||||
static char ush_pipeline_stdin_buf[USH_COPY_MAX + 1U];
|
||||
|
||||
static int ush_cmd_runtime_has_prefix(const char *text, const char *prefix) {
|
||||
u64 i = 0ULL;
|
||||
|
||||
if (text == (const char *)0 || prefix == (const char *)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (prefix[i] != '\0') {
|
||||
if (text[i] != prefix[i]) {
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ush_cmd_runtime_stdin_pipe_enabled(char **envp) {
|
||||
u64 i = 0ULL;
|
||||
|
||||
if (envp == (char **)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (envp[i] != (char *)0) {
|
||||
const char *entry = envp[i];
|
||||
|
||||
if (ush_cmd_runtime_has_prefix(entry, "USH_STDIN_MODE=PIPE") != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ush_cmd_runtime_capture_stdin_pipe(void) {
|
||||
u64 total = 0ULL;
|
||||
int truncated = 0;
|
||||
char drain[256];
|
||||
|
||||
for (;;) {
|
||||
u64 got;
|
||||
|
||||
if (total < (u64)USH_COPY_MAX) {
|
||||
got = cleonos_sys_fd_read(0ULL, ush_pipeline_stdin_buf + total, (u64)USH_COPY_MAX - total);
|
||||
} else {
|
||||
got = cleonos_sys_fd_read(0ULL, drain, (u64)sizeof(drain));
|
||||
truncated = 1;
|
||||
}
|
||||
|
||||
if (got == (u64)-1 || got == 0ULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (total < (u64)USH_COPY_MAX) {
|
||||
total += got;
|
||||
}
|
||||
}
|
||||
|
||||
ush_pipeline_stdin_buf[total] = '\0';
|
||||
ush_pipeline_stdin_text = ush_pipeline_stdin_buf;
|
||||
ush_pipeline_stdin_len = total;
|
||||
|
||||
if (truncated != 0) {
|
||||
ush_writeln("[pipe] input truncated");
|
||||
}
|
||||
}
|
||||
|
||||
void cleonos_cmd_runtime_pre_main(char **envp) {
|
||||
ush_pipeline_stdin_text = (const char *)0;
|
||||
ush_pipeline_stdin_len = 0ULL;
|
||||
ush_pipeline_stdin_buf[0] = '\0';
|
||||
|
||||
if (ush_cmd_runtime_stdin_pipe_enabled(envp) != 0) {
|
||||
ush_cmd_runtime_capture_stdin_pipe();
|
||||
}
|
||||
}
|
||||
|
||||
void ush_zero(void *ptr, u64 size) {
|
||||
if (ptr == (void *)0 || size == 0ULL) {
|
||||
|
||||
@@ -2438,6 +2438,23 @@ static int ush_cmd_not_supported(const char *name, const char *why) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static volatile int ush_builtin_fallback_enabled = 0;
|
||||
|
||||
static int ush_builtin_fallback_is_enabled(void) {
|
||||
return ush_builtin_fallback_enabled;
|
||||
}
|
||||
|
||||
static void ush_report_external_not_found(const char *cmd) {
|
||||
ush_write("command not found (external ELF required): ");
|
||||
|
||||
if (cmd == (const char *)0 || cmd[0] == '\0') {
|
||||
ush_writeln("(empty)");
|
||||
return;
|
||||
}
|
||||
|
||||
ush_writeln(cmd);
|
||||
}
|
||||
|
||||
static int ush_execute_single_command(ush_state *sh,
|
||||
const char *cmd,
|
||||
const char *arg,
|
||||
@@ -2462,13 +2479,31 @@ static int ush_execute_single_command(ush_state *sh,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (allow_external != 0 && ush_try_exec_external(sh, cmd, arg, &success) != 0) {
|
||||
(void)allow_external;
|
||||
|
||||
if (ush_try_exec_external(sh, cmd, arg, &success) != 0) {
|
||||
if (out_success != (int *)0) {
|
||||
*out_success = success;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ush_builtin_fallback_is_enabled() == 0) {
|
||||
known = 0;
|
||||
success = 0;
|
||||
ush_report_external_not_found(cmd);
|
||||
|
||||
if (out_known != (int *)0) {
|
||||
*out_known = known;
|
||||
}
|
||||
|
||||
if (out_success != (int *)0) {
|
||||
*out_success = success;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ush_streq(cmd, "help") != 0) {
|
||||
success = ush_cmd_help();
|
||||
} else if (ush_streq(cmd, "ls") != 0 || ush_streq(cmd, "dir") != 0) {
|
||||
@@ -2743,6 +2778,23 @@ static int ush_pipeline_open_write_fd(const char *path, u64 flags, u64 *out_fd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ush_pipeline_open_read_fd(const char *path, u64 *out_fd) {
|
||||
u64 fd;
|
||||
|
||||
if (path == (const char *)0 || out_fd == (u64 *)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = cleonos_sys_fd_open(path, CLEONOS_O_RDONLY, 0ULL);
|
||||
|
||||
if (fd == (u64)-1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_fd = fd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ush_pipeline_read_path_into_buffer(const char *path, char *buffer, u64 buffer_size, u64 *out_len) {
|
||||
u64 fd;
|
||||
u64 total = 0ULL;
|
||||
@@ -2864,6 +2916,114 @@ static int ush_execute_pipeline(ush_state *sh,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ush_builtin_fallback_is_enabled() == 0) {
|
||||
const char *pipe_input_path_external = (const char *)0;
|
||||
int pipe_output_toggle_external = 0;
|
||||
|
||||
for (i = 0ULL; i < stage_count; i++) {
|
||||
int stage_known = 1;
|
||||
int stage_success = 0;
|
||||
u64 stage_stdin_fd = CLEONOS_FD_INHERIT;
|
||||
u64 stage_stdout_fd = CLEONOS_FD_INHERIT;
|
||||
u64 opened_in_fd = (u64)-1;
|
||||
u64 opened_out_fd = (u64)-1;
|
||||
const char *stage_pipe_out = (const char *)0;
|
||||
|
||||
if (i + 1ULL < stage_count && stages[i].redirect_mode != 0) {
|
||||
ush_writeln("pipe: redirection is only supported on final stage");
|
||||
known = 1;
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pipe_input_path_external != (const char *)0) {
|
||||
if (ush_pipeline_open_read_fd(pipe_input_path_external, &opened_in_fd) == 0) {
|
||||
ush_writeln("pipe: failed to open stage input");
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
stage_stdin_fd = opened_in_fd;
|
||||
}
|
||||
|
||||
if (i + 1ULL < stage_count) {
|
||||
stage_pipe_out = (pipe_output_toggle_external == 0) ? USH_PIPE_TMP_A : USH_PIPE_TMP_B;
|
||||
|
||||
if (ush_pipeline_open_write_fd(stage_pipe_out,
|
||||
CLEONOS_O_WRONLY | CLEONOS_O_CREAT | CLEONOS_O_TRUNC,
|
||||
&opened_out_fd) == 0) {
|
||||
ush_writeln("pipe: failed to open temp stream");
|
||||
|
||||
if (opened_in_fd != (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(opened_in_fd);
|
||||
}
|
||||
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
stage_stdout_fd = opened_out_fd;
|
||||
} else if (stages[i].redirect_mode != 0) {
|
||||
if (ush_pipeline_open_redirect_fd(sh, &stages[i], &opened_out_fd) == 0) {
|
||||
if (opened_in_fd != (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(opened_in_fd);
|
||||
}
|
||||
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
stage_stdout_fd = opened_out_fd;
|
||||
}
|
||||
|
||||
stage_known = ush_try_exec_external_with_fds(sh,
|
||||
stages[i].cmd,
|
||||
stages[i].arg,
|
||||
stage_stdin_fd,
|
||||
stage_stdout_fd,
|
||||
CLEONOS_FD_INHERIT,
|
||||
&stage_success);
|
||||
|
||||
if (opened_in_fd != (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(opened_in_fd);
|
||||
}
|
||||
|
||||
if (opened_out_fd != (u64)-1) {
|
||||
(void)cleonos_sys_fd_close(opened_out_fd);
|
||||
}
|
||||
|
||||
if (stage_known == 0) {
|
||||
known = 0;
|
||||
success = 0;
|
||||
ush_report_external_not_found(stages[i].cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (stage_success == 0) {
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i + 1ULL < stage_count) {
|
||||
pipe_input_path_external = stage_pipe_out;
|
||||
pipe_output_toggle_external = (pipe_output_toggle_external == 0) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
(void)cleonos_sys_fs_remove(USH_PIPE_TMP_A);
|
||||
(void)cleonos_sys_fs_remove(USH_PIPE_TMP_B);
|
||||
|
||||
if (out_known != (int *)0) {
|
||||
*out_known = known;
|
||||
}
|
||||
|
||||
if (out_success != (int *)0) {
|
||||
*out_success = success;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0ULL; i < stage_count; i++) {
|
||||
int stage_known = 1;
|
||||
int stage_success = 0;
|
||||
|
||||
@@ -137,10 +137,16 @@ int ush_command_ret_read(ush_cmd_ret *out_ret) {
|
||||
return (got == (u64)sizeof(*out_ret)) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *out_success) {
|
||||
int ush_try_exec_external_with_fds(ush_state *sh,
|
||||
const char *cmd,
|
||||
const char *arg,
|
||||
u64 stdin_fd,
|
||||
u64 stdout_fd,
|
||||
u64 stderr_fd,
|
||||
int *out_success) {
|
||||
const char *canonical;
|
||||
char path[USH_PATH_MAX];
|
||||
char env_line[USH_PATH_MAX + USH_CMD_MAX + 32ULL];
|
||||
char env_line[USH_PATH_MAX + USH_CMD_MAX + 96ULL];
|
||||
u64 status;
|
||||
ush_cmd_ret ret;
|
||||
|
||||
@@ -179,7 +185,11 @@ int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *
|
||||
ush_append_text(env_line, (u64)sizeof(env_line), ";CMD=");
|
||||
ush_append_text(env_line, (u64)sizeof(env_line), canonical);
|
||||
|
||||
status = cleonos_sys_exec_pathv(path, arg, env_line);
|
||||
if (stdin_fd != CLEONOS_FD_INHERIT) {
|
||||
ush_append_text(env_line, (u64)sizeof(env_line), ";USH_STDIN_MODE=PIPE");
|
||||
}
|
||||
|
||||
status = cleonos_sys_exec_pathv_io(path, arg, env_line, stdin_fd, stdout_fd, stderr_fd);
|
||||
|
||||
if (status == (u64)-1) {
|
||||
ush_writeln("exec: request failed");
|
||||
@@ -218,3 +228,13 @@ int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *out_success) {
|
||||
return ush_try_exec_external_with_fds(sh,
|
||||
cmd,
|
||||
arg,
|
||||
CLEONOS_FD_INHERIT,
|
||||
CLEONOS_FD_INHERIT,
|
||||
CLEONOS_FD_INHERIT,
|
||||
out_success);
|
||||
}
|
||||
|
||||
@@ -112,6 +112,13 @@ void ush_command_ret_reset(void);
|
||||
int ush_command_ret_write(const ush_cmd_ret *ret);
|
||||
int ush_command_ret_read(ush_cmd_ret *out_ret);
|
||||
int ush_try_exec_external(ush_state *sh, const char *cmd, const char *arg, int *out_success);
|
||||
int ush_try_exec_external_with_fds(ush_state *sh,
|
||||
const char *cmd,
|
||||
const char *arg,
|
||||
u64 stdin_fd,
|
||||
u64 stdout_fd,
|
||||
u64 stderr_fd,
|
||||
int *out_success);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user