Annotation of src/usr.bin/sudo/term.c, Revision 1.2
1.1 millert 1: /*
2: * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: #include <sys/types.h>
20: #include <sys/param.h>
21: #include <stdio.h>
22: #ifdef STDC_HEADERS
23: # include <stdlib.h>
24: # include <stddef.h>
25: #else
26: # ifdef HAVE_STDLIB_H
27: # include <stdlib.h>
28: # endif
29: #endif /* STDC_HEADERS */
30: #ifdef HAVE_STRING_H
31: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
32: # include <memory.h>
33: # endif
34: # include <string.h>
35: #else
36: # ifdef HAVE_STRINGS_H
37: # include <strings.h>
38: # endif
39: #endif /* HAVE_STRING_H */
40: #ifdef HAVE_TERMIOS_H
41: # include <termios.h>
42: #else
43: # ifdef HAVE_TERMIO_H
44: # include <termio.h>
45: # else
46: # include <sgtty.h>
47: # include <sys/ioctl.h>
48: # endif /* HAVE_TERMIO_H */
49: #endif /* HAVE_TERMIOS_H */
50:
51: #include "sudo.h"
52:
53: #ifndef TCSASOFT
54: # define TCSASOFT 0
55: #endif
56: #ifndef ECHONL
57: # define ECHONL 0
58: #endif
59: #ifndef IEXTEN
60: # define IEXTEN 0
61: #endif
62:
63: #ifndef _POSIX_VDISABLE
64: # ifdef VDISABLE
65: # define _POSIX_VDISABLE VDISABLE
66: # else
67: # define _POSIX_VDISABLE 0
68: # endif
69: #endif
70:
71: /*
72: * Compat macros for non-termios systems.
73: */
74: #ifndef HAVE_TERMIOS_H
75: # ifdef HAVE_TERMIO_H
76: # undef termios
77: # define termios termio
78: # define tcgetattr(f, t) ioctl(f, TCGETA, t)
79: # define tcsetattr(f, a, t) ioctl(f, a, t)
80: # undef TCSAFLUSH
81: # define TCSAFLUSH TCSETAF
82: # else /* SGTTY */
83: # undef termios
84: # define termios sgttyb
85: # define c_lflag sg_flags
86: # define tcgetattr(f, t) ioctl(f, TIOCGETP, t)
87: # define tcsetattr(f, a, t) ioctl(f, a, t)
88: # undef TCSAFLUSH
89: # define TCSAFLUSH TIOCSETP
90: # endif /* HAVE_TERMIO_H */
91: #endif /* HAVE_TERMIOS_H */
92:
93: typedef struct termios sudo_term_t;
94:
95: static sudo_term_t term, oterm;
96: static int changed;
97: int term_erase;
98: int term_kill;
99:
100: int
101: term_restore(fd)
102: int fd;
103: {
104: if (changed) {
105: if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &oterm) != 0)
106: return(0);
107: changed = 0;
108: }
109: return(1);
110: }
111:
112: int
113: term_noecho(fd)
114: int fd;
115: {
116: if (!changed && tcgetattr(fd, &oterm) != 0)
117: return(0);
118: (void) memcpy(&term, &oterm, sizeof(term));
119: CLR(term.c_lflag, ECHO|ECHONL);
120: #ifdef VSTATUS
121: term.c_cc[VSTATUS] = _POSIX_VDISABLE;
122: #endif
123: if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &term) == 0) {
124: changed = 1;
125: return(1);
126: }
127: return(0);
128: }
129:
130: #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
131: int
132: term_raw(fd)
133: int fd;
134: {
135: if (!changed && tcgetattr(fd, &oterm) != 0)
136: return(0);
137: (void) memcpy(&term, &oterm, sizeof(term));
138: /* Set terminal to half-cooked mode */
139: term.c_cc[VMIN] = 1;
140: term.c_cc[VTIME] = 0;
141: CLR(term.c_lflag, ECHO | ECHONL | ICANON | IEXTEN);
142: SET(term.c_lflag, ISIG);
143: #ifdef VSTATUS
144: term.c_cc[VSTATUS] = _POSIX_VDISABLE;
145: #endif
146: if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &term) == 0) {
147: term_erase = term.c_cc[VERASE];
148: term_kill = term.c_cc[VKILL];
149: changed = 1;
150: return(1);
151: }
152: return(0);
153: }
154:
155: #else /* SGTTY */
156:
157: int
158: term_raw(fd)
159: int fd;
160: {
161: if (!changed && ioctl(fd, TIOCGETP, &oterm) != 0)
162: return(0);
163: (void) memcpy(&term, &oterm, sizeof(term));
164: /* Set terminal to half-cooked mode */
165: CLR(term.c_lflag, ECHO);
166: SET(term.sg_flags, CBREAK);
167: if (ioctl(fd, TIOCSETP, &term) == 0) {
168: term_erase = term.sg_erase;
169: term_kill = term.sg_kill;
170: changed = 1;
171: return(1);
172: }
173: return(0);
174: }
175:
176: #endif