xref: /plan9/sys/src/ape/lib/ap/plan9/tcgetattr.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
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
isptty(int fd)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
tcgetattr(int fd,struct termios * t)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
tcsetattr(int fd,int,const struct termios * t)90 tcsetattr(int fd, int, 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
tcsetpgrp(int fd,pid_t pgrpid)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 	return 0;
148 }
149 
150 pid_t
tcgetpgrp(int fd)151 tcgetpgrp(int fd)
152 {
153 	int n;
154 	pid_t pgrp;
155 	char buf[100];
156 
157 	if(!isptty(fd)) {
158 		errno = ENOTTY;
159 		return -1;
160 	}
161 	if(_SEEK(fd, -2, 0) != -2) {
162 		_syserrno();
163 		return -1;
164 	}
165 	n = _READ(fd, buf, sizeof(buf));
166 	if(n < 0) {
167 		_syserrno();
168 		return -1;
169 	}
170 	pgrp = atoi(buf+24+(NCCS*3));
171 	return pgrp;
172 }
173 
174 /* should do a better job here */
175 
176 int
tcdrain(int)177 tcdrain(int)
178 {
179 	errno = ENOTTY;
180 	return -1;
181 }
182 
183 int
tcflush(int,int)184 tcflush(int, int)
185 {
186 	errno = ENOTTY;
187 	return -1;
188 }
189 
190 int
tcflow(int,int)191 tcflow(int, int)
192 {
193 	errno = ENOTTY;
194 	return -1;
195 }
196 
197 int
tcsendbreak(int)198 tcsendbreak(int)
199 {
200 	errno = ENOTTY;
201 	return -1;
202 }
203