mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-24 19:34:01 +00:00
libc
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
#include "cmd_runtime.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
char path[USH_PATH_MAX];
|
||||
char buf[USH_CAT_MAX + 1ULL];
|
||||
@@ -8,28 +10,28 @@ static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
|
||||
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);
|
||||
(void)fputs(ush_pipeline_stdin_text, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ush_writeln("cat: file path required");
|
||||
(void)puts("cat: file path required");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ush_resolve_path(sh, arg, path, (u64)sizeof(path)) == 0) {
|
||||
ush_writeln("cat: invalid path");
|
||||
(void)puts("cat: invalid path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
|
||||
ush_writeln("cat: file not found");
|
||||
(void)puts("cat: file not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = cleonos_sys_fs_stat_size(path);
|
||||
|
||||
if (size == (u64)-1) {
|
||||
ush_writeln("cat: failed to stat file");
|
||||
(void)puts("cat: failed to stat file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -41,7 +43,7 @@ static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
got = cleonos_sys_fs_read(path, buf, req);
|
||||
|
||||
if (got == 0ULL) {
|
||||
ush_writeln("cat: read failed");
|
||||
(void)puts("cat: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -50,10 +52,10 @@ static int ush_cmd_cat(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
buf[got] = '\0';
|
||||
ush_writeln(buf);
|
||||
(void)puts(buf);
|
||||
|
||||
if (size > got) {
|
||||
ush_writeln("[cat] output truncated");
|
||||
(void)puts("[cat] output truncated");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -4,16 +4,10 @@ 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) {
|
||||
if (ptr == (void *)0 || size == 0ULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0ULL; i < size; i++) {
|
||||
bytes[i] = 0;
|
||||
}
|
||||
(void)memset(ptr, 0, (size_t)size);
|
||||
}
|
||||
|
||||
void ush_init_state(ush_state *sh) {
|
||||
@@ -27,84 +21,47 @@ void ush_init_state(ush_state *sh) {
|
||||
}
|
||||
|
||||
u64 ush_strlen(const char *str) {
|
||||
u64 len = 0ULL;
|
||||
|
||||
if (str == (const char *)0) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
while (str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
return (str == (const char *)0) ? 0ULL : (u64)strlen(str);
|
||||
}
|
||||
|
||||
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;
|
||||
return (strcmp(left, right) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_is_space(char ch) {
|
||||
return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') ? 1 : 0;
|
||||
return (isspace((unsigned char)ch) != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_is_printable(char ch) {
|
||||
return (ch >= 32 && ch <= 126) ? 1 : 0;
|
||||
return (isprint((unsigned char)ch) != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_has_suffix(const char *name, const char *suffix) {
|
||||
u64 name_len;
|
||||
u64 suffix_len;
|
||||
u64 i;
|
||||
size_t name_len;
|
||||
size_t suffix_len;
|
||||
|
||||
if (name == (const char *)0 || suffix == (const char *)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
name_len = ush_strlen(name);
|
||||
suffix_len = ush_strlen(suffix);
|
||||
name_len = strlen(name);
|
||||
suffix_len = 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;
|
||||
return (strncmp(name + (name_len - suffix_len), suffix, suffix_len) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
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;
|
||||
return (strchr(text, (int)needle) != (char *)0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_parse_u64_dec(const char *text, u64 *out_value) {
|
||||
@@ -118,7 +75,7 @@ int ush_parse_u64_dec(const char *text, u64 *out_value) {
|
||||
while (text[i] != '\0') {
|
||||
u64 digit;
|
||||
|
||||
if (text[i] < '0' || text[i] > '9') {
|
||||
if (isdigit((unsigned char)text[i]) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,45 +94,34 @@ int ush_parse_u64_dec(const char *text, u64 *out_value) {
|
||||
}
|
||||
|
||||
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)strncpy(dst, src, (size_t)(dst_size - 1ULL));
|
||||
dst[dst_size - 1ULL] = '\0';
|
||||
}
|
||||
|
||||
void ush_trim_line(char *line) {
|
||||
u64 start = 0ULL;
|
||||
u64 i = 0ULL;
|
||||
u64 len;
|
||||
size_t start = 0U;
|
||||
size_t len;
|
||||
|
||||
if (line == (char *)0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (line[start] != '\0' && ush_is_space(line[start]) != 0) {
|
||||
while (line[start] != '\0' && isspace((unsigned char)line[start]) != 0) {
|
||||
start++;
|
||||
}
|
||||
|
||||
if (start > 0ULL) {
|
||||
while (line[start + i] != '\0') {
|
||||
line[i] = line[start + i];
|
||||
i++;
|
||||
}
|
||||
line[i] = '\0';
|
||||
if (start > 0U) {
|
||||
size_t remain = strlen(line + start) + 1U;
|
||||
(void)memmove(line, line + start, remain);
|
||||
}
|
||||
|
||||
len = ush_strlen(line);
|
||||
len = strlen(line);
|
||||
|
||||
while (len > 0ULL && ush_is_space(line[len - 1ULL]) != 0) {
|
||||
line[len - 1ULL] = '\0';
|
||||
while (len > 0U && isspace((unsigned char)line[len - 1U]) != 0) {
|
||||
line[len - 1U] = '\0';
|
||||
len--;
|
||||
}
|
||||
}
|
||||
@@ -220,37 +166,14 @@ void ush_parse_line(const char *line, char *out_cmd, u64 cmd_size, char *out_arg
|
||||
}
|
||||
|
||||
void ush_write(const char *text) {
|
||||
u64 len;
|
||||
const char *cursor;
|
||||
u64 left;
|
||||
|
||||
if (text == (const char *)0) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = ush_strlen(text);
|
||||
|
||||
if (len == 0ULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor = text;
|
||||
left = len;
|
||||
|
||||
while (left > 0ULL) {
|
||||
u64 wrote = cleonos_sys_fd_write(1ULL, cursor, left);
|
||||
|
||||
if (wrote == 0ULL || wrote == (u64)-1) {
|
||||
break;
|
||||
}
|
||||
|
||||
cursor += wrote;
|
||||
left -= wrote;
|
||||
}
|
||||
(void)fputs(text, 1);
|
||||
}
|
||||
|
||||
void ush_write_char(char ch) {
|
||||
(void)cleonos_sys_fd_write(1ULL, &ch, 1ULL);
|
||||
(void)fputc((int)(unsigned char)ch, 1);
|
||||
}
|
||||
|
||||
void ush_writeln(const char *text) {
|
||||
@@ -470,11 +393,9 @@ 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') {
|
||||
if (strncmp(path, "/system", 7U) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (path[7] == '\0' || path[7] == '/') ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -482,11 +403,9 @@ 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') {
|
||||
if (strncmp(path, "/temp", 5U) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (path[5] == '\0' || path[5] == '/') ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#define CLEONOS_CMD_RUNTIME_H
|
||||
|
||||
#include <cleonos_syscall.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef long long i64;
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "cmd_runtime.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void ush_grep_write_u64_dec(u64 value) {
|
||||
char tmp[32];
|
||||
u64 len = 0ULL;
|
||||
|
||||
if (value == 0ULL) {
|
||||
ush_write_char('0');
|
||||
(void)putchar('0');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,7 +17,7 @@ static void ush_grep_write_u64_dec(u64 value) {
|
||||
|
||||
while (len > 0ULL) {
|
||||
len--;
|
||||
ush_write_char(tmp[len]);
|
||||
(void)putchar((unsigned char)tmp[len]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +75,14 @@ static u64 ush_grep_emit_matches(const char *input, u64 input_len, const char *p
|
||||
|
||||
if (with_line_number != 0) {
|
||||
ush_grep_write_u64_dec(line_no);
|
||||
ush_write(":");
|
||||
(void)fputs(":", 1);
|
||||
}
|
||||
|
||||
for (j = 0ULL; j < line_len; j++) {
|
||||
ush_write_char(input[start + j]);
|
||||
(void)putchar((unsigned char)input[start + j]);
|
||||
}
|
||||
|
||||
ush_write_char('\n');
|
||||
(void)putchar('\n');
|
||||
}
|
||||
|
||||
start = i + 1ULL;
|
||||
@@ -108,12 +110,12 @@ static int ush_cmd_grep(const ush_state *sh, const char *arg) {
|
||||
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]");
|
||||
(void)puts("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]");
|
||||
(void)puts("grep: usage grep [-n] <pattern> [file]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -121,7 +123,7 @@ static int ush_cmd_grep(const ush_state *sh, const char *arg) {
|
||||
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]");
|
||||
(void)puts("grep: usage grep [-n] <pattern> [file]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -133,43 +135,43 @@ static int ush_cmd_grep(const ush_state *sh, const char *arg) {
|
||||
|
||||
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]");
|
||||
(void)puts("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]");
|
||||
(void)puts("grep: usage grep [-n] <pattern> [file]");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pattern == (const char *)0 || pattern[0] == '\0') {
|
||||
ush_writeln("grep: pattern required");
|
||||
(void)puts("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");
|
||||
(void)puts("grep: invalid path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
|
||||
ush_writeln("grep: file not found");
|
||||
(void)puts("grep: file not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = cleonos_sys_fs_stat_size(path);
|
||||
|
||||
if (size == (u64)-1) {
|
||||
ush_writeln("grep: failed to stat file");
|
||||
(void)puts("grep: failed to stat file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > (u64)USH_COPY_MAX) {
|
||||
ush_writeln("grep: file too large for user buffer");
|
||||
(void)puts("grep: file too large for user buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -180,7 +182,7 @@ static int ush_cmd_grep(const ush_state *sh, const char *arg) {
|
||||
got = cleonos_sys_fs_read(path, file_buf, size);
|
||||
|
||||
if (got == 0ULL || got != size) {
|
||||
ush_writeln("grep: read failed");
|
||||
(void)puts("grep: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -189,7 +191,7 @@ static int ush_cmd_grep(const ush_state *sh, const char *arg) {
|
||||
input_len = got;
|
||||
} else {
|
||||
if (ush_pipeline_stdin_text == (const char *)0) {
|
||||
ush_writeln("grep: file path required (or pipeline input)");
|
||||
(void)puts("grep: file path required (or pipeline input)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "cmd_runtime.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int ush_head_parse_args(const char *arg, u64 *out_line_count, char *out_file, u64 out_file_size) {
|
||||
char first[USH_PATH_MAX];
|
||||
@@ -69,24 +70,24 @@ static int ush_head_load_input(const ush_state *sh, const char *file_arg, const
|
||||
|
||||
if (file_arg != (const char *)0 && file_arg[0] != '\0') {
|
||||
if (ush_resolve_path(sh, file_arg, path, (u64)sizeof(path)) == 0) {
|
||||
ush_writeln("head: invalid path");
|
||||
(void)puts("head: invalid path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
|
||||
ush_writeln("head: file not found");
|
||||
(void)puts("head: file not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = cleonos_sys_fs_stat_size(path);
|
||||
|
||||
if (size == (u64)-1) {
|
||||
ush_writeln("head: failed to stat file");
|
||||
(void)puts("head: failed to stat file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > (u64)USH_COPY_MAX) {
|
||||
ush_writeln("head: file too large for user buffer");
|
||||
(void)puts("head: file too large for user buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -100,7 +101,7 @@ static int ush_head_load_input(const ush_state *sh, const char *file_arg, const
|
||||
got = cleonos_sys_fs_read(path, file_buf, size);
|
||||
|
||||
if (got == 0ULL || got != size) {
|
||||
ush_writeln("head: read failed");
|
||||
(void)puts("head: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ static int ush_head_load_input(const ush_state *sh, const char *file_arg, const
|
||||
}
|
||||
|
||||
if (ush_pipeline_stdin_text == (const char *)0) {
|
||||
ush_writeln("head: file path required (or pipeline input)");
|
||||
(void)puts("head: file path required (or pipeline input)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ static void ush_head_emit(const char *input, u64 input_len, u64 line_count) {
|
||||
break;
|
||||
}
|
||||
|
||||
ush_write_char(input[i]);
|
||||
(void)putchar((unsigned char)input[i]);
|
||||
|
||||
if (input[i] == '\n') {
|
||||
emitted++;
|
||||
@@ -152,7 +153,7 @@ static int ush_cmd_head(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
if (ush_head_parse_args(arg, &line_count, file_arg, (u64)sizeof(file_arg)) == 0) {
|
||||
ush_writeln("head: usage head [-n N] [file]");
|
||||
(void)puts("head: usage head [-n N] [file]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <cleonos_syscall.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int cleonos_app_main(void) {
|
||||
static const char msg[] = "[USER][HELLO] Hello world from /hello.elf\n";
|
||||
(void)cleonos_sys_fd_write(1ULL, msg, (u64)(sizeof(msg) - 1U));
|
||||
(void)printf("[USER][HELLO] Hello world from %s\n", "/hello.elf");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
#include "cmd_runtime.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void clio_write(const char *text) {
|
||||
(void)fputs(text, 1);
|
||||
}
|
||||
|
||||
static void clio_writeln(const char *text) {
|
||||
(void)fputs(text, 1);
|
||||
(void)putchar('\n');
|
||||
}
|
||||
|
||||
static void clio_write_char(char ch) {
|
||||
(void)putchar((unsigned char)ch);
|
||||
}
|
||||
|
||||
static void clio_write_hex_u64(u64 value) {
|
||||
(void)printf("0X%llX", (unsigned long long)value);
|
||||
}
|
||||
|
||||
static int ush_ls_join_path(const char *dir_path, const char *name, char *out_path, u64 out_size) {
|
||||
u64 p = 0ULL;
|
||||
u64 i;
|
||||
@@ -80,30 +99,30 @@ static int ush_ls_is_dot_entry(const char *name) {
|
||||
|
||||
static void ush_ls_print_one(const char *name, u64 type, u64 size, int long_mode) {
|
||||
if (long_mode == 0) {
|
||||
ush_writeln(name);
|
||||
clio_writeln(name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == 2ULL) {
|
||||
ush_write("d ");
|
||||
clio_write("d ");
|
||||
} else if (type == 1ULL) {
|
||||
ush_write("f ");
|
||||
clio_write("f ");
|
||||
} else {
|
||||
ush_write("? ");
|
||||
clio_write("? ");
|
||||
}
|
||||
|
||||
ush_write(name);
|
||||
clio_write(name);
|
||||
|
||||
if (type == 1ULL) {
|
||||
ush_write(" size=");
|
||||
ush_write_hex_u64(size);
|
||||
clio_write(" size=");
|
||||
clio_write_hex_u64(size);
|
||||
} else if (type == 2ULL) {
|
||||
ush_write(" <DIR>");
|
||||
clio_write(" <DIR>");
|
||||
} else {
|
||||
ush_write(" <UNKNOWN>");
|
||||
clio_write(" <UNKNOWN>");
|
||||
}
|
||||
|
||||
ush_write_char('\n');
|
||||
clio_write_char('\n');
|
||||
}
|
||||
|
||||
static int ush_ls_parse_args(const char *arg,
|
||||
@@ -186,19 +205,19 @@ static int ush_ls_dir(const char *path,
|
||||
u64 i;
|
||||
|
||||
if (depth > 16ULL) {
|
||||
ush_writeln("ls: recursion depth limit reached");
|
||||
clio_writeln("ls: recursion depth limit reached");
|
||||
return 0;
|
||||
}
|
||||
|
||||
count = cleonos_sys_fs_child_count(path);
|
||||
|
||||
if (print_header != 0) {
|
||||
ush_write(path);
|
||||
ush_writeln(":");
|
||||
clio_write(path);
|
||||
clio_writeln(":");
|
||||
}
|
||||
|
||||
if (count == 0ULL) {
|
||||
ush_writeln("(empty)");
|
||||
clio_writeln("(empty)");
|
||||
}
|
||||
|
||||
for (i = 0ULL; i < count; i++) {
|
||||
@@ -249,7 +268,7 @@ static int ush_ls_dir(const char *path,
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_stat_type(child_path) == 2ULL) {
|
||||
ush_write_char('\n');
|
||||
clio_write_char('\n');
|
||||
(void)ush_ls_dir(child_path, long_mode, recursive, 1, depth + 1ULL);
|
||||
}
|
||||
}
|
||||
@@ -265,12 +284,12 @@ static int ush_cmd_ls(const ush_state *sh, const char *arg) {
|
||||
int recursive;
|
||||
|
||||
if (ush_ls_parse_args(arg, &long_mode, &recursive, target, (u64)sizeof(target)) == 0) {
|
||||
ush_writeln("ls: usage ls [-l] [-R] [path]");
|
||||
clio_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");
|
||||
clio_writeln("ls: invalid path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -283,7 +302,7 @@ static int ush_cmd_ls(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
if (type != 2ULL) {
|
||||
ush_writeln("ls: path not found");
|
||||
clio_writeln("ls: path not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#define CLEONOS_USER_SHELL_INTERNAL_H
|
||||
|
||||
#include <cleonos_syscall.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef long long i64;
|
||||
|
||||
|
||||
@@ -5,106 +5,53 @@ void ush_init_state(ush_state *sh) {
|
||||
return;
|
||||
}
|
||||
|
||||
sh->line[0] = '\0';
|
||||
sh->line_len = 0ULL;
|
||||
sh->cursor = 0ULL;
|
||||
sh->rendered_len = 0ULL;
|
||||
(void)memset(sh, 0, sizeof(*sh));
|
||||
|
||||
ush_copy(sh->cwd, (u64)sizeof(sh->cwd), "/");
|
||||
|
||||
sh->history_count = 0ULL;
|
||||
sh->history_nav = -1;
|
||||
sh->nav_saved_line[0] = '\0';
|
||||
sh->nav_saved_len = 0ULL;
|
||||
sh->nav_saved_cursor = 0ULL;
|
||||
|
||||
sh->cmd_total = 0ULL;
|
||||
sh->cmd_ok = 0ULL;
|
||||
sh->cmd_fail = 0ULL;
|
||||
sh->cmd_unknown = 0ULL;
|
||||
sh->exit_requested = 0;
|
||||
sh->exit_code = 0ULL;
|
||||
}
|
||||
|
||||
u64 ush_strlen(const char *str) {
|
||||
u64 len = 0ULL;
|
||||
|
||||
if (str == (const char *)0) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
while (str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
return (str == (const char *)0) ? 0ULL : (u64)strlen(str);
|
||||
}
|
||||
|
||||
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;
|
||||
return (strcmp(left, right) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_is_space(char ch) {
|
||||
return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') ? 1 : 0;
|
||||
return (isspace((unsigned char)ch) != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_is_printable(char ch) {
|
||||
return (ch >= 32 && ch <= 126) ? 1 : 0;
|
||||
return (isprint((unsigned char)ch) != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_has_suffix(const char *name, const char *suffix) {
|
||||
u64 name_len;
|
||||
u64 suffix_len;
|
||||
u64 i;
|
||||
size_t name_len;
|
||||
size_t suffix_len;
|
||||
|
||||
if (name == (const char *)0 || suffix == (const char *)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
name_len = ush_strlen(name);
|
||||
suffix_len = ush_strlen(suffix);
|
||||
name_len = strlen(name);
|
||||
suffix_len = 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;
|
||||
return (strncmp(name + (name_len - suffix_len), suffix, suffix_len) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
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;
|
||||
return (strchr(text, (int)needle) != (char *)0) ? 1 : 0;
|
||||
}
|
||||
|
||||
int ush_parse_u64_dec(const char *text, u64 *out_value) {
|
||||
@@ -118,7 +65,7 @@ int ush_parse_u64_dec(const char *text, u64 *out_value) {
|
||||
while (text[i] != '\0') {
|
||||
u64 digit;
|
||||
|
||||
if (text[i] < '0' || text[i] > '9') {
|
||||
if (isdigit((unsigned char)text[i]) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,45 +84,34 @@ int ush_parse_u64_dec(const char *text, u64 *out_value) {
|
||||
}
|
||||
|
||||
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)strncpy(dst, src, (size_t)(dst_size - 1ULL));
|
||||
dst[dst_size - 1ULL] = '\0';
|
||||
}
|
||||
|
||||
void ush_trim_line(char *line) {
|
||||
u64 start = 0ULL;
|
||||
u64 i = 0ULL;
|
||||
u64 len;
|
||||
size_t start = 0U;
|
||||
size_t len;
|
||||
|
||||
if (line == (char *)0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (line[start] != '\0' && ush_is_space(line[start]) != 0) {
|
||||
while (line[start] != '\0' && isspace((unsigned char)line[start]) != 0) {
|
||||
start++;
|
||||
}
|
||||
|
||||
if (start > 0ULL) {
|
||||
while (line[start + i] != '\0') {
|
||||
line[i] = line[start + i];
|
||||
i++;
|
||||
}
|
||||
line[i] = '\0';
|
||||
if (start > 0U) {
|
||||
size_t remain = strlen(line + start) + 1U;
|
||||
(void)memmove(line, line + start, remain);
|
||||
}
|
||||
|
||||
len = ush_strlen(line);
|
||||
len = strlen(line);
|
||||
|
||||
while (len > 0ULL && ush_is_space(line[len - 1ULL]) != 0) {
|
||||
line[len - 1ULL] = '\0';
|
||||
while (len > 0U && isspace((unsigned char)line[len - 1U]) != 0) {
|
||||
line[len - 1U] = '\0';
|
||||
len--;
|
||||
}
|
||||
}
|
||||
@@ -231,7 +167,6 @@ static int ush_out_fd_mirror_tty = 1;
|
||||
|
||||
static void ush_output_capture_append(const char *text, u64 len) {
|
||||
u64 writable;
|
||||
u64 i;
|
||||
|
||||
if (ush_out_capture_active == 0 || text == (const char *)0 || len == 0ULL) {
|
||||
return;
|
||||
@@ -254,9 +189,7 @@ static void ush_output_capture_append(const char *text, u64 len) {
|
||||
ush_out_capture_truncated = 1;
|
||||
}
|
||||
|
||||
for (i = 0ULL; i < len; i++) {
|
||||
ush_out_capture_buffer[ush_out_capture_length + i] = text[i];
|
||||
}
|
||||
(void)memcpy(ush_out_capture_buffer + ush_out_capture_length, text, (size_t)len);
|
||||
|
||||
ush_out_capture_length += len;
|
||||
ush_out_capture_buffer[ush_out_capture_length] = '\0';
|
||||
@@ -341,19 +274,7 @@ void ush_write(const char *text) {
|
||||
}
|
||||
|
||||
if (should_write_tty != 0) {
|
||||
const char *cursor = text;
|
||||
u64 left = len;
|
||||
|
||||
while (left > 0ULL) {
|
||||
u64 wrote = cleonos_sys_fd_write(1ULL, cursor, left);
|
||||
|
||||
if (wrote == 0ULL || wrote == (u64)-1) {
|
||||
break;
|
||||
}
|
||||
|
||||
cursor += wrote;
|
||||
left -= wrote;
|
||||
}
|
||||
(void)fputs(text, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +298,7 @@ void ush_write_char(char ch) {
|
||||
}
|
||||
|
||||
if (should_write_tty != 0) {
|
||||
(void)cleonos_sys_fd_write(1ULL, &ch, 1ULL);
|
||||
(void)fputc((int)(unsigned char)ch, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <cleonos_syscall.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int cleonos_app_main(void) {
|
||||
static const char banner[] =
|
||||
"spin: busy loop started (test Alt+Ctrl+C force stop)\n";
|
||||
volatile u64 noise = 0xC1E0C1E0ULL;
|
||||
volatile unsigned long long noise = 0xC1E0C1E0ULL;
|
||||
|
||||
(void)cleonos_sys_fd_write(1ULL, banner, (u64)(sizeof(banner) - 1U));
|
||||
(void)fputs(banner, 1);
|
||||
|
||||
for (;;) {
|
||||
noise ^= (noise << 7);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "cmd_runtime.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int ush_tail_parse_args(const char *arg, u64 *out_line_count, char *out_file, u64 out_file_size) {
|
||||
char first[USH_PATH_MAX];
|
||||
@@ -69,24 +70,24 @@ static int ush_tail_load_input(const ush_state *sh, const char *file_arg, const
|
||||
|
||||
if (file_arg != (const char *)0 && file_arg[0] != '\0') {
|
||||
if (ush_resolve_path(sh, file_arg, path, (u64)sizeof(path)) == 0) {
|
||||
ush_writeln("tail: invalid path");
|
||||
(void)puts("tail: invalid path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
|
||||
ush_writeln("tail: file not found");
|
||||
(void)puts("tail: file not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = cleonos_sys_fs_stat_size(path);
|
||||
|
||||
if (size == (u64)-1) {
|
||||
ush_writeln("tail: failed to stat file");
|
||||
(void)puts("tail: failed to stat file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > (u64)USH_COPY_MAX) {
|
||||
ush_writeln("tail: file too large for user buffer");
|
||||
(void)puts("tail: file too large for user buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -100,7 +101,7 @@ static int ush_tail_load_input(const ush_state *sh, const char *file_arg, const
|
||||
got = cleonos_sys_fs_read(path, file_buf, size);
|
||||
|
||||
if (got == 0ULL || got != size) {
|
||||
ush_writeln("tail: read failed");
|
||||
(void)puts("tail: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ static int ush_tail_load_input(const ush_state *sh, const char *file_arg, const
|
||||
}
|
||||
|
||||
if (ush_pipeline_stdin_text == (const char *)0) {
|
||||
ush_writeln("tail: file path required (or pipeline input)");
|
||||
(void)puts("tail: file path required (or pipeline input)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -174,7 +175,7 @@ static int ush_cmd_tail(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
if (ush_tail_parse_args(arg, &line_count, file_arg, (u64)sizeof(file_arg)) == 0) {
|
||||
ush_writeln("tail: usage tail [-n N] [file]");
|
||||
(void)puts("tail: usage tail [-n N] [file]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -191,7 +192,7 @@ static int ush_cmd_tail(const ush_state *sh, const char *arg) {
|
||||
start_offset = ush_tail_find_start_offset(input, input_len, skip_lines);
|
||||
|
||||
for (i = start_offset; i < input_len; i++) {
|
||||
ush_write_char(input[i]);
|
||||
(void)putchar((unsigned char)input[i]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "cmd_runtime.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void ush_wc_write_u64_dec(u64 value) {
|
||||
char tmp[32];
|
||||
u64 len = 0ULL;
|
||||
|
||||
if (value == 0ULL) {
|
||||
ush_write_char('0');
|
||||
(void)putchar('0');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,7 +17,7 @@ static void ush_wc_write_u64_dec(u64 value) {
|
||||
|
||||
while (len > 0ULL) {
|
||||
len--;
|
||||
ush_write_char(tmp[len]);
|
||||
(void)putchar((unsigned char)tmp[len]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,24 +62,24 @@ static int ush_wc_load_input(const ush_state *sh, const char *file_arg, const ch
|
||||
|
||||
if (file_arg != (const char *)0 && file_arg[0] != '\0') {
|
||||
if (ush_resolve_path(sh, file_arg, path, (u64)sizeof(path)) == 0) {
|
||||
ush_writeln("wc: invalid path");
|
||||
(void)puts("wc: invalid path");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cleonos_sys_fs_stat_type(path) != 1ULL) {
|
||||
ush_writeln("wc: file not found");
|
||||
(void)puts("wc: file not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = cleonos_sys_fs_stat_size(path);
|
||||
|
||||
if (size == (u64)-1) {
|
||||
ush_writeln("wc: failed to stat file");
|
||||
(void)puts("wc: failed to stat file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > (u64)USH_COPY_MAX) {
|
||||
ush_writeln("wc: file too large for user buffer");
|
||||
(void)puts("wc: file too large for user buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ static int ush_wc_load_input(const ush_state *sh, const char *file_arg, const ch
|
||||
got = cleonos_sys_fs_read(path, file_buf, size);
|
||||
|
||||
if (got == 0ULL || got != size) {
|
||||
ush_writeln("wc: read failed");
|
||||
(void)puts("wc: read failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ static int ush_wc_load_input(const ush_state *sh, const char *file_arg, const ch
|
||||
}
|
||||
|
||||
if (ush_pipeline_stdin_text == (const char *)0) {
|
||||
ush_writeln("wc: file path required (or pipeline input)");
|
||||
(void)puts("wc: file path required (or pipeline input)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ static int ush_cmd_wc(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
if (ush_wc_parse_args(arg, file_arg, (u64)sizeof(file_arg)) == 0) {
|
||||
ush_writeln("wc: usage wc [file]");
|
||||
(void)puts("wc: usage wc [file]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -153,11 +154,11 @@ static int ush_cmd_wc(const ush_state *sh, const char *arg) {
|
||||
}
|
||||
|
||||
ush_wc_write_u64_dec(lines);
|
||||
ush_write(" ");
|
||||
(void)putchar(' ');
|
||||
ush_wc_write_u64_dec(words);
|
||||
ush_write(" ");
|
||||
(void)putchar(' ');
|
||||
ush_wc_write_u64_dec(bytes);
|
||||
ush_write_char('\n');
|
||||
(void)putchar('\n');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user