os161-1.99
 All Data Structures
kgets.c
00001 /*
00002  * Copyright (c) 2001
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 
00031 #include <types.h>
00032 #include <lib.h>
00033 
00034 /*
00035  * Do a backspace in typed input.
00036  * We overwrite the current character with a space in case we're on
00037  * a terminal where backspace is nondestructive.
00038  */
00039 static
00040 void
00041 backsp(void)
00042 {
00043         putch('\b');
00044         putch(' ');
00045         putch('\b');
00046 }
00047 
00048 /*
00049  * Read a string off the console. Support a few of the more useful
00050  * common control characters. Do not include the terminating newline
00051  * in the buffer passed back.
00052  */
00053 void
00054 kgets(char *buf, size_t maxlen)
00055 {
00056         size_t pos = 0;
00057         int ch;
00058 
00059         while (1) {
00060                 ch = getch();
00061                 if (ch=='\n' || ch=='\r') {
00062                         putch('\n');
00063                         break;
00064                 }
00065 
00066                 /* Only allow the normal 7-bit ascii */
00067                 if (ch>=32 && ch<127 && pos < maxlen-1) {
00068                         putch(ch);
00069                         buf[pos++] = ch;
00070                 }
00071                 else if ((ch=='\b' || ch==127) && pos>0) {
00072                         /* backspace */
00073                         backsp();
00074                         pos--;
00075                 }
00076                 else if (ch==3) {
00077                         /* ^C - return empty string */
00078                         putch('^');
00079                         putch('C');
00080                         putch('\n');
00081                         pos = 0;
00082                         break;
00083                 }
00084                 else if (ch==18) {
00085                         /* ^R - reprint input */
00086                         buf[pos] = 0;
00087                         kprintf("^R\n%s", buf);
00088                 }
00089                 else if (ch==21) {
00090                         /* ^U - erase line */
00091                         while (pos > 0) {
00092                                 backsp();
00093                                 pos--;
00094                         }
00095                 }
00096                 else if (ch==23) {
00097                         /* ^W - erase word */
00098                         while (pos > 0 && buf[pos-1]==' ') {
00099                                 backsp();
00100                                 pos--;
00101                         }
00102                         while (pos > 0 && buf[pos-1]!=' ') {
00103                                 backsp();
00104                                 pos--;
00105                         }
00106                 }
00107                 else {
00108                         beep();
00109                 }
00110         }
00111 
00112         buf[pos] = 0;
00113 }
 All Data Structures