diff options
author | dzwdz | 2022-07-14 17:23:50 +0200 |
---|---|---|
committer | dzwdz | 2022-07-14 17:23:50 +0200 |
commit | c5ad54a55123582b09f9d9d8046623916c2dec4a (patch) | |
tree | 0945ecd0d2fbd454504fa15ee5f5db76b2194785 /src/user | |
parent | 22a3e004cdf41cb3a48d9087f8bf87e56cc4cbe9 (diff) |
user/shell/cat: support reading from stdin until eof
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/app/shell.c | 27 | ||||
-rw-r--r-- | src/user/driver/termcook.c | 8 | ||||
-rw-r--r-- | src/user/lib/stdlib.c | 17 | ||||
-rw-r--r-- | src/user/lib/stdlib.h | 1 |
4 files changed, 39 insertions, 14 deletions
diff --git a/src/user/app/shell.c b/src/user/app/shell.c index 3a08af4..952b9b7 100644 --- a/src/user/app/shell.c +++ b/src/user/app/shell.c @@ -46,21 +46,24 @@ static void cmd_cat_ls(const char *args, bool ls) { static char buf[512]; int len; // first used for strlen(args), then length of buffer - if (!args) args = "/"; - len = strlen(args); - memcpy(buf, args, len + 1); // no overflow check - the shell is just a PoC - - if (ls) { // paths to directories always have a trailing slash - char *p = buf; - while (*p) p++; - if (p[-1] != '/') { - p[0] = '/'; - p[1] = '\0'; - len++; + if (args) { + len = strlen(args); + memcpy(buf, args, len + 1); // no overflow check - the shell is just a PoC + + if (ls) { // paths to directories always have a trailing slash + if (buf[len-1] != '/') { + buf[len] = '/'; + buf[len+1] = '\0'; + } } + + file = file_open(buf, 0); + } else if (ls) { /* ls default argument */ + file = file_open("/", 0); + } else { /* cat default argument */ + file = file_clone(stdin); } - file = file_open(buf, 0); if (!file) { printf("couldn't open.\n"); return; diff --git a/src/user/driver/termcook.c b/src/user/driver/termcook.c index 6ed8223..56ac77c 100644 --- a/src/user/driver/termcook.c +++ b/src/user/driver/termcook.c @@ -28,8 +28,12 @@ static void line_editor(handle_t input, handle_t output) { } break; case 4: /* EOT, C-d */ - w_output(output, linebuf, linepos); - linepos = 0; + if (linepos > 0) { + w_output(output, linebuf, linepos); + linepos = 0; + } else { + _syscall_write(output, NULL, 0, 0); // eof + } break; case '\n': case '\r': diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c index 32b4f06..56b8bb4 100644 --- a/src/user/lib/stdlib.c +++ b/src/user/lib/stdlib.c @@ -94,6 +94,23 @@ fail: return NULL; } +libc_file *file_clone(const libc_file *f) { + handle_t h = _syscall_dup(f->fd, -1, 0); + libc_file *f2; + if (h < 0) return NULL; + + // TODO file_wrapfd + f2 = malloc(sizeof *f2); + if (!f2) { + close(h); + return NULL; + } + f2->pos = f->pos; + f2->eof = f->eof; + f2->fd = h; + return f2; +} + int file_read(libc_file *f, char *buf, size_t len) { if (f->fd < 0) return -1; diff --git a/src/user/lib/stdlib.h b/src/user/lib/stdlib.h index 22227e3..1982e85 100644 --- a/src/user/lib/stdlib.h +++ b/src/user/lib/stdlib.h @@ -17,6 +17,7 @@ typedef struct { } libc_file; libc_file *file_open(const char *path, int flags); libc_file *file_reopen(libc_file*, const char *path, int flags); +libc_file *file_clone(const libc_file*); int file_read(libc_file*, char *buf, size_t len); int file_write(libc_file*, const char *buf, size_t len); void file_close(libc_file*); |