xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/tcgetattr.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 	char buf[256];
30 
31 	if(_FSTAT(fd, buf) < 0)
32 		return 0;
33 	convM2D(buf, &d);
34 	return (strncmp(d.name, "ptty", 4) == 0);
35 }
36 
37 int
38 tcgetattr(int fd, struct termios *t)
39 {
40 	int n;
41 	char buf[60];
42 
43 	if(!isptty(fd)) {
44 		if(isatty(fd)) {
45 			/* If there is no emulation return sensible defaults */
46 			t->c_iflag = ISTRIP|ICRNL|IXON|IXOFF;
47 			t->c_oflag = OPOST|TAB3|ONLCR;
48 			t->c_cflag = B9600;
49 			t->c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
50 			t->c_cc[VINTR] = CINTR;
51 			t->c_cc[VQUIT] = CQUIT;
52 			t->c_cc[VERASE] = CERASE;
53 			t->c_cc[VKILL] = CKILL;
54 			t->c_cc[VEOF] = CEOF;
55 			t->c_cc[VEOL] = CEOL;
56 			t->c_cc[VSTART] = CSTART;
57 			t->c_cc[VSTOP] = CSTOP;
58 			return 0;
59 		} else {
60 			errno = ENOTTY;
61 			return -1;
62 		}
63 	}
64 	if(_SEEK(fd, -2, 0) != -2) {
65 		_syserrno();
66 		return -1;
67 	}
68 
69 	n = _READ(fd, buf, 57);
70 	if(n < 0) {
71 		_syserrno();
72 		return -1;
73 	}
74 
75 	t->c_iflag = strtoul(buf+4, 0, 16);
76 	t->c_oflag = strtoul(buf+9, 0, 16);
77 	t->c_cflag = strtoul(buf+14, 0, 16);
78 	t->c_lflag = strtoul(buf+19, 0, 16);
79 
80 	for(n = 0; n < NCCS; n++)
81 		t->c_cc[n] = strtoul(buf+24+(n*3), 0, 16);
82 
83 	return 0;
84 }
85 
86 /* BUG: ignores optional actions */
87 
88 int
89 tcsetattr(int fd, int optactions, const struct termios *t)
90 {
91 	int n, i;
92 	char buf[100];
93 
94 	if(!isptty(fd)) {
95 		if(!isatty(fd)) {
96 			errno = ENOTTY;
97 			return -1;
98 		} else
99 			return 0;
100 	}
101 	n = sprintf(buf, "IOW %4.4x %4.4x %4.4x %4.4x ",
102 		t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag);
103 
104 	for(i = 0; i < NCCS; i++)
105 		n += sprintf(buf+n, "%2.2x ", t->c_cc[i]);
106 
107 	if(_SEEK(fd, -2, 0) != -2) {
108 		_syserrno();
109 		return -1;
110 	}
111 
112 	n = _WRITE(fd, buf, n);
113 	if(n < 0) {
114 		_syserrno();
115 		return -1;
116 	}
117 
118 	return 0;
119 }
120 
121 int
122 tcsetpgrp(int fd, pid_t pgrpid)
123 {
124 	int n;
125 	char buf[30];
126 
127 	if(!isptty(fd)) {
128 		if(!isatty(fd)) {
129 			errno = ENOTTY;
130 			return -1;
131 		} else
132 			return 0;
133 	}
134 	n = sprintf(buf, "IOW note %d", pgrpid);
135 
136 	if(_SEEK(fd, -2, 0) != -2) {
137 		_syserrno();
138 		return -1;
139 	}
140 
141 	n = _WRITE(fd, buf, n);
142 	if(n < 0) {
143 		_syserrno();
144 		return -1;
145 	}
146 }
147 
148 pid_t
149 tcgetpgrp(int fd)
150 {
151 	int n;
152 	pid_t pgrp;
153 	char buf[100];
154 
155 	if(!isptty(fd)) {
156 		errno = ENOTTY;
157 		return -1;
158 	}
159 	if(_SEEK(fd, -2, 0) != -2) {
160 		_syserrno();
161 		return -1;
162 	}
163 	n = _READ(fd, buf, sizeof(buf));
164 	if(n < 0) {
165 		_syserrno();
166 		return -1;
167 	}
168 	pgrp = atoi(buf+24+(NCCS*3));
169 	return pgrp;
170 }
171