sys_read() from /dev/stdin
[akaros.git] / kern / src / readline.c
1 #ifdef __SHARC__
2 #pragma nosharc
3 #endif
4
5 #include <error.h>
6 #include <stdio.h>
7 #include <assert.h>
8 #include <atomic.h>
9
10 int readline(char *buf, size_t buf_l, const char *prompt, ...)
11 {
12         static spinlock_t readline_lock = SPINLOCK_INITIALIZER;
13         int i, c, echoing, retval;
14         va_list ap;
15
16         va_start(ap, prompt);
17         if (prompt != NULL)
18                 vcprintf(prompt, ap);
19         va_end(ap);
20
21         i = 0;
22         spin_lock_irqsave(&readline_lock);
23         echoing = iscons(0);
24         while (1) {
25                 c = getchar();
26                 if (c < 0) {
27                         printk("read error: %e\n", c);  /* %e! */
28                         retval = i;
29                         break;
30                 } else if (c >= ' ' && i < buf_l - 1) {
31                         if (echoing)
32                                 cputchar(c);
33                         buf[i++] = c;
34                 } else if (c == '\b' && i > 0) {
35                         if (echoing)
36                                 cputchar(c);
37                         i--;
38                 } else if (c == '\n' || c == '\r') {
39                         if (echoing)
40                                 cputchar(c);
41                         assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
42                         buf[i++] = c;
43                         retval =  i;
44                         break;
45                 }
46         }
47         spin_unlock_irqsave(&readline_lock);
48         return retval;
49 }
50