sys_read() from /dev/stdin
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 24 Aug 2010 20:37:50 +0000 (13:37 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:53 +0000 (17:35 -0700)
Via the readline, used by the monitor.  As a pleasant side effect,
readline and monitor are less ghetto.

kern/include/stdio.h
kern/src/devfs.c
kern/src/monitor.c
kern/src/readline.c

index 1968fd7..a5cc6d7 100644 (file)
@@ -48,6 +48,6 @@ int   fprintf(int fd, const char *NTS fmt, ...);
 int    vfprintf(int fd, const char *NTS fmt, va_list);
 
 // lib/readline.c
-char *NTS readline(const char *NTS prompt, ...);
+int readline(char *buf, size_t buf_l, const char *prompt, ...);
 
 #endif /* !ROS_INC_STDIO_H */
index ebd59a5..391cd01 100644 (file)
@@ -13,6 +13,7 @@
 #include <process.h>
 #include <smp.h>
 #include <umem.h>
+#include <kmalloc.h>
 
 /* These structs are declared again and initialized farther down */
 struct file_operations dev_f_op_stdin;
@@ -66,8 +67,20 @@ off_t dev_c_llseek(struct file *file, off_t offset, int whence)
 ssize_t dev_stdin_read(struct file *file, char *buf, size_t count,
                        off_t *offset)
 {
-       printk("[kernel] Tried to read %d bytes from stdin\n", count);
-       return -1;
+       int read_amt;
+       char *kbuf = kmalloc(count, 0);
+       memset(kbuf, 0, count);// TODO REMOVE ME
+       read_amt = readline(kbuf, count, 0);
+       assert(read_amt <= count);
+       /* applications (ash) expect a \n instead of a \r */
+       if (kbuf[read_amt - 1] == '\r')
+               kbuf[read_amt - 1] = '\n';
+       /* TODO UMEM */
+       if (current)
+               memcpy_to_user_errno(current, buf, kbuf, read_amt);
+       else
+               memcpy(buf, kbuf, read_amt);
+       return read_amt;
 }
 
 ssize_t dev_stdout_write(struct file *file, const char *buf, size_t count,
index c9cc3bf..e2acbd3 100644 (file)
@@ -735,11 +735,11 @@ static int runcmd(char *NTS real_buf, trapframe_t *tf) {
        return 0;
 }
 
-void monitor(trapframe_t *tf) {
-       static spinlock_t monitor_lock = SPINLOCK_INITIALIZER;
-       spin_lock_irqsave(&monitor_lock);
-
-       char *buf;
+void monitor(struct trapframe *tf)
+{
+       #define MON_CMD_LENGTH 256
+       char buf[MON_CMD_LENGTH];
+       int cnt;
 
        /* they are always disabled, since we have this irqsave lock */
        if (irq_is_enabled())
@@ -751,12 +751,10 @@ void monitor(trapframe_t *tf) {
        if (tf != NULL)
                print_trapframe(tf);
 
-       spin_unlock_irqsave(&monitor_lock);
        while (1) {
-               spin_lock_irqsave(&monitor_lock);
-               buf = readline("ROS(Core %d)> ", core_id());
-               if (buf != NULL) {
-                       spin_unlock_irqsave(&monitor_lock);
+               cnt = readline(buf, MON_CMD_LENGTH, "ROS(Core %d)> ", core_id());
+               if (cnt > 0) {
+                       buf[cnt] = 0;
                        if (runcmd(buf, tf) < 0)
                                break;
                }
index 27db85b..9798652 100644 (file)
@@ -4,15 +4,13 @@
 
 #include <error.h>
 #include <stdio.h>
+#include <assert.h>
+#include <atomic.h>
 
-#define BUFLEN 1024
-// zra: used only by monitor.c.
-static char RACY (RO NT buf)[BUFLEN];
-
-char *
-readline(const char *prompt, ...)
+int readline(char *buf, size_t buf_l, const char *prompt, ...)
 {
-       int i, c, echoing;
+       static spinlock_t readline_lock = SPINLOCK_INITIALIZER;
+       int i, c, echoing, retval;
        va_list ap;
 
        va_start(ap, prompt);
@@ -21,13 +19,15 @@ readline(const char *prompt, ...)
        va_end(ap);
 
        i = 0;
+       spin_lock_irqsave(&readline_lock);
        echoing = iscons(0);
        while (1) {
                c = getchar();
                if (c < 0) {
-                       cprintf("read error: %e\n", c);
-                       return NULL;
-               } else if (c >= ' ' && i < BUFLEN-1) {
+                       printk("read error: %e\n", c);  /* %e! */
+                       retval = i;
+                       break;
+               } else if (c >= ' ' && i < buf_l - 1) {
                        if (echoing)
                                cputchar(c);
                        buf[i++] = c;
@@ -38,9 +38,13 @@ readline(const char *prompt, ...)
                } else if (c == '\n' || c == '\r') {
                        if (echoing)
                                cputchar(c);
-                       buf[i] = 0;
-                       return buf;
+                       assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
+                       buf[i++] = c;
+                       retval =  i;
+                       break;
                }
        }
+       spin_unlock_irqsave(&readline_lock);
+       return retval;
 }