annotate contrib/chg/procutil.c @ 42558:11c025c83393

rust: simplify overly complicated expression Differential Revision: https://phab.mercurial-scm.org/D6592
author Raphaël Gomès <rgomes@octobus.net>
date Mon, 01 Jul 2019 10:53:36 +0200
parents 763b45bc4483
children
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);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
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);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
30 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
31 debugmsg("forward signal %d", sig);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
32 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
33
29608
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
34 static void forwardsignaltogroup(int sig)
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
35 {
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
36 /* 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
37 pid_t killpid = peerpgid > 1 ? -peerpgid : peerpid;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
38 if (kill(killpid, sig) < 0) {
29608
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
39 abortmsgerrno("cannot kill %d", killpid);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
40 }
29608
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
41 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
42 }
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
43
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
44 static void handlestopsignal(int sig)
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
45 {
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
46 sigset_t unblockset, oldset;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
47 struct sigaction sa, oldsa;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
48 if (sigemptyset(&unblockset) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
49 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
50 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
51 if (sigaddset(&unblockset, sig) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
52 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
53 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
54 memset(&sa, 0, sizeof(sa));
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
55 sa.sa_handler = SIG_DFL;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
56 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
57 if (sigemptyset(&sa.sa_mask) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
58 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
59 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
60
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
61 forwardsignal(sig);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
62 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
63 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
64 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
65 if (sigaction(sig, &sa, &oldsa) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
66 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
67 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
68 if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
69 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
70 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
71 /* resent signal will be handled before sigprocmask() returns */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
72 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
73 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
74 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
75 if (sigaction(sig, &oldsa, NULL) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
76 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
77 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
78 return;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
79
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
80 error:
28789
7f6e0a15189b chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
81 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
82 }
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
83
29440
009cc6c89d0f chg: silence warning of unused parameter 'sig'
Yuya Nishihara <yuya@tcha.org>
parents: 29429
diff changeset
84 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
85 {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
86 if (peerpid == 0 || pagerpid == 0) {
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
87 return;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
88 }
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
89 /* 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
90 * 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
91 * anything. (issue5278) */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
92 if (waitpid(pagerpid, NULL, WNOHANG) == pagerpid) {
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
93 kill(peerpid, SIGPIPE);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
94 }
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
95 }
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
96
30693
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
97 void setupsignalhandler(pid_t pid, pid_t pgid)
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
98 {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
99 if (pid <= 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
100 return;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
101 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
102 peerpid = pid;
29608
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
103 peerpgid = (pgid <= 1 ? 0 : pgid);
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
104
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
105 struct sigaction sa;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
106 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
107
68c94f286e25 chg: document why we send SIGHUP and SIGINT to process group
Jun Wu <quark@fb.com>
parents: 30693
diff changeset
108 /* 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
109 * - 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
110 * 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
111 * - SIGINT: usually generated by the terminal */
29608
681fe090d82e chg: forward SIGINT, SIGHUP to process group
Jun Wu <quark@fb.com>
parents: 29440
diff changeset
112 sa.sa_handler = forwardsignaltogroup;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
113 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
114 if (sigemptyset(&sa.sa_mask) < 0) {
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
115 goto error;
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
116 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
117 if (sigaction(SIGHUP, &sa, NULL) < 0) {
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
118 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
119 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
120 if (sigaction(SIGINT, &sa, NULL) < 0) {
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
121 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
122 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
123
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
124 /* 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
125 sa.sa_handler = forwardsignal;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
126 sa.sa_flags |= SA_RESETHAND;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
127 if (sigaction(SIGTERM, &sa, NULL) < 0) {
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
128 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
129 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
130
28980
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
131 /* notify the worker about window resize events */
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
132 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
133 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
28980
b89e4457fa86 chg: forward SIGWINCH to worker
Jun Wu <quark@fb.com>
parents: 28863
diff changeset
134 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
135 }
31230
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
136 /* forward user-defined signals */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
137 if (sigaction(SIGUSR1, &sa, NULL) < 0) {
31230
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
138 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
139 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
140 if (sigaction(SIGUSR2, &sa, NULL) < 0) {
31230
cc37b5a06e32 chg: forward user-defined signals
Jun Wu <quark@fb.com>
parents: 31229
diff changeset
141 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
142 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
143 /* 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
144 sa.sa_handler = forwardsignal;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
145 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
146 if (sigaction(SIGCONT, &sa, NULL) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
147 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
148 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
149 sa.sa_handler = handlestopsignal;
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
150 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
151 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
152 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
153 }
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
154 /* 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
155 sa.sa_handler = handlechildsignal;
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
156 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
157 if (sigaction(SIGCHLD, &sa, NULL) < 0) {
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
158 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
159 }
28086
65d24ca35496 chg: forward job control signals to worker process (issue5051)
Yuya Nishihara <yuya@tcha.org>
parents: 28085
diff changeset
160
28085
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
161 return;
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
162
c0d1bf1b26b7 chg: verify return value of sigaction() and sigemptyset()
Yuya Nishihara <yuya@tcha.org>
parents: 28084
diff changeset
163 error:
28789
7f6e0a15189b chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
164 abortmsgerrno("failed to set up signal handlers");
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
165 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
166
30693
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
167 void restoresignalhandler(void)
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
168 {
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
169 struct sigaction sa;
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
170 memset(&sa, 0, sizeof(sa));
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
171 sa.sa_handler = SIG_DFL;
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
172 sa.sa_flags = SA_RESTART;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
173 if (sigemptyset(&sa.sa_mask) < 0) {
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
174 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
175 }
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
176
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
177 if (sigaction(SIGHUP, &sa, NULL) < 0) {
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
178 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
179 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
180 if (sigaction(SIGTERM, &sa, NULL) < 0) {
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
181 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
182 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
183 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
184 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
185 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
186 if (sigaction(SIGCONT, &sa, NULL) < 0) {
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
187 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
188 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
189 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
190 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
191 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
192 if (sigaction(SIGCHLD, &sa, NULL) < 0) {
29429
cf99de051385 chg: send SIGPIPE to server immediately when pager exits (issue5278)
Jun Wu <quark@fb.com>
parents: 29370
diff changeset
193 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
194 }
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
195
29370
3ddf4d0c4170 chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents: 29369
diff changeset
196 /* 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
197 sa.sa_handler = SIG_IGN;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
198 if (sigaction(SIGINT, &sa, NULL) < 0) {
29370
3ddf4d0c4170 chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents: 29369
diff changeset
199 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
200 }
29370
3ddf4d0c4170 chg: ignore SIGINT while waiting pager termination
Yuya Nishihara <yuya@tcha.org>
parents: 29369
diff changeset
201
29369
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
202 peerpid = 0;
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
203 return;
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
204
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
205 error:
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
206 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
207 }
85a18f3c0bdd chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents: 29357
diff changeset
208
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
209 /* 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
210 * 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
211 pid_t setuppager(const char *pagercmd, const char *envp[])
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
212 {
30692
23ddd43ba866 chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents: 30691
diff changeset
213 assert(pagerpid == 0);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
214 if (!pagercmd) {
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
215 return 0;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
216 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
217
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
218 int pipefds[2];
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
219 if (pipe(pipefds) < 0) {
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
220 return 0;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
221 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
222 pid_t pid = fork();
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
223 if (pid < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
224 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
225 }
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
226 if (pid > 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
227 close(pipefds[0]);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
228 if (dup2(pipefds[1], fileno(stdout)) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
229 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
230 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
231 if (isatty(fileno(stderr))) {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
232 if (dup2(pipefds[1], fileno(stderr)) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
233 goto error;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
234 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
235 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
236 close(pipefds[1]);
30692
23ddd43ba866 chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents: 30691
diff changeset
237 pagerpid = pid;
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
238 return pid;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
239 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
240 dup2(pipefds[0], fileno(stdin));
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
241 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
242 close(pipefds[1]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
243
35959
9724f54923ec chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents: 31941
diff changeset
244 int r =
9724f54923ec chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents: 31941
diff changeset
245 execle("/bin/sh", "/bin/sh", "-c", pagercmd, NULL, envp);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
246 if (r < 0) {
28789
7f6e0a15189b chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
247 abortmsgerrno("cannot start pager '%s'", pagercmd);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
248 }
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
249 return 0;
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
250 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
251
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
252 error:
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
253 close(pipefds[0]);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
254 close(pipefds[1]);
28789
7f6e0a15189b chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
255 abortmsgerrno("failed to prepare pager");
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
256 return 0;
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
257 }
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
258
30693
baee0f47b533 chg: add procutil.h
Jun Wu <quark@fb.com>
parents: 30692
diff changeset
259 void waitpager(void)
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
260 {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
261 if (pagerpid == 0) {
30692
23ddd43ba866 chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents: 30691
diff changeset
262 return;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
263 }
30692
23ddd43ba866 chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents: 30691
diff changeset
264
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
265 /* 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
266 fclose(stdout);
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
267 fclose(stderr);
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
268 while (1) {
30692
23ddd43ba866 chg: let procutil maintain its own pagerpid
Jun Wu <quark@fb.com>
parents: 30691
diff changeset
269 pid_t ret = waitpid(pagerpid, NULL, 0);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
270 if (ret == -1 && errno == EINTR) {
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
271 continue;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
272 }
29344
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
273 break;
bb3d5c20eaf6 chg: exec pager in child process
Jun Wu <quark@fb.com>
parents: 29016
diff changeset
274 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
275 }