xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/tcgetattr.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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>
5*219b2ee8SDavid du Colombier #include <termios.h>
63e12c5d1SDavid du Colombier #include <unistd.h>
73e12c5d1SDavid du Colombier #include <fcntl.h>
83e12c5d1SDavid du Colombier #include <errno.h>
9*219b2ee8SDavid du Colombier #include "sys9.h"
10*219b2ee8SDavid du Colombier #include "lib.h"
11*219b2ee8SDavid du Colombier #include "dir.h"
123e12c5d1SDavid du Colombier 
13*219b2ee8SDavid du Colombier #define	CESC	'\\'
14*219b2ee8SDavid du Colombier #define	CINTR	0177	/* DEL */
15*219b2ee8SDavid du Colombier #define	CQUIT	034	/* FS, cntl | */
16*219b2ee8SDavid du Colombier #define	CERASE	010	/* BS */
17*219b2ee8SDavid du Colombier #define	CKILL	025 /* cntl u */
18*219b2ee8SDavid du Colombier #define	CEOF	04	/* cntl d */
19*219b2ee8SDavid du Colombier #define	CSTART	021	/* cntl q */
20*219b2ee8SDavid du Colombier #define	CSTOP	023	/* cntl s */
21*219b2ee8SDavid du Colombier #define	CSWTCH	032	/* cntl z */
22*219b2ee8SDavid du Colombier #define CEOL	000
23*219b2ee8SDavid du Colombier #define	CNSWTCH	0
243e12c5d1SDavid du Colombier 
25*219b2ee8SDavid du Colombier static int
26*219b2ee8SDavid du Colombier isptty(int fd)
27*219b2ee8SDavid du Colombier {
28*219b2ee8SDavid du Colombier 	Dir d;
29*219b2ee8SDavid du Colombier 	char buf[256];
30*219b2ee8SDavid du Colombier 
31*219b2ee8SDavid du Colombier 	if(_FSTAT(fd, buf) < 0)
32*219b2ee8SDavid du Colombier 		return 0;
33*219b2ee8SDavid du Colombier 	convM2D(buf, &d);
34*219b2ee8SDavid du Colombier 	return (strncmp(d.name, "ptty", 4) == 0);
35*219b2ee8SDavid du Colombier }
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier int
383e12c5d1SDavid du Colombier tcgetattr(int fd, struct termios *t)
393e12c5d1SDavid du Colombier {
403e12c5d1SDavid du Colombier 	int n;
41*219b2ee8SDavid du Colombier 	char buf[60];
423e12c5d1SDavid du Colombier 
43*219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
44*219b2ee8SDavid du Colombier 		if(isatty(fd)) {
45*219b2ee8SDavid du Colombier 			/* If there is no emulation return sensible defaults */
46*219b2ee8SDavid du Colombier 			t->c_iflag = ISTRIP|ICRNL|IXON|IXOFF;
47*219b2ee8SDavid du Colombier 			t->c_oflag = OPOST|TAB3|ONLCR;
48*219b2ee8SDavid du Colombier 			t->c_cflag = B9600;
49*219b2ee8SDavid du Colombier 			t->c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
50*219b2ee8SDavid du Colombier 			t->c_cc[VINTR] = CINTR;
51*219b2ee8SDavid du Colombier 			t->c_cc[VQUIT] = CQUIT;
52*219b2ee8SDavid du Colombier 			t->c_cc[VERASE] = CERASE;
53*219b2ee8SDavid du Colombier 			t->c_cc[VKILL] = CKILL;
54*219b2ee8SDavid du Colombier 			t->c_cc[VEOF] = CEOF;
55*219b2ee8SDavid du Colombier 			t->c_cc[VEOL] = CEOL;
56*219b2ee8SDavid du Colombier 			t->c_cc[VSTART] = CSTART;
57*219b2ee8SDavid du Colombier 			t->c_cc[VSTOP] = CSTOP;
58*219b2ee8SDavid du Colombier 			return 0;
59*219b2ee8SDavid du Colombier 		} else {
603e12c5d1SDavid du Colombier 			errno = ENOTTY;
613e12c5d1SDavid du Colombier 			return -1;
623e12c5d1SDavid du Colombier 		}
633e12c5d1SDavid du Colombier 	}
64*219b2ee8SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
65*219b2ee8SDavid du Colombier 		_syserrno();
663e12c5d1SDavid du Colombier 		return -1;
673e12c5d1SDavid du Colombier 	}
68*219b2ee8SDavid du Colombier 
69*219b2ee8SDavid du Colombier 	n = _READ(fd, buf, 57);
70*219b2ee8SDavid du Colombier 	if(n < 0) {
71*219b2ee8SDavid du Colombier 		_syserrno();
72*219b2ee8SDavid du Colombier 		return -1;
73*219b2ee8SDavid du Colombier 	}
74*219b2ee8SDavid du Colombier 
75*219b2ee8SDavid du Colombier 	t->c_iflag = strtoul(buf+4, 0, 16);
76*219b2ee8SDavid du Colombier 	t->c_oflag = strtoul(buf+9, 0, 16);
77*219b2ee8SDavid du Colombier 	t->c_cflag = strtoul(buf+14, 0, 16);
78*219b2ee8SDavid du Colombier 	t->c_lflag = strtoul(buf+19, 0, 16);
79*219b2ee8SDavid du Colombier 
80*219b2ee8SDavid du Colombier 	for(n = 0; n < NCCS; n++)
81*219b2ee8SDavid du Colombier 		t->c_cc[n] = strtoul(buf+24+(n*3), 0, 16);
82*219b2ee8SDavid du Colombier 
833e12c5d1SDavid du Colombier 	return 0;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier /* BUG: ignores optional actions */
873e12c5d1SDavid du Colombier 
883e12c5d1SDavid du Colombier int
893e12c5d1SDavid du Colombier tcsetattr(int fd, int optactions, const struct termios *t)
903e12c5d1SDavid du Colombier {
91*219b2ee8SDavid du Colombier 	int n, i;
92*219b2ee8SDavid du Colombier 	char buf[100];
933e12c5d1SDavid du Colombier 
94*219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
95*219b2ee8SDavid du Colombier 		if(!isatty(fd)) {
963e12c5d1SDavid du Colombier 			errno = ENOTTY;
973e12c5d1SDavid du Colombier 			return -1;
98*219b2ee8SDavid du Colombier 		} else
993e12c5d1SDavid du Colombier 			return 0;
1003e12c5d1SDavid du Colombier 	}
101*219b2ee8SDavid du Colombier 	n = sprintf(buf, "IOW %4.4x %4.4x %4.4x %4.4x ",
102*219b2ee8SDavid du Colombier 		t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag);
103*219b2ee8SDavid du Colombier 
104*219b2ee8SDavid du Colombier 	for(i = 0; i < NCCS; i++)
105*219b2ee8SDavid du Colombier 		n += sprintf(buf+n, "%2.2x ", t->c_cc[i]);
106*219b2ee8SDavid du Colombier 
107*219b2ee8SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
108*219b2ee8SDavid du Colombier 		_syserrno();
109*219b2ee8SDavid du Colombier 		return -1;
110*219b2ee8SDavid du Colombier 	}
111*219b2ee8SDavid du Colombier 
112*219b2ee8SDavid du Colombier 	n = _WRITE(fd, buf, n);
113*219b2ee8SDavid du Colombier 	if(n < 0) {
114*219b2ee8SDavid du Colombier 		_syserrno();
115*219b2ee8SDavid du Colombier 		return -1;
116*219b2ee8SDavid du Colombier 	}
117*219b2ee8SDavid du Colombier 
118*219b2ee8SDavid du Colombier 	return 0;
119*219b2ee8SDavid du Colombier }
120*219b2ee8SDavid du Colombier 
121*219b2ee8SDavid du Colombier int
122*219b2ee8SDavid du Colombier tcsetpgrp(int fd, pid_t pgrpid)
123*219b2ee8SDavid du Colombier {
124*219b2ee8SDavid du Colombier 	int n;
125*219b2ee8SDavid du Colombier 	char buf[30];
126*219b2ee8SDavid du Colombier 
127*219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
128*219b2ee8SDavid du Colombier 		if(!isatty(fd)) {
129*219b2ee8SDavid du Colombier 			errno = ENOTTY;
130*219b2ee8SDavid du Colombier 			return -1;
131*219b2ee8SDavid du Colombier 		} else
132*219b2ee8SDavid du Colombier 			return 0;
133*219b2ee8SDavid du Colombier 	}
134*219b2ee8SDavid du Colombier 	n = sprintf(buf, "IOW note %d", pgrpid);
135*219b2ee8SDavid du Colombier 
136*219b2ee8SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
137*219b2ee8SDavid du Colombier 		_syserrno();
138*219b2ee8SDavid du Colombier 		return -1;
139*219b2ee8SDavid du Colombier 	}
140*219b2ee8SDavid du Colombier 
141*219b2ee8SDavid du Colombier 	n = _WRITE(fd, buf, n);
142*219b2ee8SDavid du Colombier 	if(n < 0) {
143*219b2ee8SDavid du Colombier 		_syserrno();
144*219b2ee8SDavid du Colombier 		return -1;
145*219b2ee8SDavid du Colombier 	}
146*219b2ee8SDavid du Colombier }
147*219b2ee8SDavid du Colombier 
148*219b2ee8SDavid du Colombier pid_t
149*219b2ee8SDavid du Colombier tcgetpgrp(int fd)
150*219b2ee8SDavid du Colombier {
151*219b2ee8SDavid du Colombier 	int n;
152*219b2ee8SDavid du Colombier 	pid_t pgrp;
153*219b2ee8SDavid du Colombier 	char buf[100];
154*219b2ee8SDavid du Colombier 
155*219b2ee8SDavid du Colombier 	if(!isptty(fd)) {
156*219b2ee8SDavid du Colombier 		errno = ENOTTY;
157*219b2ee8SDavid du Colombier 		return -1;
158*219b2ee8SDavid du Colombier 	}
159*219b2ee8SDavid du Colombier 	if(_SEEK(fd, -2, 0) != -2) {
160*219b2ee8SDavid du Colombier 		_syserrno();
161*219b2ee8SDavid du Colombier 		return -1;
162*219b2ee8SDavid du Colombier 	}
163*219b2ee8SDavid du Colombier 	n = _READ(fd, buf, sizeof(buf));
164*219b2ee8SDavid du Colombier 	if(n < 0) {
165*219b2ee8SDavid du Colombier 		_syserrno();
166*219b2ee8SDavid du Colombier 		return -1;
167*219b2ee8SDavid du Colombier 	}
168*219b2ee8SDavid du Colombier 	pgrp = atoi(buf+24+(NCCS*3));
169*219b2ee8SDavid du Colombier 	return pgrp;
170*219b2ee8SDavid du Colombier }
171