Mercurial > hg-stable
annotate contrib/chg/chg.c @ 50248:af9d050f2bb8
rust: box ConfigValueParseError to avoid large result types
clippy emits a warning that all the Result types are way too large
because of HgError includes ConfigValueParseError as one of the variants,
so its size is 136 bytes.
By boxing ConfigValueParseError we're hopefully making everything faster
"for free".
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Mon, 27 Feb 2023 18:24:29 +0000 |
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> | |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
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 | |
30680 | 30 #ifndef PATH_MAX |
31 #define PATH_MAX 4096 | |
28060 | 32 #endif |
33 | |
34 struct cmdserveropts { | |
30680 | 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 | |
35998
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 |
35998
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[] = { |
35998
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 */ |
35998
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]) |
35998
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; |
35998
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 | |
30916 | 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 | |
30683
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30680
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:
30680
diff
changeset
|
149 { |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30680
diff
changeset
|
150 /* by default, put socket file in secure directory |
30684 | 151 * (${XDG_RUNTIME_DIR}/chg, or /${TMPDIR:-tmp}/chg$UID) |
30683
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30680
diff
changeset
|
152 * (permission of socket file may be ignored on some Unices) */ |
30684 | 153 const char *runtimedir = getenv("XDG_RUNTIME_DIR"); |
154 int r; | |
30916 | 155 if (runtimedir && checkruntimedir(runtimedir)) { |
30684 | 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 } | |
30683
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30680
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:
30680
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:
30680
diff
changeset
|
165 } |
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30680
diff
changeset
|
166 |
28060 | 167 static void setcmdserveropts(struct cmdserveropts *opts) |
168 { | |
169 int r; | |
30680 | 170 char sockdir[PATH_MAX]; |
28060 | 171 const char *envsockname = getenv("CHGSOCKNAME"); |
172 if (!envsockname) { | |
30683
4677df6b449a
chg: make "get default sockdir" a separate method
Jun Wu <quark@fb.com>
parents:
30680
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); | |
35998
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()); |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
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:
30522
diff
changeset
|
185 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
28060 | 186 } |
187 | |
45557
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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; |
45557
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45528
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:
45528
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:
45528
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:
45528
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:
45528
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"); |
45557
4c8d9b53b1c7
chg: make is possible to call by default an hg binary located next to chg
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
45528
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:
45528
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[] = { |
47065
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", |
35998
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)); |
37871
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
252 if (opts->args) { |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
253 size_t size = sizeof(char *) * opts->argsize; |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
254 memcpy(argv + baseargvsize, opts->args, size); |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
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 |
44308
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
37871
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:
37871
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:
37871
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:
37871
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:
37871
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:
37871
diff
changeset
|
263 if (setenv("CHGORIG_LC_CTYPE", lc_ctype_env, 1) != 0) { |
45015 | 264 abortmsgerrno("failed to setenv CHGORIG_LC_CTYPE"); |
44308
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
37871
diff
changeset
|
265 } |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
37871
diff
changeset
|
266 } |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
37871
diff
changeset
|
267 |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
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:
45557
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:
45557
diff
changeset
|
270 if (dp != NULL) { |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
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:
45557
diff
changeset
|
272 struct dirent *de; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
273 while ((de = readdir(dp))) { |
45771
81da6feb5000
chg: reset errno prior to calling strtol()
Yuya Nishihara <yuya@tcha.org>
parents:
45770
diff
changeset
|
274 errno = 0; |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
275 char *end; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
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:
45557
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:
45557
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:
45557
diff
changeset
|
279 continue; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
280 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
281 if (errno == ERANGE) { |
45768 | 282 debugmsg("tried to parse %s, but range error " |
283 "occurred", | |
284 de->d_name); | |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
285 continue; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
286 } |
45770
9534de20358f
chg: do not close dir fd while iterating
Yuya Nishihara <yuya@tcha.org>
parents:
45769
diff
changeset
|
287 if (fd_value > STDERR_FILENO && fd_value != dirfd(dp)) { |
45769
731ea8fa1f11
chg: show debug message for each fd to be closed
Yuya Nishihara <yuya@tcha.org>
parents:
45768
diff
changeset
|
288 debugmsg("closing fd %ld", fd_value); |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
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:
45557
diff
changeset
|
290 if (res) { |
45768 | 291 debugmsg("tried to close fd %ld: %d " |
292 "(errno: %d)", | |
293 fd_value, res, errno); | |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
294 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
295 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
296 } |
45770
9534de20358f
chg: do not close dir fd while iterating
Yuya Nishihara <yuya@tcha.org>
parents:
45769
diff
changeset
|
297 closedir(dp); |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
298 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
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 | |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
313 debugmsg("try connect to %s repeatedly", opts->initsockname); |
29345 | 314 |
35998
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++) { | |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
321 hgclient_t *hgc = hgc_open(opts->initsockname); |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
322 if (hgc) { |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
323 debugmsg("rename %s to %s", opts->initsockname, |
35998
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
324 opts->sockname); |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
325 int r = rename(opts->initsockname, opts->sockname); |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
326 if (r != 0) |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
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; |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
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 | |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
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 " |
35998
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 { |
35998
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 |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
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, |
35998
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 /* |
45528
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
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:
45015
diff
changeset
|
438 * |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
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:
45015
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:
45015
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:
45015
diff
changeset
|
442 * correctly. |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
443 * |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
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:
45015
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:
45771
diff
changeset
|
449 enum { |
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45771
diff
changeset
|
450 SERVE = 1, |
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45771
diff
changeset
|
451 DAEMON = 2, |
0c320e6032f1
chg: format code by clang-format version 11.0.1-+rc1-1
Yuya Nishihara <yuya@tcha.org>
parents:
45771
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; |
45528
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
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:
45015
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:
45015
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:
45015
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:
45015
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:
45015
diff
changeset
|
461 return 1; |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
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; |
44621
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44308
diff
changeset
|
466 /* |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44308
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:
44308
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:
44308
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:
44308
diff
changeset
|
470 */ |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44308
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 || |
35998
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" | |
35998
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" | |
35998
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 } |