annotate contrib/chg/util.c @ 45551:4c8d9b53b1c7

chg: make is possible to call by default an hg binary located next to chg When a single version of hg is in use and it's in the PATH, using chg is just a matter of calling chg. But when there are multiple installations of hg+chg around, and hg is referred to with an absolute path, using chg is more annoying because it requires both changing the invocation to hg to use chg, but also setting CHGHG. Currently, we set HGPATH when we build chg to remove the need to set CHGHG in the previous paragraph. But that means chg now hardcodes its installation path, which makes the installation not relocatable. Hence this proposal to make chg find ./hg relative to itself (as opposed to CHGHG=./hg which find hg relative to cwd). This only works on linux as written, but since it's opt-in, it sounds fine. Tested by hand, as I'm not sure how else to test this. Differential Revision: https://phab.mercurial-scm.org/D9006
author Valentin Gatien-Baron <vgatien-baron@janestreet.com>
date Thu, 03 Sep 2020 11:07:47 -0400
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 /*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 * Utility functions
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
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
10 #include <errno.h>
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
11 #include <fcntl.h>
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
12 #include <signal.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
13 #include <stdarg.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
14 #include <stdio.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
15 #include <stdlib.h>
28084
3fc45956c978 chg: initialize sigaction fields more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 28060
diff changeset
16 #include <string.h>
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
17 #include <sys/time.h>
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
18 #include <sys/types.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
19 #include <sys/wait.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
20 #include <unistd.h>
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
21
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
22 #include "util.h"
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
23
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
24 static int colorenabled = 0;
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
25
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
26 static inline void fsetcolor(FILE *fp, const char *code)
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
27 {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
28 if (!colorenabled) {
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
29 return;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
30 }
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
31 fprintf(fp, "\033[%sm", code);
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
32 }
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
33
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
34 static void vabortmsgerrno(int no, const char *fmt, va_list args)
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
35 {
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
36 fsetcolor(stderr, "1;31");
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
37 fputs("chg: abort: ", stderr);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
38 vfprintf(stderr, fmt, args);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
39 if (no != 0) {
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
40 fprintf(stderr, " (errno = %d, %s)", no, strerror(no));
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
41 }
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
42 fsetcolor(stderr, "");
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
43 fputc('\n', stderr);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
44 exit(255);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
45 }
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
46
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
47 void abortmsg(const char *fmt, ...)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
48 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
49 va_list args;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
50 va_start(args, fmt);
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
51 vabortmsgerrno(0, fmt, args);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
52 va_end(args);
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
53 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
54
28788
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
55 void abortmsgerrno(const char *fmt, ...)
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
56 {
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
57 int no = errno;
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
58 va_list args;
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
59 va_start(args, fmt);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
60 vabortmsgerrno(no, fmt, args);
57a78a64de44 chg: add util function abortmsgerrno to print error with errno
Jun Wu <quark@fb.com>
parents: 28787
diff changeset
61 va_end(args);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
62 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
63
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
64 static int debugmsgenabled = 0;
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
65 static double debugstart = 0;
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
66
35959
9724f54923ec chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents: 34309
diff changeset
67 static double now()
9724f54923ec chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents: 34309
diff changeset
68 {
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
69 struct timeval t;
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
70 gettimeofday(&t, NULL);
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
71 return t.tv_usec / 1e6 + t.tv_sec;
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
72 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
73
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
74 void enablecolor(void)
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
75 {
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
76 colorenabled = 1;
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
77 }
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
78
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
79 void enabledebugmsg(void)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
80 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
81 debugmsgenabled = 1;
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
82 debugstart = now();
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
83 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
84
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
85 void debugmsg(const char *fmt, ...)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
86 {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
87 if (!debugmsgenabled) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
88 return;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
89 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
90
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
91 va_list args;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
92 va_start(args, fmt);
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
93 fsetcolor(stderr, "1;30");
34309
b94db1780365 chg: show timestamp with debug messages
Jun Wu <quark@fb.com>
parents: 28855
diff changeset
94 fprintf(stderr, "chg: debug: %4.6f ", now() - debugstart);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
95 vfprintf(stderr, fmt, args);
28787
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
96 fsetcolor(stderr, "");
ea86cdcd9b50 chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents: 28165
diff changeset
97 fputc('\n', stderr);
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
98 va_end(args);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
99 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
100
28854
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
101 void fchdirx(int dirfd)
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
102 {
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
103 int r = fchdir(dirfd);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
104 if (r == -1) {
28854
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
105 abortmsgerrno("failed to fchdir");
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
106 }
28854
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
107 }
ddef14468952 chg: add fchdirx as a utility function
Jun Wu <quark@fb.com>
parents: 28788
diff changeset
108
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
109 void fsetcloexec(int fd)
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
110 {
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
111 int flags = fcntl(fd, F_GETFD);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
112 if (flags < 0) {
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
113 abortmsgerrno("cannot get flags of fd %d", fd);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
114 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
115 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
116 abortmsgerrno("cannot set flags of fd %d", fd);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
117 }
28855
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
118 }
f5764e177bbe chg: extract the logic of setting FD_CLOEXEC to a utility function
Jun Wu <quark@fb.com>
parents: 28854
diff changeset
119
28165
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
120 void *mallocx(size_t size)
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
121 {
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
122 void *result = malloc(size);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
123 if (!result) {
28165
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
124 abortmsg("failed to malloc");
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
125 }
28165
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
126 return result;
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
127 }
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
128
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
129 void *reallocx(void *ptr, size_t size)
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
130 {
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
131 void *result = realloc(ptr, size);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
132 if (!result) {
28165
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
133 abortmsg("failed to realloc");
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
134 }
28165
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
135 return result;
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
136 }
c6705c6303dd chg: add utility functions mallocx, reallocx
Jun Wu <quark@fb.com>
parents: 28084
diff changeset
137
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
138 /*
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
139 * Execute a shell command in mostly the same manner as system(), with the
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
140 * give environment variables, after chdir to the given cwd. Returns a status
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
141 * code compatible with the Python subprocess module.
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 int runshellcmd(const char *cmd, const char *envp[], const char *cwd)
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
144 {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
145 enum { F_SIGINT = 1, F_SIGQUIT = 2, F_SIGMASK = 4, F_WAITPID = 8 };
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
146 unsigned int doneflags = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
147 int status = 0;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
148 struct sigaction newsa, oldsaint, oldsaquit;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
149 sigset_t oldmask;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
150
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
151 /* block or mask signals just as system() does */
28084
3fc45956c978 chg: initialize sigaction fields more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 28060
diff changeset
152 memset(&newsa, 0, sizeof(newsa));
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
153 newsa.sa_handler = SIG_IGN;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
154 newsa.sa_flags = 0;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
155 if (sigemptyset(&newsa.sa_mask) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
156 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
157 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
158 if (sigaction(SIGINT, &newsa, &oldsaint) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
159 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
160 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
161 doneflags |= F_SIGINT;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
162 if (sigaction(SIGQUIT, &newsa, &oldsaquit) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
163 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
164 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
165 doneflags |= F_SIGQUIT;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
166
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
167 if (sigaddset(&newsa.sa_mask, SIGCHLD) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
168 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
169 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
170 if (sigprocmask(SIG_BLOCK, &newsa.sa_mask, &oldmask) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
171 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
172 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
173 doneflags |= F_SIGMASK;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
174
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
175 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
176 if (pid < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
177 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
178 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
179 if (pid == 0) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
180 sigaction(SIGINT, &oldsaint, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
181 sigaction(SIGQUIT, &oldsaquit, NULL);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
182 sigprocmask(SIG_SETMASK, &oldmask, NULL);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
183 if (cwd && chdir(cwd) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
184 _exit(127);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
185 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
186 const char *argv[] = {"sh", "-c", cmd, NULL};
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
187 if (envp) {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
188 execve("/bin/sh", (char **)argv, (char **)envp);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
189 } else {
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
190 execv("/bin/sh", (char **)argv);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
191 }
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
192 _exit(127);
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
193 } else {
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
194 if (waitpid(pid, &status, 0) < 0) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
195 goto done;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
196 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
197 doneflags |= F_WAITPID;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
198 }
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 done:
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
201 if (doneflags & F_SIGINT) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
202 sigaction(SIGINT, &oldsaint, NULL);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
203 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
204 if (doneflags & F_SIGQUIT) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
205 sigaction(SIGQUIT, &oldsaquit, NULL);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
206 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
207 if (doneflags & F_SIGMASK) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
208 sigprocmask(SIG_SETMASK, &oldmask, NULL);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
209 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
210
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
211 /* no way to report other errors, use 127 (= shell termination) */
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
212 if (!(doneflags & F_WAITPID)) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
213 return 127;
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
214 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
215 if (WIFEXITED(status)) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
216 return WEXITSTATUS(status);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
217 }
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
218 if (WIFSIGNALED(status)) {
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
219 return -WTERMSIG(status);
41336
763b45bc4483 cleanup: use clang-tidy to add missing {} around one-line statements
Augie Fackler <augie@google.com>
parents: 35959
diff changeset
220 }
28060
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
221 return 127;
726f8d6cc324 chg: import frontend sources
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
222 }