net: Allow connectionless convs to auto bind
[akaros.git] / kern / src / readline.c
index 0ca4818..32548a6 100644 (file)
@@ -1,43 +1,51 @@
-#ifdef __SHARC__
-#pragma nosharc
-#endif
-
-#include <ros/error.h>
+#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_IRQSAVE;
+       int i, c, echoing, retval;
+       va_list ap;
 
+       spin_lock_irqsave(&readline_lock);
+       va_start(ap, prompt);
        if (prompt != NULL)
-               cprintf("%s", prompt);
+               vcprintf(prompt, ap);
+       va_end(ap);
 
        i = 0;
        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: %d\n", c);
+                       retval = i;
+                       break;
+               } else if (c == '\b' || c == 0x7f) {
+                       if (i > 0) {
+                               if (echoing)
+                                       cputchar(c);
+                               i--;
+                       }
+                       continue;
+               } else if (c == '\n' || c == '\r') {
+                       /* sending a \n regardless, since the serial port gives us a \r for
+                        * carriage returns. (probably won't get a \r anymore) */
                        if (echoing)
-                               cputchar(c);
+                               cputchar('\n');
+                       assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
                        buf[i++] = c;
-               } else if (c == '\b' && i > 0) {
+                       retval =  i;
+                       break;
+               } else if (c >= ' ' && i < buf_l - 1) {
                        if (echoing)
                                cputchar(c);
-                       i--;
-               } else if (c == '\n' || c == '\r') {
-                       if (echoing)
-                               cputchar(c);
-                       buf[i] = 0;
-                       return buf;
+                       buf[i++] = c;
                }
        }
+       spin_unlock_irqsave(&readline_lock);
+       return retval;
 }