Mercurial > hg
annotate contrib/chg/chg.c @ 49957:ff4df0954742
setup: Ensure target directory exists with building rust extension
When the rust extension is the first to be build, the target directory may not
exist so the copy fails.
author | Cédric Krier <ced@b2ck.com> |
---|---|
date | Sat, 28 Jan 2023 20:08:57 +0100 |
parents | 8fcc0a829f3d |
children | cf4d2f31660d |
rev | line source |
---|---|
28060 | 1 /* |
2 * A fast client for Mercurial command server | |
3 * | |
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org> | |
5 * | |
6 * This software may be used and distributed according to the terms of the | |
7 * GNU General Public License version 2 or any later version. | |
8 */ | |
9 | |
10 #include <assert.h> | |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
11 #include <dirent.h> |
28060 | 12 #include <errno.h> |
13 #include <fcntl.h> | |
14 #include <signal.h> | |
15 #include <stdio.h> | |
16 #include <stdlib.h> | |
17 #include <string.h> | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
18 #include <sys/file.h> |
28060 | 19 #include <sys/stat.h> |
20 #include <sys/types.h> | |
21 #include <sys/un.h> | |
22 #include <sys/wait.h> | |
23 #include <time.h> | |
24 #include <unistd.h> | |
25 | |
26 #include "hgclient.h" | |
30693 | 27 #include "procutil.h" |
28060 | 28 #include "util.h" |
29 | |
30677 | 30 #ifndef PATH_MAX |
31 #define PATH_MAX 4096 | |
28060 | 32 #endif |
33 | |
34 struct cmdserveropts { | |
30677 | 35 char sockname[PATH_MAX]; |
36 char initsockname[PATH_MAX]; | |
37 char redirectsockname[PATH_MAX]; | |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
38 size_t argsize; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
39 const char **args; |
28060 | 40 }; |
41 | |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
42 static void initcmdserveropts(struct cmdserveropts *opts) |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
43 { |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
44 memset(opts, 0, sizeof(struct cmdserveropts)); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
45 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
46 |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
47 static void freecmdserveropts(struct cmdserveropts *opts) |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
48 { |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
49 free(opts->args); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
50 opts->args = NULL; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
51 opts->argsize = 0; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
52 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
53 |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
54 /* |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
55 * Test if an argument is a sensitive flag that should be passed to the server. |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
56 * Return 0 if not, otherwise the number of arguments starting from the current |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
57 * one that should be passed to the server. |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
58 */ |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
59 static size_t testsensitiveflag(const char *arg) |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
60 { |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
61 static const struct { |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
62 const char *name; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
63 size_t narg; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
64 } flags[] = { |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
65 {"--config", 1}, {"--cwd", 1}, {"--repo", 1}, |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
66 {"--repository", 1}, {"--traceback", 0}, {"-R", 1}, |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
67 }; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
68 size_t i; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
69 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) { |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
70 size_t len = strlen(flags[i].name); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
71 size_t narg = flags[i].narg; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
72 if (memcmp(arg, flags[i].name, len) == 0) { |
28790 | 73 if (arg[len] == '\0') { |
74 /* --flag (value) */ | |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
75 return narg + 1; |
28790 | 76 } else if (arg[len] == '=' && narg > 0) { |
77 /* --flag=value */ | |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
78 return 1; |
28790 | 79 } else if (flags[i].name[1] != '-') { |
80 /* short flag */ | |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
81 return 1; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
82 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
83 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
84 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
85 return 0; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
86 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
87 |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
88 /* |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
89 * Parse argv[] and put sensitive flags to opts->args |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
90 */ |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
91 static void setcmdserverargs(struct cmdserveropts *opts, int argc, |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
92 const char *argv[]) |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
93 { |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
94 size_t i, step; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
95 opts->argsize = 0; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
96 for (i = 0, step = 1; i < (size_t)argc; i += step, step = 1) { |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
97 if (!argv[i]) |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
98 continue; /* pass clang-analyse */ |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
99 if (strcmp(argv[i], "--") == 0) |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
100 break; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
101 size_t n = testsensitiveflag(argv[i]); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
102 if (n == 0 || i + n > (size_t)argc) |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
103 continue; |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
104 opts->args = |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
105 reallocx(opts->args, (n + opts->argsize) * sizeof(char *)); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
106 memcpy(opts->args + opts->argsize, argv + i, |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
107 sizeof(char *) * n); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
108 opts->argsize += n; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
109 step = n; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
110 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
111 } |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
112 |
28060 | 113 static void preparesockdir(const char *sockdir) |
114 { | |
115 int r; | |
116 r = mkdir(sockdir, 0700); | |
117 if (r < 0 && errno != EEXIST) | |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
118 abortmsgerrno("cannot create sockdir %s", sockdir); |
28060 | 119 |
120 struct stat st; | |
121 r = lstat(sockdir, &st); | |
122 if (r < 0) | |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
123 abortmsgerrno("cannot stat %s", sockdir); |
28060 | 124 if (!S_ISDIR(st.st_mode)) |
125 abortmsg("cannot create sockdir %s (file exists)", sockdir); | |
126 if (st.st_uid != geteuid() || st.st_mode & 0077) | |
127 abortmsg("insecure sockdir %s", sockdir); | |
128 } | |
129 | |
30884 | 130 /* |
131 * Check if a socket directory exists and is only owned by the current user. | |
132 * Return 1 if so, 0 if not. This is used to check if XDG_RUNTIME_DIR can be | |
133 * used or not. According to the specification [1], XDG_RUNTIME_DIR should be | |
134 * ignored if the directory is not owned by the user with mode 0700. | |
135 * [1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html | |
136 */ | |
137 static int checkruntimedir(const char *sockdir) | |
138 { | |
139 struct stat st; | |
140 int r = lstat(sockdir, &st); | |
141 if (r < 0) /* ex. does not exist */ | |
142 return 0; | |
143 if (!S_ISDIR(st.st_mode)) /* ex. is a file, not a directory */ | |
144 return 0; | |
145 return st.st_uid == geteuid() && (st.st_mode & 0777) == 0700; | |
146 } | |
147 | |
30680
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
148 static void getdefaultsockdir(char sockdir[], size_t size) |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
149 { |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
150 /* by default, put socket file in secure directory |
30681 | 151 * (${XDG_RUNTIME_DIR}/chg, or /${TMPDIR:-tmp}/chg$UID) |
30680
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
152 * (permission of socket file may be ignored on some Unices) */ |
30681 | 153 const char *runtimedir = getenv("XDG_RUNTIME_DIR"); |
154 int r; | |
30884 | 155 if (runtimedir && checkruntimedir(runtimedir)) { |
30681 | 156 r = snprintf(sockdir, size, "%s/chg", runtimedir); |
157 } else { | |
158 const char *tmpdir = getenv("TMPDIR"); | |
159 if (!tmpdir) | |
160 tmpdir = "/tmp"; | |
161 r = snprintf(sockdir, size, "%s/chg%d", tmpdir, geteuid()); | |
162 } | |
30680
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
163 if (r < 0 || (size_t)r >= size) |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
164 abortmsg("too long TMPDIR (r = %d)", r); |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
165 } |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
166 |
28060 | 167 static void setcmdserveropts(struct cmdserveropts *opts) |
168 { | |
169 int r; | |
30677 | 170 char sockdir[PATH_MAX]; |
28060 | 171 const char *envsockname = getenv("CHGSOCKNAME"); |
172 if (!envsockname) { | |
30680
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30677
diff
changeset
|
173 getdefaultsockdir(sockdir, sizeof(sockdir)); |
28060 | 174 preparesockdir(sockdir); |
175 } | |
176 | |
177 const char *basename = (envsockname) ? envsockname : sockdir; | |
178 const char *sockfmt = (envsockname) ? "%s" : "%s/server"; | |
179 r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename); | |
180 if (r < 0 || (size_t)r >= sizeof(opts->sockname)) | |
181 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); | |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
182 r = snprintf(opts->initsockname, sizeof(opts->initsockname), "%s.%u", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
183 opts->sockname, (unsigned)getpid()); |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
184 if (r < 0 || (size_t)r >= sizeof(opts->initsockname)) |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
185 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
28060 | 186 } |
187 | |
45551
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
188 /* If the current program is, say, /a/b/c/chg, returns /a/b/c/hg. */ |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
189 static char *getrelhgcmd(void) |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
190 { |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
191 ssize_t n; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
192 char *res, *slash; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
193 int maxsize = 4096; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
194 res = malloc(maxsize); |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
195 if (res == NULL) |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
196 goto cleanup; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
197 n = readlink("/proc/self/exe", res, maxsize); |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
198 if (n < 0 || n >= maxsize) |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
199 goto cleanup; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
200 res[n] = '\0'; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
201 slash = strrchr(res, '/'); |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
202 if (slash == NULL) |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
203 goto cleanup; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
204 /* 4 is strlen("/hg") + nul byte */ |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
205 if (slash + 4 >= res + maxsize) |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
206 goto cleanup; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
207 memcpy(slash, "/hg", 4); |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
208 return res; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
209 cleanup: |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
210 free(res); |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
211 return NULL; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
212 } |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
213 |
28237
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
214 static const char *gethgcmd(void) |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
215 { |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
216 static const char *hgcmd = NULL; |
45551
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
217 #ifdef HGPATHREL |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
218 int tryrelhgcmd = 1; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
219 #else |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
220 int tryrelhgcmd = 0; |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
221 #endif |
28237
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
222 if (!hgcmd) { |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
223 hgcmd = getenv("CHGHG"); |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
224 if (!hgcmd || hgcmd[0] == '\0') |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
225 hgcmd = getenv("HG"); |
45551
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
226 if (tryrelhgcmd && (!hgcmd || hgcmd[0] == '\0')) |
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45520
diff
changeset
|
227 hgcmd = getrelhgcmd(); |
28237
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
228 if (!hgcmd || hgcmd[0] == '\0') |
28605
baa073200ba2
chg: allows default hg path to be overridden
Jun Wu <quark@fb.com>
parents:
28555
diff
changeset
|
229 #ifdef HGPATH |
baa073200ba2
chg: allows default hg path to be overridden
Jun Wu <quark@fb.com>
parents:
28555
diff
changeset
|
230 hgcmd = (HGPATH); |
baa073200ba2
chg: allows default hg path to be overridden
Jun Wu <quark@fb.com>
parents:
28555
diff
changeset
|
231 #else |
28237
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
232 hgcmd = "hg"; |
28605
baa073200ba2
chg: allows default hg path to be overridden
Jun Wu <quark@fb.com>
parents:
28555
diff
changeset
|
233 #endif |
28237
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
234 } |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
235 return hgcmd; |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
236 } |
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
237 |
28060 | 238 static void execcmdserver(const struct cmdserveropts *opts) |
239 { | |
28237
a3d73e069f8d
chg: extract gethgcmd logic to a function
Jun Wu <quark@fb.com>
parents:
28196
diff
changeset
|
240 const char *hgcmd = gethgcmd(); |
28060 | 241 |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
242 const char *baseargv[] = { |
47024
8fcc0a829f3d
chg: pass --no-profile to disable profiling when starting hg serve
Kyle Lippincott <spectral@google.com>
parents:
46177
diff
changeset
|
243 hgcmd, "serve", "--no-profile", "--cmdserver", |
8fcc0a829f3d
chg: pass --no-profile to disable profiling when starting hg serve
Kyle Lippincott <spectral@google.com>
parents:
46177
diff
changeset
|
244 "chgunix", "--address", opts->initsockname, "--daemon-postexec", |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
245 "chdir:/", |
28060 | 246 }; |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
247 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
248 size_t argsize = baseargvsize + opts->argsize + 1; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
249 |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
250 const char **argv = mallocx(sizeof(char *) * argsize); |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
251 memcpy(argv, baseargv, sizeof(baseargv)); |
38198
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35959
diff
changeset
|
252 if (opts->args) { |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35959
diff
changeset
|
253 size_t size = sizeof(char *) * opts->argsize; |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35959
diff
changeset
|
254 memcpy(argv + baseargvsize, opts->args, size); |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35959
diff
changeset
|
255 } |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
256 argv[argsize - 1] = NULL; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
257 |
44261
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
258 const char *lc_ctype_env = getenv("LC_CTYPE"); |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
259 if (lc_ctype_env == NULL) { |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
260 if (putenv("CHG_CLEAR_LC_CTYPE=") != 0) |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
261 abortmsgerrno("failed to putenv CHG_CLEAR_LC_CTYPE"); |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
262 } else { |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
263 if (setenv("CHGORIG_LC_CTYPE", lc_ctype_env, 1) != 0) { |
44995 | 264 abortmsgerrno("failed to setenv CHGORIG_LC_CTYPE"); |
44261
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
265 } |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
266 } |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
38198
diff
changeset
|
267 |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
268 /* close any open files to avoid hanging locks */ |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
269 DIR *dp = opendir("/proc/self/fd"); |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
270 if (dp != NULL) { |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
271 debugmsg("closing files based on /proc contents"); |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
272 struct dirent *de; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
273 while ((de = readdir(dp))) { |
45851
81da6feb5000
chg: reset errno prior to calling strtol()
Yuya Nishihara <yuya@tcha.org>
parents:
45850
diff
changeset
|
274 errno = 0; |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
275 char *end; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
276 long fd_value = strtol(de->d_name, &end, 10); |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
277 if (end == de->d_name) { |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
278 /* unable to convert to int (. or ..) */ |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
279 continue; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
280 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
281 if (errno == ERANGE) { |
45848 | 282 debugmsg("tried to parse %s, but range error " |
283 "occurred", | |
284 de->d_name); | |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
285 continue; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
286 } |
45850
9534de20358f
chg: do not close dir fd while iterating
Yuya Nishihara <yuya@tcha.org>
parents:
45849
diff
changeset
|
287 if (fd_value > STDERR_FILENO && fd_value != dirfd(dp)) { |
45849
731ea8fa1f11
chg: show debug message for each fd to be closed
Yuya Nishihara <yuya@tcha.org>
parents:
45848
diff
changeset
|
288 debugmsg("closing fd %ld", fd_value); |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
289 int res = close(fd_value); |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
290 if (res) { |
45848 | 291 debugmsg("tried to close fd %ld: %d " |
292 "(errno: %d)", | |
293 fd_value, res, errno); | |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
294 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
295 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
296 } |
45850
9534de20358f
chg: do not close dir fd while iterating
Yuya Nishihara <yuya@tcha.org>
parents:
45849
diff
changeset
|
297 closedir(dp); |
45802
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
298 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45551
diff
changeset
|
299 |
28261 | 300 if (putenv("CHGINTERNALMARK=") != 0) |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
301 abortmsgerrno("failed to putenv"); |
28060 | 302 if (execvp(hgcmd, (char **)argv) < 0) |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
303 abortmsgerrno("failed to exec cmdserver"); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
304 free(argv); |
28060 | 305 } |
306 | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
307 /* Retry until we can connect to the server. Give up after some time. */ |
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
308 static hgclient_t *retryconnectcmdserver(struct cmdserveropts *opts, pid_t pid) |
28060 | 309 { |
310 static const struct timespec sleepreq = {0, 10 * 1000000}; | |
311 int pst = 0; | |
312 | |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
313 debugmsg("try connect to %s repeatedly", opts->initsockname); |
29345 | 314 |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
315 unsigned int timeoutsec = 60; /* default: 60 seconds */ |
29345 | 316 const char *timeoutenv = getenv("CHGTIMEOUT"); |
317 if (timeoutenv) | |
318 sscanf(timeoutenv, "%u", &timeoutsec); | |
319 | |
320 for (unsigned int i = 0; !timeoutsec || i < timeoutsec * 100; i++) { | |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
321 hgclient_t *hgc = hgc_open(opts->initsockname); |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
322 if (hgc) { |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
323 debugmsg("rename %s to %s", opts->initsockname, |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
324 opts->sockname); |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
325 int r = rename(opts->initsockname, opts->sockname); |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
326 if (r != 0) |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
327 abortmsgerrno("cannot rename"); |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
328 return hgc; |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
329 } |
28060 | 330 |
331 if (pid > 0) { | |
332 /* collect zombie if child process fails to start */ | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
333 int r = waitpid(pid, &pst, WNOHANG); |
28060 | 334 if (r != 0) |
335 goto cleanup; | |
336 } | |
337 | |
338 nanosleep(&sleepreq, NULL); | |
339 } | |
340 | |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
341 abortmsg("timed out waiting for cmdserver %s", opts->initsockname); |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
342 return NULL; |
28060 | 343 |
344 cleanup: | |
345 if (WIFEXITED(pst)) { | |
28863
6e06fbee9244
chg: server exited with code 0 without being connectable is an error
Jun Wu <quark@fb.com>
parents:
28856
diff
changeset
|
346 if (WEXITSTATUS(pst) == 0) |
6e06fbee9244
chg: server exited with code 0 without being connectable is an error
Jun Wu <quark@fb.com>
parents:
28856
diff
changeset
|
347 abortmsg("could not connect to cmdserver " |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
348 "(exited with status 0)"); |
28477
194a6cd873cd
chg: silently inherit server exit code
Jun Wu <quark@fb.com>
parents:
28455
diff
changeset
|
349 debugmsg("cmdserver exited with status %d", WEXITSTATUS(pst)); |
194a6cd873cd
chg: silently inherit server exit code
Jun Wu <quark@fb.com>
parents:
28455
diff
changeset
|
350 exit(WEXITSTATUS(pst)); |
28060 | 351 } else if (WIFSIGNALED(pst)) { |
352 abortmsg("cmdserver killed by signal %d", WTERMSIG(pst)); | |
353 } else { | |
28851
584e0716c7af
chg: fix spelling in the error message about error waiting for cmdserver
Jun Wu <quark@fb.com>
parents:
28790
diff
changeset
|
354 abortmsg("error while waiting for cmdserver"); |
28060 | 355 } |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
356 return NULL; |
28060 | 357 } |
358 | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
359 /* Connect to a cmdserver. Will start a new server on demand. */ |
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
360 static hgclient_t *connectcmdserver(struct cmdserveropts *opts) |
28060 | 361 { |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
362 const char *sockname = |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
363 opts->redirectsockname[0] ? opts->redirectsockname : opts->sockname; |
28769
222f482930c8
chg: make connect debug message less repetitive
Jun Wu <quark@fb.com>
parents:
28605
diff
changeset
|
364 debugmsg("try connect to %s", sockname); |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
365 hgclient_t *hgc = hgc_open(sockname); |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
366 if (hgc) |
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
367 return hgc; |
28060 | 368 |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
369 /* prevent us from being connected to an outdated server: we were |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
370 * told by a server to redirect to opts->redirectsockname and that |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
371 * address does not work. we do not want to connect to the server |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
372 * again because it will probably tell us the same thing. */ |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
373 if (sockname == opts->redirectsockname) |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
374 unlink(opts->sockname); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
375 |
30620
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30513
diff
changeset
|
376 debugmsg("start cmdserver at %s", opts->initsockname); |
28060 | 377 |
378 pid_t pid = fork(); | |
379 if (pid < 0) | |
380 abortmsg("failed to fork cmdserver process"); | |
381 if (pid == 0) { | |
382 execcmdserver(opts); | |
383 } else { | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
384 hgc = retryconnectcmdserver(opts, pid); |
28060 | 385 } |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
386 |
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
387 return hgc; |
28060 | 388 } |
389 | |
28455 | 390 static void killcmdserver(const struct cmdserveropts *opts) |
28060 | 391 { |
28455 | 392 /* resolve config hash */ |
393 char *resolvedpath = realpath(opts->sockname, NULL); | |
394 if (resolvedpath) { | |
395 unlink(resolvedpath); | |
396 free(resolvedpath); | |
28060 | 397 } |
398 } | |
399 | |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
400 /* Run instructions sent from the server like unlink and set redirect path |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
401 * Return 1 if reconnect is needed, otherwise 0 */ |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
402 static int runinstructions(struct cmdserveropts *opts, const char **insts) |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
403 { |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
404 int needreconnect = 0; |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
405 if (!insts) |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
406 return needreconnect; |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
407 |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
408 assert(insts); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
409 opts->redirectsockname[0] = '\0'; |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
410 const char **pinst; |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
411 for (pinst = insts; *pinst; pinst++) { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
412 debugmsg("instruction: %s", *pinst); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
413 if (strncmp(*pinst, "unlink ", 7) == 0) { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
414 unlink(*pinst + 7); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
415 } else if (strncmp(*pinst, "redirect ", 9) == 0) { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
416 int r = snprintf(opts->redirectsockname, |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
417 sizeof(opts->redirectsockname), "%s", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
418 *pinst + 9); |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
419 if (r < 0 || r >= (int)sizeof(opts->redirectsockname)) |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
420 abortmsg("redirect path is too long (%d)", r); |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
421 needreconnect = 1; |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
422 } else if (strncmp(*pinst, "exit ", 5) == 0) { |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
423 int n = 0; |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
424 if (sscanf(*pinst + 5, "%d", &n) != 1) |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
425 abortmsg("cannot read the exit code"); |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
426 exit(n); |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
427 } else if (strcmp(*pinst, "reconnect") == 0) { |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
428 needreconnect = 1; |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
429 } else { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
430 abortmsg("unknown instruction: %s", *pinst); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
431 } |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
432 } |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
433 return needreconnect; |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
434 } |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
435 |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
436 /* |
45520
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
437 * Test whether the command and the environment is unsupported or not. |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
438 * |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
439 * If any of the stdio file descriptors are not present (rare, but some tools |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
440 * might spawn new processes without stdio instead of redirecting them to the |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
441 * null device), then mark it as not supported because attachio won't work |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
442 * correctly. |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
443 * |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
444 * The command list is not designed to cover all cases. But it's fast, and does |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
445 * not depend on the server. |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
446 */ |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
447 static int isunsupported(int argc, const char *argv[]) |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
448 { |
46177
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45851
diff
changeset
|
449 enum { |
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45851
diff
changeset
|
450 SERVE = 1, |
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45851
diff
changeset
|
451 DAEMON = 2, |
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45851
diff
changeset
|
452 SERVEDAEMON = SERVE | DAEMON, |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
453 }; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
454 unsigned int state = 0; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
455 int i; |
45520
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
456 /* use fcntl to test missing stdio fds */ |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
457 if (fcntl(STDIN_FILENO, F_GETFD) == -1 || |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
458 fcntl(STDOUT_FILENO, F_GETFD) == -1 || |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
459 fcntl(STDERR_FILENO, F_GETFD) == -1) { |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
460 debugmsg("stdio fds are missing"); |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
461 return 1; |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
44995
diff
changeset
|
462 } |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
463 for (i = 0; i < argc; ++i) { |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
464 if (strcmp(argv[i], "--") == 0) |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
465 break; |
44617
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44261
diff
changeset
|
466 /* |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44261
diff
changeset
|
467 * there can be false positives but no false negative |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44261
diff
changeset
|
468 * we cannot assume `serve` will always be first argument |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44261
diff
changeset
|
469 * because global options can be passed before the command name |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44261
diff
changeset
|
470 */ |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44261
diff
changeset
|
471 if (strcmp("serve", argv[i]) == 0) |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
472 state |= SERVE; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
473 else if (strcmp("-d", argv[i]) == 0 || |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
474 strcmp("--daemon", argv[i]) == 0) |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
475 state |= DAEMON; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
476 } |
34531
50788d1ae6cc
chg: just forward --time to command server
Yuya Nishihara <yuya@tcha.org>
parents:
31890
diff
changeset
|
477 return (state & SERVEDAEMON) == SERVEDAEMON; |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
478 } |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
479 |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
480 static void execoriginalhg(const char *argv[]) |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
481 { |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
482 debugmsg("execute original hg"); |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
483 if (execvp(gethgcmd(), (char **)argv) < 0) |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
484 abortmsgerrno("failed to exec original hg"); |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
485 } |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
486 |
28060 | 487 int main(int argc, const char *argv[], const char *envp[]) |
488 { | |
489 if (getenv("CHGDEBUG")) | |
490 enabledebugmsg(); | |
491 | |
28787
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28769
diff
changeset
|
492 if (!getenv("HGPLAIN") && isatty(fileno(stderr))) |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28769
diff
changeset
|
493 enablecolor(); |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28769
diff
changeset
|
494 |
28261 | 495 if (getenv("CHGINTERNALMARK")) |
496 abortmsg("chg started by chg detected.\n" | |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
497 "Please make sure ${HG:-hg} is not a symlink or " |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
498 "wrapper to chg. Alternatively, set $CHGHG to the " |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
499 "path of real hg."); |
28261 | 500 |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
501 if (isunsupported(argc - 1, argv + 1)) |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
502 execoriginalhg(argv); |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
503 |
28060 | 504 struct cmdserveropts opts; |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
505 initcmdserveropts(&opts); |
28060 | 506 setcmdserveropts(&opts); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
507 setcmdserverargs(&opts, argc, argv); |
28060 | 508 |
509 if (argc == 2) { | |
28455 | 510 if (strcmp(argv[1], "--kill-chg-daemon") == 0) { |
511 killcmdserver(&opts); | |
28060 | 512 return 0; |
513 } | |
514 } | |
515 | |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
516 hgclient_t *hgc; |
28358 | 517 size_t retry = 0; |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
518 while (1) { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
519 hgc = connectcmdserver(&opts); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
520 if (!hgc) |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
521 abortmsg("cannot open hg client"); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
522 hgc_setenv(hgc, envp); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
523 const char **insts = hgc_validate(hgc, argv + 1, argc - 1); |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
524 int needreconnect = runinstructions(&opts, insts); |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
525 free(insts); |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
526 if (!needreconnect) |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
527 break; |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
528 hgc_close(hgc); |
28358 | 529 if (++retry > 10) |
530 abortmsg("too many redirections.\n" | |
35959
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
531 "Please make sure %s is not a wrapper which " |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
532 "changes sensitive environment variables " |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
533 "before executing hg. If you have to use a " |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
534 "wrapper, wrap chg instead of hg.", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
535 gethgcmd()); |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
536 } |
28060 | 537 |
30690
e9ec42634ec8
chg: decouple hgclient from setupsignalhandler
Jun Wu <quark@fb.com>
parents:
30689
diff
changeset
|
538 setupsignalhandler(hgc_peerpid(hgc), hgc_peerpgid(hgc)); |
31890 | 539 atexit(waitpager); |
28060 | 540 int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1); |
29369
85a18f3c0bdd
chg: reset signal handlers to default before waiting pager
Yuya Nishihara <yuya@tcha.org>
parents:
29357
diff
changeset
|
541 restoresignalhandler(); |
28060 | 542 hgc_close(hgc); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
543 freecmdserveropts(&opts); |
29344 | 544 |
28060 | 545 return exitcode; |
546 } |