rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 1 | #include <u.h> |
rsc | 4dcd9af | 2004-04-15 02:04:30 +0000 | [diff] [blame] | 2 | #include <signal.h> |
rsc | b4a659b | 2004-04-19 23:03:46 +0000 | [diff] [blame] | 3 | #include <libc.h> |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 4 | #include "term.h" |
| 5 | |
rsc | c6687d4 | 2004-09-21 01:11:28 +0000 | [diff] [blame] | 6 | static void |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 7 | sys(char *buf, int devnull) |
rsc | c6687d4 | 2004-09-21 01:11:28 +0000 | [diff] [blame] | 8 | { |
| 9 | char buf2[100]; |
| 10 | char *f[20]; |
| 11 | int nf, pid; |
| 12 | |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 13 | notedisable("sys: child"); |
rsc | c6687d4 | 2004-09-21 01:11:28 +0000 | [diff] [blame] | 14 | strcpy(buf2, buf); |
| 15 | nf = tokenize(buf2, f, nelem(f)); |
| 16 | f[nf] = nil; |
| 17 | switch(pid = fork()){ |
| 18 | case 0: |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 19 | close(1); |
| 20 | open("/dev/null", OREAD); |
| 21 | close(2); |
| 22 | open("/dev/null", OREAD); |
rsc | c6687d4 | 2004-09-21 01:11:28 +0000 | [diff] [blame] | 23 | execvp(f[0], f); |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 24 | _exit(2); |
rsc | c6687d4 | 2004-09-21 01:11:28 +0000 | [diff] [blame] | 25 | default: |
| 26 | waitpid(); |
| 27 | } |
| 28 | } |
| 29 | |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 30 | int |
rsc | 4dcd9af | 2004-04-15 02:04:30 +0000 | [diff] [blame] | 31 | rcstart(int argc, char **argv, int *pfd, int *tfd) |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 32 | { |
rsc | a2705f2 | 2004-04-16 15:27:29 +0000 | [diff] [blame] | 33 | int fd[2], i, pid; |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 34 | char *xargv[3]; |
| 35 | char slave[256]; |
| 36 | int sfd; |
| 37 | |
| 38 | if(argc == 0){ |
| 39 | argc = 2; |
| 40 | argv = xargv; |
| 41 | argv[0] = getenv("SHELL"); |
| 42 | if(argv[0] == 0) |
| 43 | argv[0] = "rc"; |
| 44 | argv[1] = "-i"; |
| 45 | argv[2] = 0; |
| 46 | } |
| 47 | /* |
| 48 | * fd0 is slave (tty), fd1 is master (pty) |
| 49 | */ |
| 50 | fd[0] = fd[1] = -1; |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 51 | if(getpts(fd, slave) < 0){ |
| 52 | exit(3); |
rsc | 75024f0 | 2004-03-26 00:09:27 +0000 | [diff] [blame] | 53 | sysfatal("getpts: %r\n"); |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 54 | } |
rsc | 55d360f | 2005-07-13 03:53:17 +0000 | [diff] [blame] | 55 | /* |
| 56 | * notedisable("sys: window size change"); |
| 57 | * |
| 58 | * Can't disable because will be inherited by other programs |
| 59 | * like if you run an xterm from the prompt, and then xterm's |
rsc | 1a24aac | 2005-07-21 15:43:51 +0000 | [diff] [blame] | 60 | * resizes won't get handled right. Sigh. |
| 61 | * |
| 62 | * Can't not disable because when we stty below we'll get a |
| 63 | * signal, which will drop us into the thread library note handler, |
| 64 | * which will get all confused because we just forked and thus |
| 65 | * have an unknown pid. |
| 66 | * |
| 67 | * So disable it internally. ARGH! |
rsc | 55d360f | 2005-07-13 03:53:17 +0000 | [diff] [blame] | 68 | */ |
rsc | 1a24aac | 2005-07-21 15:43:51 +0000 | [diff] [blame] | 69 | notifyoff("sys: window size change"); |
| 70 | |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 71 | pid = fork(); |
| 72 | switch(pid){ |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 73 | case 0: |
| 74 | putenv("TERM", "9term"); |
| 75 | sfd = childpty(fd, slave); |
| 76 | dup(sfd, 0); |
| 77 | dup(sfd, 1); |
| 78 | dup(sfd, 2); |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 79 | sys("stty tabs -onlcr icanon echo erase '^h' intr '^?'", 0); |
| 80 | sys("stty onocr", 1); /* not available on mac */ |
rsc | b4a659b | 2004-04-19 23:03:46 +0000 | [diff] [blame] | 81 | if(noecho) |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 82 | sys("stty -echo", 0); |
rsc | a2705f2 | 2004-04-16 15:27:29 +0000 | [diff] [blame] | 83 | for(i=3; i<100; i++) |
| 84 | close(i); |
rsc | c6687d4 | 2004-09-21 01:11:28 +0000 | [diff] [blame] | 85 | signal(SIGINT, SIG_DFL); |
| 86 | signal(SIGHUP, SIG_DFL); |
| 87 | signal(SIGTERM, SIG_DFL); |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 88 | execvp(argv[0], argv); |
| 89 | fprint(2, "exec %s failed: %r\n", argv[0]); |
rsc | 60535a5 | 2004-12-26 21:37:31 +0000 | [diff] [blame] | 90 | _exit(2); |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 91 | break; |
| 92 | case -1: |
| 93 | sysfatal("proc failed: %r"); |
| 94 | break; |
| 95 | } |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 96 | *pfd = fd[1]; |
rsc | a2705f2 | 2004-04-16 15:27:29 +0000 | [diff] [blame] | 97 | close(fd[0]); |
| 98 | if(tfd){ |
| 99 | if((*tfd = open(slave, OREAD)) < 0) |
| 100 | sysfatal("parent open %s: %r", slave); |
| 101 | } |
rsc | 8ad5179 | 2004-03-25 23:03:57 +0000 | [diff] [blame] | 102 | return pid; |
| 103 | } |
| 104 | |