annotate contrib/chg/procutil.c @ 33877:bcf53149ebce

contrib: make import checker always think in terms of bytes The doctests now do some regrettable things, but they'll always work since we're dealing with ASCII module names etc.
author Augie Fackler <raf@durin42.com>
date Tue, 22 Aug 2017 12:58:28 -0400
parents ac5527021097
children 9724f54923ec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 *
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5 *
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
6 * This software may be used and distributed according to the terms of the
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
7 * GNU General Public License version 2 or any later version.
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
8 */
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
9
30693
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
10 #include <assert.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
11 #include <errno.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
12 #include <signal.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
13 #include <stdio.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
14 #include <string.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
15 #include <sys/wait.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
16 #include <unistd.h>
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
17
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
18 #include "procutil.h"
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
19 #include "util.h"
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
23 static pid_t peerpid = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
24
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
25 static void forwardsignal(int sig)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
26 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
27 assert(peerpid > 0);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
30 debugmsg("forward signal %d", sig);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
31 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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);
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
57 if (raise(sig) < 0) /* resend to self */
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
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
85 void setupsignalhandler(pid_t pid, pid_t pgid)
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
86 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
87 if (pid <= 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
88 return;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
92 struct sigaction sa;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
107
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
114 /* notify the worker about window resize events */
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
115 sa.sa_flags = SA_RESTART;
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
116 if (sigaction(SIGWINCH, &sa, NULL) < 0)
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
117 goto error;
31230
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
118 /* forward user-defined signals */
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
119 if (sigaction(SIGUSR1, &sa, NULL) < 0)
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
120 goto error;
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
121 if (sigaction(SIGUSR2, &sa, NULL) < 0)
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
142 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
143
30693
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
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
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
178 /* This implementation is based on hgext/pager.py (post 369741ef7253)
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
181 {
30692
23ddd43ba866 chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents: 30691
diff changeset
182 assert(pagerpid == 0);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
183 if (!pagercmd)
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
184 return 0;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
185
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
186 int pipefds[2];
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
187 if (pipe(pipefds) < 0)
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
188 return 0;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
189 pid_t pid = fork();
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
190 if (pid < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
191 goto error;
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
192 if (pid > 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
193 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
194 if (dup2(pipefds[1], fileno(stdout)) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
195 goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
196 if (isatty(fileno(stderr))) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
197 if (dup2(pipefds[1], fileno(stderr)) < 0)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
198 goto error;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
199 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
202 return pid;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
203 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
204 dup2(pipefds[0], fileno(stdin));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
205 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
206 close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
207
31941
ac5527021097 chg: respect environment variables for pager
Jun Wu <quark@fb.com>
parents: 31230
diff changeset
208 int r = execle("/bin/sh", "/bin/sh", "-c", pagercmd, NULL,
ac5527021097 chg: respect environment variables for pager
Jun Wu <quark@fb.com>
parents: 31230
diff changeset
209 envp);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
212 }
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
213 return 0;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
214 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
215
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
216 error:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
217 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
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
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
220 return 0;
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
221 }
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
222
30693
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
223 void waitpager(void)
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
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
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
228 /* close output streams to notify the pager its input ends */
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
229 fclose(stdout);
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
230 fclose(stderr);
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
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
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
233 if (ret == -1 && errno == EINTR)
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
234 continue;
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
235 break;
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
236 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
237 }