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 }