1 /* $OpenBSD: keyboard.c,v 1.16 2004/07/11 05:24:56 pvalchev Exp $ */
2 /* $NetBSD: keyboard.c,v 1.2 1995/01/20 08:51:59 jtc Exp $ */
3
4 /*-
5 * Copyright (c) 1980, 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)keyboard.c 8.1 (Berkeley) 6/6/93";
36 #endif
37 static char rcsid[] = "$OpenBSD: keyboard.c,v 1.16 2004/07/11 05:24:56 pvalchev Exp $";
38 #endif /* not lint */
39
40 #include <sys/types.h>
41 #include <ctype.h>
42 #include <signal.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <termios.h>
46 #include <errno.h>
47
48 #include "systat.h"
49 #include "extern.h"
50
51 void
keyboard(void)52 keyboard(void)
53 {
54 char line[80];
55 sigset_t mask, omask;
56 int ch;
57
58 for (;;) {
59 col = 0;
60 move(CMDLINE, 0);
61 do {
62 if (gottstp) {
63 endwin();
64 kill(getpid(), SIGSTOP);
65 gotwinch = 1;
66 gottstp = 0;
67 }
68 if (gotdisplay) {
69 display();
70 gotdisplay = 0;
71 }
72 if (gotdie) {
73 die();
74 }
75 if (gotwinch) {
76 clearok(curscr, TRUE);
77 wrefresh(curscr);
78 gotwinch = 0;
79 }
80
81 refresh();
82 if ((ch = getch()) == ERR) {
83 if (errno == EINTR)
84 continue;
85 exit(1);
86 }
87 ch &= 0177;
88 if (ch == 0177 && ferror(stdin)) {
89 clearerr(stdin);
90 continue;
91 }
92 if (ch >= 'A' && ch <= 'Z')
93 ch += 'a' - 'A';
94 if (col == 0) {
95 switch (ch) {
96 case CTRL('l'):
97 case CTRL('g'):
98 sigemptyset(&mask);
99 sigaddset(&mask, SIGALRM);
100 sigprocmask(SIG_BLOCK, &mask, &omask);
101 if (ch == CTRL('l'))
102 wrefresh(curscr);
103 else
104 status();
105 sigprocmask(SIG_SETMASK, &omask, NULL);
106 continue;
107 case ':':
108 break;
109 default:
110 continue;
111 }
112 move(CMDLINE, 0);
113 clrtoeol();
114 }
115 if (ch == erasechar() && col > 0) {
116 if (col == 1 && line[0] == ':')
117 continue;
118 col--;
119 goto doerase;
120 }
121 if (ch == CTRL('w') && col > 0) {
122 while (--col >= 0 && isspace(line[col]))
123 ;
124 col++;
125 while (--col >= 0 && !isspace(line[col]))
126 if (col == 0 && line[0] == ':')
127 break;
128 col++;
129 goto doerase;
130 }
131 if (ch == killchar() && col > 0) {
132 col = 0;
133 if (line[0] == ':')
134 col++;
135 doerase:
136 move(CMDLINE, col);
137 clrtoeol();
138 continue;
139 }
140 if (col >= sizeof(line) - 1) {
141 /* line too long */
142 beep();
143 continue;
144 }
145 if (isprint(ch) || ch == ' ') {
146 line[col] = ch;
147 mvaddch(CMDLINE, col, ch);
148 col++;
149 }
150 } while (col == 0 || (ch != '\r' && ch != '\n'));
151 line[col] = '\0';
152 sigemptyset(&mask);
153 sigaddset(&mask, SIGALRM);
154 sigprocmask(SIG_BLOCK, &mask, &omask);
155 command(line + 1);
156 sigprocmask(SIG_SETMASK, &omask, NULL);
157 }
158 /*NOTREACHED*/
159 }
160