svn commit: r228633 - in head/sys: kern sys

Andriy Gapon avg at FreeBSD.org
Sat Dec 17 15:16:55 UTC 2011


Author: avg
Date: Sat Dec 17 15:16:54 2011
New Revision: 228633
URL: http://svn.freebsd.org/changeset/base/228633

Log:
  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

Modified:
  head/sys/kern/kern_cons.c
  head/sys/sys/cons.h

Modified: head/sys/kern/kern_cons.c
==============================================================================
--- head/sys/kern/kern_cons.c	Sat Dec 17 15:11:22 2011	(r228632)
+++ head/sys/kern/kern_cons.c	Sat Dec 17 15:16:54 2011	(r228633)
@@ -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;

Modified: head/sys/sys/cons.h
==============================================================================
--- head/sys/sys/cons.h	Sat Dec 17 15:11:22 2011	(r228632)
+++ head/sys/sys/cons.h	Sat Dec 17 15:16:54 2011	(r228633)
@@ -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);


More information about the svn-src-head mailing list