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 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 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 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 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 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 177 tcdrain(int) 178 { 179 errno = ENOTTY; 180 return -1; 181 } 182 183 int 184 tcflush(int, int) 185 { 186 errno = ENOTTY; 187 return -1; 188 } 189 190 int 191 tcflow(int, int) 192 { 193 errno = ENOTTY; 194 return -1; 195 } 196 197 int 198 tcsendbreak(int) 199 { 200 errno = ENOTTY; 201 return -1; 202 } 203