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