1 #include <lib9.h> 2 #include <bio.h> 3 #include <sys/types.h> 4 #include <termios.h> 5 #undef getwd 6 #undef getwd 7 #include <unistd.h> 8 #include "mach.h" 9 #define Extern extern 10 #include "acid.h" 11 #include <signal.h> 12 #include <sys/wait.h> 13 14 static void 15 setraw(int fd, int baud) 16 { 17 struct termios sg; 18 19 switch(baud){ 20 case 1200: baud = B1200; break; 21 case 2400: baud = B2400; break; 22 case 4800: baud = B4800; break; 23 case 9600: baud = B9600; break; 24 case 19200: baud = B19200; break; 25 case 38400: baud = B38400; break; 26 default: 27 werrstr("unknown speed %d", baud); 28 return; 29 } 30 if(tcgetattr(fd, &sg) >= 0) { 31 sg.c_iflag = sg.c_oflag = sg.c_lflag = 0; 32 sg.c_cflag &= ~CSIZE; 33 sg.c_cflag |= CS8 | CREAD; 34 sg.c_cflag &= ~(PARENB|PARODD); 35 sg.c_cc[VMIN] = 1; 36 sg.c_cc[VTIME] = 0; 37 if(baud) { 38 cfsetispeed(&sg, baud); 39 cfsetospeed(&sg, baud); 40 } 41 tcsetattr(fd, TCSANOW, &sg); 42 } 43 } 44 45 int 46 opentty(char *tty, int baud) 47 { 48 int fd; 49 50 if(baud == 0) 51 baud = 19200; 52 fd = open(tty, 2); 53 if(fd < 0) 54 return -1; 55 setraw(fd, baud); 56 return fd; 57 } 58 59 void 60 detach(void) 61 { 62 setpgid(0, 0); 63 } 64 65 char * 66 waitfor(int pid) 67 { 68 int n, status; 69 static char buf[32]; 70 71 for(;;) { 72 n = wait(&status); 73 if(n < 0) 74 error("wait %r"); 75 if(n == pid) { 76 sprint(buf, "%d", status); 77 return buf; 78 } 79 } 80 } 81 82 char * 83 runcmd(char *cmd) 84 { 85 char *argv[4]; 86 int pid; 87 88 argv[0] = "/bin/sh"; 89 argv[1] = "-c"; 90 argv[2] = cmd; 91 argv[3] = 0; 92 93 pid = fork(); 94 switch(pid) { 95 case -1: 96 error("fork %r"); 97 case 0: 98 execv("/bin/sh", argv); 99 exits(0); 100 default: 101 return waitfor(pid); 102 } 103 return 0; 104 } 105 106 void (*notefunc)(int); 107 108 void 109 os_notify(void (*func)(int)) 110 { 111 notefunc = func; 112 signal(SIGINT, func); 113 } 114 115 void 116 catcher(int sig) 117 { 118 if(sig==SIGINT) { 119 gotint = 1; 120 signal(SIGINT, notefunc); 121 } 122 } 123 124 void 125 setup_os_notify(void) 126 { 127 os_notify(catcher); 128 } 129 130 int 131 nproc(char **argv) 132 { 133 char buf[128]; 134 int pid, i, fd; 135 136 if(rdebug) 137 error("can't newproc in remote mode"); 138 139 pid = fork(); 140 switch(pid) { 141 case -1: 142 error("new: fork %r"); 143 case 0: 144 detach(); 145 146 sprint(buf, "/proc/%d/ctl", getpid()); 147 fd = open(buf, ORDWR); 148 if(fd < 0) 149 fatal("new: open %s: %r", buf); 150 write(fd, "hang", 4); 151 close(fd); 152 153 close(0); 154 close(1); 155 close(2); 156 for(i = 3; i < NFD; i++) 157 close(i); 158 159 open("/dev/cons", OREAD); 160 open("/dev/cons", OWRITE); 161 open("/dev/cons", OWRITE); 162 execvp(argv[0], argv); 163 fatal("new: execvp %s: %r"); 164 default: 165 install(pid); 166 msg(pid, "waitstop"); 167 notes(pid); 168 sproc(pid); 169 dostop(pid); 170 break; 171 } 172 173 return pid; 174 } 175 176 int 177 remote_read(int fd, char *buf, int bytes) 178 { 179 return read(fd, buf, bytes); 180 } 181 182 int remote_write(int fd, char *buf, int bytes) 183 { 184 return write(fd, buf, bytes); 185 } 186