xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/tcgetattr.c (revision 6a9fc400c33447ef5e1cda7185cb4de2c8e8010e)
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <termios.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include "sys9.h"
10 #include "lib.h"
11 #include "dir.h"
12 
13 #define	CESC	'\\'
14 #define	CINTR	0177	/* DEL */
15 #define	CQUIT	034	/* FS, cntl | */
16 #define	CERASE	010	/* BS */
17 #define	CKILL	025 /* cntl u */
18 #define	CEOF	04	/* cntl d */
19 #define	CSTART	021	/* cntl q */
20 #define	CSTOP	023	/* cntl s */
21 #define	CSWTCH	032	/* cntl z */
22 #define CEOL	000
23 #define	CNSWTCH	0
24 
25 static int
26 isptty(int fd)
27 {
28 	Dir *d;
29 	int rv;
30 
31 	if((d = _dirfstat(fd)) == nil)
32 		return 0;
33 	rv = (strncmp(d->name, "ptty", 4) == 0);
34 	free(d);
35 	return rv;
36 }
37 
38 int
39 tcgetattr(int fd, struct termios *t)
40 {
41 	int n;
42 	char buf[60];
43 
44 	if(!isptty(fd)) {
45 		if(isatty(fd)) {
46 			/* If there is no emulation return sensible defaults */
47 			t->c_iflag = ISTRIP|ICRNL|IXON|IXOFF;
48 			t->c_oflag = OPOST|TAB3|ONLCR;
49 			t->c_cflag = B9600;
50 			t->c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
51 			t->c_cc[VINTR] = CINTR;
52 			t->c_cc[VQUIT] = CQUIT;
53 			t->c_cc[VERASE] = CERASE;
54 			t->c_cc[VKILL] = CKILL;
55 			t->c_cc[VEOF] = CEOF;
56 			t->c_cc[VEOL] = CEOL;
57 			t->c_cc[VSTART] = CSTART;
58 			t->c_cc[VSTOP] = CSTOP;
59 			return 0;
60 		} else {
61 			errno = ENOTTY;
62 			return -1;
63 		}
64 	}
65 	if(_SEEK(fd, -2, 0) != -2) {
66 		_syserrno();
67 		return -1;
68 	}
69 
70 	n = _READ(fd, buf, 57);
71 	if(n < 0) {
72 		_syserrno();
73 		return -1;
74 	}
75 
76 	t->c_iflag = strtoul(buf+4, 0, 16);
77 	t->c_oflag = strtoul(buf+9, 0, 16);
78 	t->c_cflag = strtoul(buf+14, 0, 16);
79 	t->c_lflag = strtoul(buf+19, 0, 16);
80 
81 	for(n = 0; n < NCCS; n++)
82 		t->c_cc[n] = strtoul(buf+24+(n*3), 0, 16);
83 
84 	return 0;
85 }
86 
87 /* BUG: ignores optional actions */
88 
89 int
90 tcsetattr(int fd, int optactions, const struct termios *t)
91 {
92 	int n, i;
93 	char buf[100];
94 
95 	if(!isptty(fd)) {
96 		if(!isatty(fd)) {
97 			errno = ENOTTY;
98 			return -1;
99 		} else
100 			return 0;
101 	}
102 	n = sprintf(buf, "IOW %4.4x %4.4x %4.4x %4.4x ",
103 		t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag);
104 
105 	for(i = 0; i < NCCS; i++)
106 		n += sprintf(buf+n, "%2.2x ", t->c_cc[i]);
107 
108 	if(_SEEK(fd, -2, 0) != -2) {
109 		_syserrno();
110 		return -1;
111 	}
112 
113 	n = _WRITE(fd, buf, n);
114 	if(n < 0) {
115 		_syserrno();
116 		return -1;
117 	}
118 
119 	return 0;
120 }
121 
122 int
123 tcsetpgrp(int fd, pid_t pgrpid)
124 {
125 	int n;
126 	char buf[30];
127 
128 	if(!isptty(fd)) {
129 		if(!isatty(fd)) {
130 			errno = ENOTTY;
131 			return -1;
132 		} else
133 			return 0;
134 	}
135 	n = sprintf(buf, "IOW note %d", pgrpid);
136 
137 	if(_SEEK(fd, -2, 0) != -2) {
138 		_syserrno();
139 		return -1;
140 	}
141 
142 	n = _WRITE(fd, buf, n);
143 	if(n < 0) {
144 		_syserrno();
145 		return -1;
146 	}
147 }
148 
149 pid_t
150 tcgetpgrp(int fd)
151 {
152 	int n;
153 	pid_t pgrp;
154 	char buf[100];
155 
156 	if(!isptty(fd)) {
157 		errno = ENOTTY;
158 		return -1;
159 	}
160 	if(_SEEK(fd, -2, 0) != -2) {
161 		_syserrno();
162 		return -1;
163 	}
164 	n = _READ(fd, buf, sizeof(buf));
165 	if(n < 0) {
166 		_syserrno();
167 		return -1;
168 	}
169 	pgrp = atoi(buf+24+(NCCS*3));
170 	return pgrp;
171 }
172 
173 /* should do a better job here */
174 
175 int
176 tcdrain(int)
177 {
178 	errno = ENOTTY;
179 	return -1;
180 }
181 
182 int
183 tcflush(int, int)
184 {
185 	errno = ENOTTY;
186 	return -1;
187 }
188 
189 int
190 tcflow(int, int)
191 {
192 	errno = ENOTTY;
193 	return -1;
194 }
195 
196 int
197 tcsendbreak(int)
198 {
199 	errno = ENOTTY;
200 	return -1;
201 }
202