diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
| commit | 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch) | |
| tree | c6e220ba61db3a6ea4052e6841296d829654e664 /utils/acid/os-Posix.c | |
| parent | 46439007cf417cbd9ac8049bb4122c890097a0fa (diff) | |
20060303
Diffstat (limited to 'utils/acid/os-Posix.c')
| -rw-r--r-- | utils/acid/os-Posix.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/utils/acid/os-Posix.c b/utils/acid/os-Posix.c new file mode 100644 index 00000000..58b4b255 --- /dev/null +++ b/utils/acid/os-Posix.c @@ -0,0 +1,183 @@ +#include <lib9.h> +#include <bio.h> +#include <sys/types.h> +#include <termios.h> +#undef getwd +#undef getwd +#include <unistd.h> +#include "mach.h" +#define Extern extern +#include "acid.h" +#include <signal.h> + +static void +setraw(int fd, int baud) +{ + struct termios sg; + + switch(baud){ + case 1200: baud = B1200; break; + case 2400: baud = B2400; break; + case 4800: baud = B4800; break; + case 9600: baud = B9600; break; + case 19200: baud = B19200; break; + case 38400: baud = B38400; break; + default: + werrstr("unknown speed %d", baud); + return; + } + if(tcgetattr(fd, &sg) >= 0) { + sg.c_iflag = sg.c_oflag = sg.c_lflag = 0; + sg.c_cflag &= ~CSIZE; + sg.c_cflag |= CS8 | CREAD; + sg.c_cflag &= ~(PARENB|PARODD); + sg.c_cc[VMIN] = 1; + sg.c_cc[VTIME] = 0; + if(baud) { + cfsetispeed(&sg, baud); + cfsetospeed(&sg, baud); + } + tcsetattr(fd, TCSANOW, &sg); + } +} + +int +opentty(char *tty, int baud) +{ + int fd; + + if(baud == 0) + baud = 19200; + fd = open(tty, 2); + if(fd < 0) + return -1; + setraw(fd, baud); + return fd; +} + +void +detach(void) +{ + setpgid(0, 0); +} + +char * +waitfor(int pid) +{ + int n, status; + static char buf[32]; + + for(;;) { + n = wait(&status); + if(n < 0) + error("wait %r"); + if(n == pid) { + sprint(buf, "%d", status); + return buf; + } + } +} + +char * +runcmd(char *cmd) +{ + char *argv[4]; + int pid; + + argv[0] = "/bin/sh"; + argv[1] = "-c"; + argv[2] = cmd; + argv[3] = 0; + + pid = fork(); + switch(pid) { + case -1: + error("fork %r"); + case 0: + execv("/bin/sh", argv); + exits(0); + default: + return waitfor(pid); + } + return 0; +} + +void (*notefunc)(int); + +os_notify(void (*func)(int)) +{ + notefunc = func; + signal(SIGINT, func); +} + +void +catcher(int sig) +{ + if(sig==SIGINT) { + gotint = 1; + signal(SIGINT, notefunc); + } +} + +void +setup_os_notify(void) +{ + os_notify(catcher); +} + +int +nproc(char **argv) +{ + char buf[128]; + int pid, i, fd; + + if(rdebug) + error("can't newproc in remote mode"); + + pid = fork(); + switch(pid) { + case -1: + error("new: fork %r"); + case 0: + detach(); + + sprint(buf, "/proc/%d/ctl", getpid()); + fd = open(buf, ORDWR); + if(fd < 0) + fatal("new: open %s: %r", buf); + write(fd, "hang", 4); + close(fd); + + close(0); + close(1); + close(2); + for(i = 3; i < NFD; i++) + close(i); + + open("/dev/cons", OREAD); + open("/dev/cons", OWRITE); + open("/dev/cons", OWRITE); + execvp(argv[0], argv); + fatal("new: execvp %s: %r"); + default: + install(pid); + msg(pid, "waitstop"); + notes(pid); + sproc(pid); + dostop(pid); + break; + } + + return pid; +} + +int +remote_read(int fd, char *buf, int bytes) +{ + return read(fd, buf, bytes); +} + +int remote_write(int fd, char *buf, int bytes) +{ + return write(fd, buf, bytes); +} |
