aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2011-12-17 15:16:54 +0000
committerAndriy Gapon <avg@FreeBSD.org>2011-12-17 15:16:54 +0000
commit8e62854265eea86eb0d9d01d3421d168f1777e62 (patch)
treeec0a518e9e619f1d03d7c942ce15d3f80c2e2f47 /sys
parentbf8696b4083cbdb001f70be6e690394aa5761bc9 (diff)
downloadsrc-8e62854265eea86eb0d9d01d3421d168f1777e62.tar.gz
src-8e62854265eea86eb0d9d01d3421d168f1777e62.zip
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
Notes
Notes: svn path=/head/; revision=228633
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_cons.c49
-rw-r--r--sys/sys/cons.h1
2 files changed, 50 insertions, 0 deletions
diff --git a/sys/kern/kern_cons.c b/sys/kern/kern_cons.c
index b5df465bebde..01254e376f67 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;
diff --git a/sys/sys/cons.h b/sys/sys/cons.h
index bd599c095092..79e2574895fc 100644
--- a/sys/sys/cons.h
+++ b/sys/sys/cons.h
@@ -121,6 +121,7 @@ void cngrab(void);
void cnungrab(void);
int cncheckc(void);
int cngetc(void);
+void cngets(char *, size_t, int);
void cnputc(int);
void cnputs(char *);
int cnunavailable(void);