blob: 2df6369e67d90e6ceb9f82742448c8c1e1785dfd [file] [log] [blame] [edit]
#ifdef __SHARC__
#pragma nosharc
#endif
#include <error.h>
#include <stdio.h>
#include <assert.h>
#include <atomic.h>
int readline(char *buf, size_t buf_l, const char *prompt, ...)
{
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)
vcprintf(prompt, ap);
va_end(ap);
i = 0;
echoing = iscons(0);
while (1) {
c = getchar();
if (c < 0) {
printk("read error: %e\n", c); /* %e! */
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('\n');
assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
buf[i++] = c;
retval = i;
break;
} else if (c >= ' ' && i < buf_l - 1) {
if (echoing)
cputchar(c);
buf[i++] = c;
}
}
spin_unlock_irqsave(&readline_lock);
return retval;
}