BNX2X: spatch signed typedefs
[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_IRQSAVE;
13         int i, c, echoing, retval;
14         va_list ap;
15
16         spin_lock_irqsave(&readline_lock);
17         va_start(ap, prompt);
18         if (prompt != NULL)
19                 vcprintf(prompt, ap);
20         va_end(ap);
21
22         i = 0;
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 == '\b' || c == 0x7f) {
31                         if (i > 0) {
32                                 if (echoing)
33                                         cputchar(c);
34                                 i--;
35                         }
36                         continue;
37                 } else if (c == '\n' || c == '\r') {
38                         /* sending a \n regardless, since the serial port gives us a \r for
39                          * carriage returns. (probably won't get a \r anymore) */
40                         if (echoing)
41                                 cputchar('\n');
42                         assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
43                         buf[i++] = c;
44                         retval =  i;
45                         break;
46                 } else if (c >= ' ' && i < buf_l - 1) {
47                         if (echoing)
48                                 cputchar(c);
49                         buf[i++] = c;
50                 }
51         }
52         spin_unlock_irqsave(&readline_lock);
53         return retval;
54 }
55