| OLD | NEW |
| 1 #include <pty.h> | 1 #include <pty.h> |
| 2 #include <utmp.h> | 2 #include <utmp.h> |
| 3 #include <unistd.h> | 3 #include <unistd.h> |
| 4 #include <errno.h> | 4 #include <errno.h> |
| 5 #include <fcntl.h> | 5 #include <fcntl.h> |
| 6 #include <sys/wait.h> | 6 #include <sys/wait.h> |
| 7 #include <pthread.h> | 7 #include <pthread.h> |
| 8 | 8 |
| 9 int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize
*ws) | 9 int forkpty(int* pm, |
| 10 { | 10 char* name, |
| 11 » int m, s, ec=0, p[2], cs; | 11 const struct termios* tio, |
| 12 » pid_t pid=-1; | 12 const struct winsize* ws) { |
| 13 » sigset_t set, oldset; | 13 int m, s, ec = 0, p[2], cs; |
| 14 pid_t pid = -1; |
| 15 sigset_t set, oldset; |
| 14 | 16 |
| 15 » if (openpty(&m, &s, name, tio, ws) < 0) return -1; | 17 if (openpty(&m, &s, name, tio, ws) < 0) |
| 18 return -1; |
| 16 | 19 |
| 17 » sigfillset(&set); | 20 sigfillset(&set); |
| 18 » pthread_sigmask(SIG_BLOCK, &set, &oldset); | 21 pthread_sigmask(SIG_BLOCK, &set, &oldset); |
| 19 » pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); | 22 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
| 20 | 23 |
| 21 » if (pipe2(p, O_CLOEXEC)) { | 24 if (pipe2(p, O_CLOEXEC)) { |
| 22 » » close(s); | 25 close(s); |
| 23 » » goto out; | 26 goto out; |
| 24 » } | 27 } |
| 25 | 28 |
| 26 » pid = fork(); | 29 pid = fork(); |
| 27 » if (!pid) { | 30 if (!pid) { |
| 28 » » close(m); | 31 close(m); |
| 29 » » close(p[0]); | 32 close(p[0]); |
| 30 » » if (login_tty(s)) { | 33 if (login_tty(s)) { |
| 31 » » » write(p[1], &errno, sizeof errno); | 34 write(p[1], &errno, sizeof errno); |
| 32 » » » _exit(127); | 35 _exit(127); |
| 33 » » } | 36 } |
| 34 » » close(p[1]); | 37 close(p[1]); |
| 35 » » pthread_setcancelstate(cs, 0); | 38 pthread_setcancelstate(cs, 0); |
| 36 » » pthread_sigmask(SIG_SETMASK, &oldset, 0); | 39 pthread_sigmask(SIG_SETMASK, &oldset, 0); |
| 37 » » return 0; | 40 return 0; |
| 38 » } | 41 } |
| 39 » close(s); | 42 close(s); |
| 40 » close(p[1]); | 43 close(p[1]); |
| 41 » if (read(p[0], &ec, sizeof ec) > 0) { | 44 if (read(p[0], &ec, sizeof ec) > 0) { |
| 42 » » int status; | 45 int status; |
| 43 » » waitpid(pid, &status, 0); | 46 waitpid(pid, &status, 0); |
| 44 » » pid = -1; | 47 pid = -1; |
| 45 » » errno = ec; | 48 errno = ec; |
| 46 » } | 49 } |
| 47 » close(p[0]); | 50 close(p[0]); |
| 48 | 51 |
| 49 out: | 52 out: |
| 50 » if (pid > 0) *pm = m; | 53 if (pid > 0) |
| 51 » else close(m); | 54 *pm = m; |
| 55 else |
| 56 close(m); |
| 52 | 57 |
| 53 » pthread_setcancelstate(cs, 0); | 58 pthread_setcancelstate(cs, 0); |
| 54 » pthread_sigmask(SIG_SETMASK, &oldset, 0); | 59 pthread_sigmask(SIG_SETMASK, &oldset, 0); |
| 55 | 60 |
| 56 » return pid; | 61 return pid; |
| 57 } | 62 } |
| OLD | NEW |