xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/tcgetattr.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
13e12c5d1SDavid du Colombier #include <stdlib.h>
23e12c5d1SDavid du Colombier #include <string.h>
33e12c5d1SDavid du Colombier #include <stdio.h>
43e12c5d1SDavid du Colombier #include <sys/types.h>
5219b2ee8SDavid du Colombier #include <termios.h>
63e12c5d1SDavid du Colombier #include <unistd.h>
73e12c5d1SDavid du Colombier #include <fcntl.h>
83e12c5d1SDavid du Colombier #include <errno.h>
9219b2ee8SDavid du Colombier #include "sys9.h"
10219b2ee8SDavid du Colombier #include "lib.h"
11219b2ee8SDavid du Colombier #include "dir.h"
123e12c5d1SDavid du Colombier 
13219b2ee8SDavid du Colombier #define	CESC	'\\'
14219b2ee8SDavid du Colombier #define	CINTR	0177	/* DEL */
15219b2ee8SDavid du Colombier #define	CQUIT	034	/* FS, cntl | */
16219b2ee8SDavid du Colombier #define	CERASE	010	/* BS */
17219b2ee8SDavid du Colombier #define	CKILL	025 /* cntl u */
18219b2ee8SDavid du Colombier #define	CEOF	04	/* cntl d */
19219b2ee8SDavid du Colombier #define	CSTART	021	/* cntl q */
20219b2ee8SDavid du Colombier #define	CSTOP	023	/* cntl s */
21219b2ee8SDavid du Colombier #define	CSWTCH	032	/* cntl z */
22219b2ee8SDavid du Colombier #define CEOL	000
23219b2ee8SDavid du Colombier #define	CNSWTCH	0
243e12c5d1SDavid du Colombier 
25219b2ee8SDavid du Colombier static int
isptty(int fd)26219b2ee8SDavid du Colombier isptty(int fd)
27219b2ee8SDavid du Colombier {
289a747e4fSDavid du Colombier 	Dir *d;
299a747e4fSDavid du Colombier 	int rv;
30219b2ee8SDavid du Colombier 
319a747e4fSDavid du Colombier 	if((d = _dirfstat(fd)) == nil)
32219b2ee8SDavid du Colombier 		return 0;
339a747e4fSDavid du Colombier 	rv = (strncmp(d->name, "ptty", 4) == 0);
349a747e4fSDavid du Colombier 	free(d);
359a747e4fSDavid du Colombier 	return rv;
36219b2ee8SDavid du Colombier }
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier int
tcgetattr(int fd,struct termios * t)393e12c5d1SDavid du Colombier tcgetattr(int fd, struct termios *t)
403e12c5d1SDavid du Colombier {
413e12c5d1SDavid du Colombier 	int n;
42219b2ee8SDavid du Colombier 	char buf[60];
433e12c5d1SDavid du Colombier 
44219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
45219b2ee8SDavid du Colombier 		if(isatty(fd)) {
46219b2ee8SDavid du Colombier 			/* If there is no emulation return sensible defaults */
47219b2ee8SDavid du Colombier 			t->c_iflag = ISTRIP|ICRNL|IXON|IXOFF;
48219b2ee8SDavid du Colombier 			t->c_oflag = OPOST|TAB3|ONLCR;
49219b2ee8SDavid du Colombier 			t->c_cflag = B9600;
50219b2ee8SDavid du Colombier 			t->c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
51219b2ee8SDavid du Colombier 			t->c_cc[VINTR] = CINTR;
52219b2ee8SDavid du Colombier 			t->c_cc[VQUIT] = CQUIT;
53219b2ee8SDavid du Colombier 			t->c_cc[VERASE] = CERASE;
54219b2ee8SDavid du Colombier 			t->c_cc[VKILL] = CKILL;
55219b2ee8SDavid du Colombier 			t->c_cc[VEOF] = CEOF;
56219b2ee8SDavid du Colombier 			t->c_cc[VEOL] = CEOL;
57219b2ee8SDavid du Colombier 			t->c_cc[VSTART] = CSTART;
58219b2ee8SDavid du Colombier 			t->c_cc[VSTOP] = CSTOP;
59219b2ee8SDavid du Colombier 			return 0;
60219b2ee8SDavid du Colombier 		} else {
613e12c5d1SDavid du Colombier 			errno = ENOTTY;
623e12c5d1SDavid du Colombier 			return -1;
633e12c5d1SDavid du Colombier 		}
643e12c5d1SDavid du Colombier 	}
65d9306527SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
66219b2ee8SDavid du Colombier 		_syserrno();
673e12c5d1SDavid du Colombier 		return -1;
683e12c5d1SDavid du Colombier 	}
69219b2ee8SDavid du Colombier 
70219b2ee8SDavid du Colombier 	n = _READ(fd, buf, 57);
71219b2ee8SDavid du Colombier 	if(n < 0) {
72219b2ee8SDavid du Colombier 		_syserrno();
73219b2ee8SDavid du Colombier 		return -1;
74219b2ee8SDavid du Colombier 	}
75219b2ee8SDavid du Colombier 
76219b2ee8SDavid du Colombier 	t->c_iflag = strtoul(buf+4, 0, 16);
77219b2ee8SDavid du Colombier 	t->c_oflag = strtoul(buf+9, 0, 16);
78219b2ee8SDavid du Colombier 	t->c_cflag = strtoul(buf+14, 0, 16);
79219b2ee8SDavid du Colombier 	t->c_lflag = strtoul(buf+19, 0, 16);
80219b2ee8SDavid du Colombier 
81219b2ee8SDavid du Colombier 	for(n = 0; n < NCCS; n++)
82219b2ee8SDavid du Colombier 		t->c_cc[n] = strtoul(buf+24+(n*3), 0, 16);
83219b2ee8SDavid du Colombier 
843e12c5d1SDavid du Colombier 	return 0;
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier /* BUG: ignores optional actions */
883e12c5d1SDavid du Colombier 
893e12c5d1SDavid du Colombier int
tcsetattr(int fd,int,const struct termios * t)90*781103c4SDavid du Colombier tcsetattr(int fd, int, const struct termios *t)
913e12c5d1SDavid du Colombier {
92219b2ee8SDavid du Colombier 	int n, i;
93219b2ee8SDavid du Colombier 	char buf[100];
943e12c5d1SDavid du Colombier 
95219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
96219b2ee8SDavid du Colombier 		if(!isatty(fd)) {
973e12c5d1SDavid du Colombier 			errno = ENOTTY;
983e12c5d1SDavid du Colombier 			return -1;
99219b2ee8SDavid du Colombier 		} else
1003e12c5d1SDavid du Colombier 			return 0;
1013e12c5d1SDavid du Colombier 	}
102219b2ee8SDavid du Colombier 	n = sprintf(buf, "IOW %4.4x %4.4x %4.4x %4.4x ",
103219b2ee8SDavid du Colombier 		t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag);
104219b2ee8SDavid du Colombier 
105219b2ee8SDavid du Colombier 	for(i = 0; i < NCCS; i++)
106219b2ee8SDavid du Colombier 		n += sprintf(buf+n, "%2.2x ", t->c_cc[i]);
107219b2ee8SDavid du Colombier 
108d9306527SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
109219b2ee8SDavid du Colombier 		_syserrno();
110219b2ee8SDavid du Colombier 		return -1;
111219b2ee8SDavid du Colombier 	}
112219b2ee8SDavid du Colombier 
113219b2ee8SDavid du Colombier 	n = _WRITE(fd, buf, n);
114219b2ee8SDavid du Colombier 	if(n < 0) {
115219b2ee8SDavid du Colombier 		_syserrno();
116219b2ee8SDavid du Colombier 		return -1;
117219b2ee8SDavid du Colombier 	}
118219b2ee8SDavid du Colombier 
119219b2ee8SDavid du Colombier 	return 0;
120219b2ee8SDavid du Colombier }
121219b2ee8SDavid du Colombier 
122219b2ee8SDavid du Colombier int
tcsetpgrp(int fd,pid_t pgrpid)123219b2ee8SDavid du Colombier tcsetpgrp(int fd, pid_t pgrpid)
124219b2ee8SDavid du Colombier {
125219b2ee8SDavid du Colombier 	int n;
126219b2ee8SDavid du Colombier 	char buf[30];
127219b2ee8SDavid du Colombier 
128219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
129219b2ee8SDavid du Colombier 		if(!isatty(fd)) {
130219b2ee8SDavid du Colombier 			errno = ENOTTY;
131219b2ee8SDavid du Colombier 			return -1;
132219b2ee8SDavid du Colombier 		} else
133219b2ee8SDavid du Colombier 			return 0;
134219b2ee8SDavid du Colombier 	}
135219b2ee8SDavid du Colombier 	n = sprintf(buf, "IOW note %d", pgrpid);
136219b2ee8SDavid du Colombier 
137d9306527SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
138219b2ee8SDavid du Colombier 		_syserrno();
139219b2ee8SDavid du Colombier 		return -1;
140219b2ee8SDavid du Colombier 	}
141219b2ee8SDavid du Colombier 
142219b2ee8SDavid du Colombier 	n = _WRITE(fd, buf, n);
143219b2ee8SDavid du Colombier 	if(n < 0) {
144219b2ee8SDavid du Colombier 		_syserrno();
145219b2ee8SDavid du Colombier 		return -1;
146219b2ee8SDavid du Colombier 	}
147027288c8SDavid du Colombier 	return 0;
148219b2ee8SDavid du Colombier }
149219b2ee8SDavid du Colombier 
150219b2ee8SDavid du Colombier pid_t
tcgetpgrp(int fd)151219b2ee8SDavid du Colombier tcgetpgrp(int fd)
152219b2ee8SDavid du Colombier {
153219b2ee8SDavid du Colombier 	int n;
154219b2ee8SDavid du Colombier 	pid_t pgrp;
155219b2ee8SDavid du Colombier 	char buf[100];
156219b2ee8SDavid du Colombier 
157219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
158219b2ee8SDavid du Colombier 		errno = ENOTTY;
159219b2ee8SDavid du Colombier 		return -1;
160219b2ee8SDavid du Colombier 	}
161d9306527SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
162219b2ee8SDavid du Colombier 		_syserrno();
163219b2ee8SDavid du Colombier 		return -1;
164219b2ee8SDavid du Colombier 	}
165219b2ee8SDavid du Colombier 	n = _READ(fd, buf, sizeof(buf));
166219b2ee8SDavid du Colombier 	if(n < 0) {
167219b2ee8SDavid du Colombier 		_syserrno();
168219b2ee8SDavid du Colombier 		return -1;
169219b2ee8SDavid du Colombier 	}
170219b2ee8SDavid du Colombier 	pgrp = atoi(buf+24+(NCCS*3));
171219b2ee8SDavid du Colombier 	return pgrp;
172219b2ee8SDavid du Colombier }
173d9306527SDavid du Colombier 
174d9306527SDavid du Colombier /* should do a better job here */
175d9306527SDavid du Colombier 
176d9306527SDavid du Colombier int
tcdrain(int)177d9306527SDavid du Colombier tcdrain(int)
178d9306527SDavid du Colombier {
179d9306527SDavid du Colombier 	errno = ENOTTY;
180d9306527SDavid du Colombier 	return -1;
181d9306527SDavid du Colombier }
182d9306527SDavid du Colombier 
183d9306527SDavid du Colombier int
tcflush(int,int)184d9306527SDavid du Colombier tcflush(int, int)
185d9306527SDavid du Colombier {
186d9306527SDavid du Colombier 	errno = ENOTTY;
187d9306527SDavid du Colombier 	return -1;
188d9306527SDavid du Colombier }
189d9306527SDavid du Colombier 
190d9306527SDavid du Colombier int
tcflow(int,int)191d9306527SDavid du Colombier tcflow(int, int)
192d9306527SDavid du Colombier {
193d9306527SDavid du Colombier 	errno = ENOTTY;
194d9306527SDavid du Colombier 	return -1;
195d9306527SDavid du Colombier }
196d9306527SDavid du Colombier 
197d9306527SDavid du Colombier int
tcsendbreak(int)198d9306527SDavid du Colombier tcsendbreak(int)
199d9306527SDavid du Colombier {
200d9306527SDavid du Colombier 	errno = ENOTTY;
201d9306527SDavid du Colombier 	return -1;
202d9306527SDavid du Colombier }
203