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