source:
EcnlProtoTool/trunk/musl-1.1.18/src/misc/forkpty.c
Last change on this file was 444, checked in by , 4 years ago | |
---|---|
|
|
File size: 1.0 KB |
Line | |
---|---|
1 | #include <pty.h> |
2 | #include <utmp.h> |
3 | #include <unistd.h> |
4 | #include <errno.h> |
5 | #include <fcntl.h> |
6 | #include <sys/wait.h> |
7 | #include <pthread.h> |
8 | |
9 | int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws) |
10 | { |
11 | int m, s, ec=0, p[2], cs; |
12 | pid_t pid=-1; |
13 | sigset_t set, oldset; |
14 | |
15 | if (openpty(&m, &s, name, tio, ws) < 0) return -1; |
16 | |
17 | sigfillset(&set); |
18 | pthread_sigmask(SIG_BLOCK, &set, &oldset); |
19 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
20 | |
21 | if (pipe2(p, O_CLOEXEC)) { |
22 | close(s); |
23 | goto out; |
24 | } |
25 | |
26 | pid = fork(); |
27 | if (!pid) { |
28 | close(m); |
29 | close(p[0]); |
30 | if (login_tty(s)) { |
31 | write(p[1], &errno, sizeof errno); |
32 | _exit(127); |
33 | } |
34 | close(p[1]); |
35 | pthread_setcancelstate(cs, 0); |
36 | pthread_sigmask(SIG_SETMASK, &oldset, 0); |
37 | return 0; |
38 | } |
39 | close(s); |
40 | close(p[1]); |
41 | if (read(p[0], &ec, sizeof ec) > 0) { |
42 | int status; |
43 | waitpid(pid, &status, 0); |
44 | pid = -1; |
45 | errno = ec; |
46 | } |
47 | close(p[0]); |
48 | |
49 | out: |
50 | if (pid > 0) *pm = m; |
51 | else close(m); |
52 | |
53 | pthread_setcancelstate(cs, 0); |
54 | pthread_sigmask(SIG_SETMASK, &oldset, 0); |
55 | |
56 | return pid; |
57 | } |
Note:
See TracBrowser
for help on using the repository browser.