Mercurial > hg
annotate contrib/chg/procutil.c @ 40667:02318e0810ac
py3: add 9 new passing tests caught by buildbot
Differential Revision: https://phab.mercurial-scm.org/D5284
author | Pulkit Goyal <pulkit@yandex-team.ru> |
---|---|
date | Mon, 19 Nov 2018 19:57:11 +0300 |
parents | 9724f54923ec |
children | 763b45bc4483 |
rev | line source |
---|---|
28060 | 1 /* |
30689
9fa7255d4abd
chg: move signal and pager handling to a separate file
Jun Wu <quark@fb.com>
parents:
30681
diff
changeset
|
2 * Utilities about process handling - signal and subprocess (ex. pager) |
28060 | 3 * |
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org> | |
5 * | |
6 * This software may be used and distributed according to the terms of the | |
7 * GNU General Public License version 2 or any later version. | |
8 */ | |
9 | |
30693 | 10 #include <assert.h> |
11 #include <errno.h> | |
12 #include <signal.h> | |
13 #include <stdio.h> | |
14 #include <string.h> | |
15 #include <sys/wait.h> | |
16 #include <unistd.h> | |
17 | |
18 #include "procutil.h" | |
19 #include "util.h" | |
20 | |
29429
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
21 static pid_t pagerpid = 0; |
29608
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
22 static pid_t peerpgid = 0; |
28060 | 23 static pid_t peerpid = 0; |
24 | |
25 static void forwardsignal(int sig) | |
26 { | |
27 assert(peerpid > 0); | |
28 if (kill(peerpid, sig) < 0) | |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
29 abortmsgerrno("cannot kill %d", peerpid); |
28060 | 30 debugmsg("forward signal %d", sig); |
31 } | |
32 | |
29608
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
33 static void forwardsignaltogroup(int sig) |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
34 { |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
35 /* prefer kill(-pgid, sig), fallback to pid if pgid is invalid */ |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
36 pid_t killpid = peerpgid > 1 ? -peerpgid : peerpid; |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
37 if (kill(killpid, sig) < 0) |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
38 abortmsgerrno("cannot kill %d", killpid); |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
39 debugmsg("forward signal %d to %d", sig, killpid); |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
40 } |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
41 |
28086
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
42 static void handlestopsignal(int sig) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
43 { |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
44 sigset_t unblockset, oldset; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
45 struct sigaction sa, oldsa; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
46 if (sigemptyset(&unblockset) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
47 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
48 if (sigaddset(&unblockset, sig) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
49 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
50 memset(&sa, 0, sizeof(sa)); |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
51 sa.sa_handler = SIG_DFL; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
52 sa.sa_flags = SA_RESTART; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
53 if (sigemptyset(&sa.sa_mask) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
54 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
55 |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
56 forwardsignal(sig); |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
31941
diff
changeset
|
57 if (raise(sig) < 0) /* resend to self */ |
28086
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
58 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
59 if (sigaction(sig, &sa, &oldsa) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
60 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
61 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
62 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
63 /* resent signal will be handled before sigprocmask() returns */ |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
64 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
65 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
66 if (sigaction(sig, &oldsa, NULL) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
67 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
68 return; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
69 |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
70 error: |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
71 abortmsgerrno("failed to handle stop signal"); |
28086
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
72 } |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
73 |
29440
009cc6c89d0f
chg: silence warning of unused parameter 'sig'
Yuya Nishihara <yuya@tcha.org>
parents:
29429
diff
changeset
|
74 static void handlechildsignal(int sig UNUSED_) |
29429
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
75 { |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
76 if (peerpid == 0 || pagerpid == 0) |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
77 return; |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
78 /* if pager exits, notify the server with SIGPIPE immediately. |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
79 * otherwise the server won't get SIGPIPE if it does not write |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
80 * anything. (issue5278) */ |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
81 if (waitpid(pagerpid, NULL, WNOHANG) == pagerpid) |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
82 kill(peerpid, SIGPIPE); |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
83 } |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
84 |
30693 | 85 void setupsignalhandler(pid_t pid, pid_t pgid) |
28060 | 86 { |
87 if (pid <= 0) | |
88 return; | |
89 peerpid = pid; | |
29608
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
90 peerpgid = (pgid <= 1 ? 0 : pgid); |
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
91 |
28060 | 92 struct sigaction sa; |
93 memset(&sa, 0, sizeof(sa)); | |
31229
68c94f286e25
chg: document why we send SIGHUP and SIGINT to process group
Jun Wu <quark@fb.com>
parents:
30693
diff
changeset
|
94 |
68c94f286e25
chg: document why we send SIGHUP and SIGINT to process group
Jun Wu <quark@fb.com>
parents:
30693
diff
changeset
|
95 /* deadly signals meant to be sent to a process group: |
68c94f286e25
chg: document why we send SIGHUP and SIGINT to process group
Jun Wu <quark@fb.com>
parents:
30693
diff
changeset
|
96 * - SIGHUP: usually generated by the kernel, when termination of a |
68c94f286e25
chg: document why we send SIGHUP and SIGINT to process group
Jun Wu <quark@fb.com>
parents:
30693
diff
changeset
|
97 * process causes that process group to become orphaned |
68c94f286e25
chg: document why we send SIGHUP and SIGINT to process group
Jun Wu <quark@fb.com>
parents:
30693
diff
changeset
|
98 * - SIGINT: usually generated by the terminal */ |
29608
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
99 sa.sa_handler = forwardsignaltogroup; |
28060 | 100 sa.sa_flags = SA_RESTART; |
28085
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
101 if (sigemptyset(&sa.sa_mask) < 0) |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
102 goto error; |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
103 if (sigaction(SIGHUP, &sa, NULL) < 0) |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
104 goto error; |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
105 if (sigaction(SIGINT, &sa, NULL) < 0) |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
106 goto error; |
28060 | 107 |
108 /* terminate frontend by double SIGTERM in case of server freeze */ | |
29608
681fe090d82e
chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents:
29440
diff
changeset
|
109 sa.sa_handler = forwardsignal; |
28060 | 110 sa.sa_flags |= SA_RESETHAND; |
28085
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
111 if (sigaction(SIGTERM, &sa, NULL) < 0) |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
112 goto error; |
28086
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
113 |
28980 | 114 /* notify the worker about window resize events */ |
115 sa.sa_flags = SA_RESTART; | |
116 if (sigaction(SIGWINCH, &sa, NULL) < 0) | |
117 goto error; | |
31230 | 118 /* forward user-defined signals */ |
119 if (sigaction(SIGUSR1, &sa, NULL) < 0) | |
120 goto error; | |
121 if (sigaction(SIGUSR2, &sa, NULL) < 0) | |
122 goto error; | |
28086
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
123 /* propagate job control requests to worker */ |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
124 sa.sa_handler = forwardsignal; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
125 sa.sa_flags = SA_RESTART; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
126 if (sigaction(SIGCONT, &sa, NULL) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
127 goto error; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
128 sa.sa_handler = handlestopsignal; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
129 sa.sa_flags = SA_RESTART; |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
130 if (sigaction(SIGTSTP, &sa, NULL) < 0) |
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
131 goto error; |
29429
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
132 /* get notified when pager exits */ |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
133 sa.sa_handler = handlechildsignal; |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
134 sa.sa_flags = SA_RESTART; |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
135 if (sigaction(SIGCHLD, &sa, NULL) < 0) |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
136 goto error; |
28086
65d24ca35496
chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents:
28085
diff
changeset
|
137 |
28085
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
138 return; |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
139 |
c0d1bf1b26b7
chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents:
28084
diff
changeset
|
140 error: |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
141 abortmsgerrno("failed to set up signal handlers"); |
28060 | 142 } |
143 | |
30693 | 144 void restoresignalhandler(void) |
29369
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
145 { |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
146 struct sigaction sa; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
147 memset(&sa, 0, sizeof(sa)); |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
148 sa.sa_handler = SIG_DFL; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
149 sa.sa_flags = SA_RESTART; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
150 if (sigemptyset(&sa.sa_mask) < 0) |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
151 goto error; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
152 |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
153 if (sigaction(SIGHUP, &sa, NULL) < 0) |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
154 goto error; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
155 if (sigaction(SIGTERM, &sa, NULL) < 0) |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
156 goto error; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
157 if (sigaction(SIGWINCH, &sa, NULL) < 0) |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
158 goto error; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
159 if (sigaction(SIGCONT, &sa, NULL) < 0) |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
160 goto error; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
161 if (sigaction(SIGTSTP, &sa, NULL) < 0) |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
162 goto error; |
29429
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
163 if (sigaction(SIGCHLD, &sa, NULL) < 0) |
cf99de051385
chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents:
29370
diff
changeset
|
164 goto error; |
29369
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
165 |
29370
3ddf4d0c4170
chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents:
29369
diff
changeset
|
166 /* ignore Ctrl+C while shutting down to make pager exits cleanly */ |
3ddf4d0c4170
chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents:
29369
diff
changeset
|
167 sa.sa_handler = SIG_IGN; |
3ddf4d0c4170
chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents:
29369
diff
changeset
|
168 if (sigaction(SIGINT, &sa, NULL) < 0) |
3ddf4d0c4170
chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents:
29369
diff
changeset
|
169 goto error; |
3ddf4d0c4170
chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents:
29369
diff
changeset
|
170 |
29369
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
171 peerpid = 0; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
172 return; |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
173 |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
174 error: |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
175 abortmsgerrno("failed to restore signal handlers"); |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
176 } |
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
177 |
29344 | 178 /* This implementation is based on hgext/pager.py (post 369741ef7253) |
179 * Return 0 if pager is not started, or pid of the pager */ | |
31941
ac5527021097
chg: respect environment variables for pager
Jun Wu <quark@fb.com>
parents:
31230
diff
changeset
|
180 pid_t setuppager(const char *pagercmd, const char *envp[]) |
28060 | 181 { |
30692
23ddd43ba866
chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents:
30691
diff
changeset
|
182 assert(pagerpid == 0); |
28060 | 183 if (!pagercmd) |
29344 | 184 return 0; |
28060 | 185 |
186 int pipefds[2]; | |
187 if (pipe(pipefds) < 0) | |
29344 | 188 return 0; |
28060 | 189 pid_t pid = fork(); |
190 if (pid < 0) | |
191 goto error; | |
29344 | 192 if (pid > 0) { |
28060 | 193 close(pipefds[0]); |
194 if (dup2(pipefds[1], fileno(stdout)) < 0) | |
195 goto error; | |
196 if (isatty(fileno(stderr))) { | |
197 if (dup2(pipefds[1], fileno(stderr)) < 0) | |
198 goto error; | |
199 } | |
200 close(pipefds[1]); | |
30692
23ddd43ba866
chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents:
30691
diff
changeset
|
201 pagerpid = pid; |
29344 | 202 return pid; |
28060 | 203 } else { |
204 dup2(pipefds[0], fileno(stdin)); | |
205 close(pipefds[0]); | |
206 close(pipefds[1]); | |
207 | |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
31941
diff
changeset
|
208 int r = |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
31941
diff
changeset
|
209 execle("/bin/sh", "/bin/sh", "-c", pagercmd, NULL, envp); |
28060 | 210 if (r < 0) { |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
211 abortmsgerrno("cannot start pager '%s'", pagercmd); |
28060 | 212 } |
29344 | 213 return 0; |
28060 | 214 } |
215 | |
216 error: | |
217 close(pipefds[0]); | |
218 close(pipefds[1]); | |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
219 abortmsgerrno("failed to prepare pager"); |
29344 | 220 return 0; |
221 } | |
222 | |
30693 | 223 void waitpager(void) |
29344 | 224 { |
30692
23ddd43ba866
chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents:
30691
diff
changeset
|
225 if (pagerpid == 0) |
23ddd43ba866
chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents:
30691
diff
changeset
|
226 return; |
23ddd43ba866
chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents:
30691
diff
changeset
|
227 |
29344 | 228 /* close output streams to notify the pager its input ends */ |
229 fclose(stdout); | |
230 fclose(stderr); | |
231 while (1) { | |
30692
23ddd43ba866
chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents:
30691
diff
changeset
|
232 pid_t ret = waitpid(pagerpid, NULL, 0); |
29344 | 233 if (ret == -1 && errno == EINTR) |
234 continue; | |
235 break; | |
236 } | |
28060 | 237 } |