From bc50af00b6a3a69a7e5ab9159c281c919bfc3f25 Mon Sep 17 00:00:00 2001 From: "S.J.R. van Schaik" Date: Fri, 21 Jul 2017 17:41:12 +0200 Subject: [PATCH] shell: mufs: implement experimental write command --- include/console.h | 2 ++ source/drivers/usart_console.c | 73 ++++++++++++++++++++++++++++++++++++++++-- source/shell/mufs.c | 32 ++++++++++++++++++ 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/include/console.h b/include/console.h index 6c78c74..7116d69 100644 --- a/include/console.h +++ b/include/console.h @@ -6,5 +6,7 @@ struct usart_console; struct usart_console *console_init(unsigned dev_id); FILE *console_to_fp(struct usart_console *console); +int console_peek(char *c, struct usart_console *console, int block); int console_getc(char *c, struct usart_console *console); int console_getline(struct usart_console *console, char *buf, size_t n); +ssize_t console_read(struct usart_console *console, char *buf, size_t n); diff --git a/source/drivers/usart_console.c b/source/drivers/usart_console.c index 2add190..bdd04eb 100644 --- a/source/drivers/usart_console.c +++ b/source/drivers/usart_console.c @@ -72,6 +72,18 @@ static char usart_getc(struct usart_console *console, int block) return c; } +int console_peek(char *c, struct usart_console *console, int block) +{ + while (block && console->cur == console->next); + + if (console->cur != console->next) { + *c = console->recv_buf[console->cur]; + return 0; + } + + return -EAGAIN; +} + int console_getc(char *c, struct usart_console *console) { if (console->cur == console->next) @@ -120,9 +132,65 @@ int console_getline(struct usart_console *console, char *buf, size_t n) *p = '\0'; } + *p = '\0'; + return -EAGAIN; } +ssize_t console_read(struct usart_console *console, char *buf, size_t n) +{ + char *p = buf; + char c; + + fprintf(console->fp, "console_read\n"); + + *buf = '\0'; + + while (console_peek(&c, console, 1) == 0) { + switch (c) { + case '\004': + if (buf < p) + goto out; + + console_getc(&c, console); + return 0; + case 10: + case 127: + if (buf < p) { + usart_send_blocking(console->dev, '\010'); + usart_send_blocking(console->dev, ' '); + usart_send_blocking(console->dev, '\010'); + --p; + } + + console_getc(&c, console); + + break; + case '\r': + if (((size_t)p - (size_t)buf) >= n) + goto out; + + *p++ = '\n'; + usart_send_blocking(console->dev, '\r'); + console_getc(&c, console); + goto out; + default: + if (((size_t)p - (size_t)buf) >= n) + goto out; + + *p++ = c; + usart_send_blocking(console->dev, c); + console_getc(&c, console); + break; + } + } + +out: + *p = '\0'; + + return p - buf; +} + static ssize_t usart_read(void *cookie, char *buf, size_t n) { struct usart_console *console = cookie; @@ -217,7 +285,7 @@ static int usart_init(struct usart_console *console) struct usart_console *console_init(unsigned dev_id) { cookie_io_functions_t fops = { - .read = usart_read, + .read = console_read, .write = usart_write, .seek = NULL, .close = NULL, @@ -239,8 +307,7 @@ struct usart_console *console_init(unsigned dev_id) usart_init(console); console->fp = fopencookie(console, "r+w", fops); - - setbuf(console->fp, NULL); + setvbuf(console->fp, NULL, _IONBF, 0); return console; } diff --git a/source/shell/mufs.c b/source/shell/mufs.c index efa163d..fa33e04 100644 --- a/source/shell/mufs.c +++ b/source/shell/mufs.c @@ -167,6 +167,37 @@ static void do_mufs_cat(FILE *out, const char **argv, size_t argc) mufs_close(file); } +static void do_mufs_write(FILE *out, const char **argv, size_t argc) +{ + char data[256]; + struct mufs_file *file; + ssize_t ret; + + if (argc < 1) { + fprintf(out, "usage: mufs write \n"); + return; + } + + if (!mufs) { + fprintf(out, "error: no file system mounted.\n"); + return; + } + + if (!(file = mufs_open(mufs, argv[0], MUFS_WRITE))) { + fprintf(out, "error: unable to open the file\n"); + return; + } + + fprintf(out, "> "); + + while ((ret = fread(data, sizeof *data, sizeof data, out)) > 0) { + mufs_write(file, data, ret); + fprintf(out, "> "); + } + + mufs_close(file); +} + static void do_mufs_append(FILE *out, const char **argv, size_t argc) { struct mufs_file *file; @@ -270,6 +301,7 @@ static struct cmd mufs_cmds[] = { { "ls", NULL, do_mufs_ls }, { "stat", NULL, do_mufs_stat }, { "cat", NULL, do_mufs_cat }, + { "write", NULL, do_mufs_write }, { "append", NULL, do_mufs_append }, { "mv", NULL, do_mufs_mv, }, { "rm", NULL, do_mufs_rm, },