diff options
author | avg <avg@FreeBSD.org> | 2011-12-17 15:16:54 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2011-12-17 15:16:54 +0000 |
commit | 53f09b7dafb734fd1c82af5d5e7415c7380c60db (patch) | |
tree | ec0a518e9e619f1d03d7c942ce15d3f80c2e2f47 /sys/kern/kern_cons.c | |
parent | d062f5e7d808af770ca939a38c47ac94d6846449 (diff) | |
download | FreeBSD-src-53f09b7dafb734fd1c82af5d5e7415c7380c60db.zip FreeBSD-src-53f09b7dafb734fd1c82af5d5e7415c7380c60db.tar.gz |
introduce cngets, a method for kernel to read a string from console
This is intended as a replacement for libkern's gets and mostly borrows
its implementation. It uses cngrab/cnungrab to delimit kernel's access
to console input.
Note: libkern's gets obviously doesn't share any bits of implementation
iwth libc's gets. They also have different APIs and the former doesn't
have the overflow problems of the latter.
Inspired by: bde
MFC after: 2 months
Diffstat (limited to 'sys/kern/kern_cons.c')
-rw-r--r-- | sys/kern/kern_cons.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/sys/kern/kern_cons.c b/sys/kern/kern_cons.c index b5df465..01254e3 100644 --- a/sys/kern/kern_cons.c +++ b/sys/kern/kern_cons.c @@ -408,6 +408,55 @@ cncheckc(void) } void +cngets(char *cp, size_t size, int visible) +{ + char *lp, *end; + int c; + + cngrab(); + + lp = cp; + end = cp + size - 1; + for (;;) { + c = cngetc() & 0177; + switch (c) { + case '\n': + case '\r': + cnputc(c); + *lp = '\0'; + cnungrab(); + return; + case '\b': + case '\177': + if (lp > cp) { + if (visible) { + cnputc(c); + cnputs(" \b"); + } + lp--; + } + continue; + case '\0': + continue; + default: + if (lp < end) { + switch (visible) { + case GETS_NOECHO: + break; + case GETS_ECHOPASS: + cnputc('*'); + break; + default: + cnputc(c); + break; + } + *lp++ = c; + } + } + } +} + +void cnputc(int c) { struct cn_device *cnd; |