Mercurial > hg-stable
annotate contrib/chg/chg.c @ 45769:731ea8fa1f11 stable
chg: show debug message for each fd to be closed
It helps debugging. The number of file descriptors should be small in most
cases, so the console output wouldn't get bloated even with CHG_DEBUG=1.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Tue, 03 Nov 2020 11:12:25 +0900 |
parents | 41aaf960dc00 |
children | 9534de20358f |
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[] = { |
35998
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
243 hgcmd, |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
244 "serve", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
245 "--cmdserver", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
246 "chgunix", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
247 "--address", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
248 opts->initsockname, |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
249 "--daemon-postexec", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
250 "chdir:/", |
28060 | 251 }; |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
252 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
|
253 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
|
254 |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
255 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
|
256 memcpy(argv, baseargv, sizeof(baseargv)); |
37871
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
257 if (opts->args) { |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
258 size_t size = sizeof(char *) * opts->argsize; |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
259 memcpy(argv + baseargvsize, opts->args, size); |
3c84493556db
chg: fix an undefined behavior about memcpy
Jun Wu <quark@fb.com>
parents:
35998
diff
changeset
|
260 } |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
261 argv[argsize - 1] = NULL; |
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
262 |
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
|
263 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
|
264 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
|
265 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
|
266 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
|
267 } 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
|
268 if (setenv("CHGORIG_LC_CTYPE", lc_ctype_env, 1) != 0) { |
45015 | 269 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
|
270 } |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
37871
diff
changeset
|
271 } |
04a3ae7aba14
chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents:
37871
diff
changeset
|
272 |
45767
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
273 /* 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
|
274 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
|
275 if (dp != NULL) { |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
276 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
|
277 struct dirent *de; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
278 while ((de = readdir(dp))) { |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
279 char *end; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
280 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
|
281 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
|
282 /* 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
|
283 continue; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
284 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
285 if (errno == ERANGE) { |
45768 | 286 debugmsg("tried to parse %s, but range error " |
287 "occurred", | |
288 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
|
289 continue; |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
290 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
291 if (fd_value > STDERR_FILENO) { |
45769
731ea8fa1f11
chg: show debug message for each fd to be closed
Yuya Nishihara <yuya@tcha.org>
parents:
45768
diff
changeset
|
292 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
|
293 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
|
294 if (res) { |
45768 | 295 debugmsg("tried to close fd %ld: %d " |
296 "(errno: %d)", | |
297 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
|
298 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
299 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
300 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
301 } |
8711dc13474c
chg: close file descriptors when starting the daemon
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
45557
diff
changeset
|
302 |
28261 | 303 if (putenv("CHGINTERNALMARK=") != 0) |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
304 abortmsgerrno("failed to putenv"); |
28060 | 305 if (execvp(hgcmd, (char **)argv) < 0) |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
306 abortmsgerrno("failed to exec cmdserver"); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
307 free(argv); |
28060 | 308 } |
309 | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
310 /* 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
|
311 static hgclient_t *retryconnectcmdserver(struct cmdserveropts *opts, pid_t pid) |
28060 | 312 { |
313 static const struct timespec sleepreq = {0, 10 * 1000000}; | |
314 int pst = 0; | |
315 | |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
316 debugmsg("try connect to %s repeatedly", opts->initsockname); |
29345 | 317 |
35998
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
318 unsigned int timeoutsec = 60; /* default: 60 seconds */ |
29345 | 319 const char *timeoutenv = getenv("CHGTIMEOUT"); |
320 if (timeoutenv) | |
321 sscanf(timeoutenv, "%u", &timeoutsec); | |
322 | |
323 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
|
324 hgclient_t *hgc = hgc_open(opts->initsockname); |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
325 if (hgc) { |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
326 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
|
327 opts->sockname); |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
328 int r = rename(opts->initsockname, opts->sockname); |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
329 if (r != 0) |
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
330 abortmsgerrno("cannot rename"); |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
331 return hgc; |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
332 } |
28060 | 333 |
334 if (pid > 0) { | |
335 /* 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
|
336 int r = waitpid(pid, &pst, WNOHANG); |
28060 | 337 if (r != 0) |
338 goto cleanup; | |
339 } | |
340 | |
341 nanosleep(&sleepreq, NULL); | |
342 } | |
343 | |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
344 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
|
345 return NULL; |
28060 | 346 |
347 cleanup: | |
348 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
|
349 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
|
350 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
|
351 "(exited with status 0)"); |
28477
194a6cd873cd
chg: silently inherit server exit code
Jun Wu <quark@fb.com>
parents:
28455
diff
changeset
|
352 debugmsg("cmdserver exited with status %d", WEXITSTATUS(pst)); |
194a6cd873cd
chg: silently inherit server exit code
Jun Wu <quark@fb.com>
parents:
28455
diff
changeset
|
353 exit(WEXITSTATUS(pst)); |
28060 | 354 } else if (WIFSIGNALED(pst)) { |
355 abortmsg("cmdserver killed by signal %d", WTERMSIG(pst)); | |
356 } else { | |
28851
584e0716c7af
chg: fix spelling in the error message about error waiting for cmdserver
Jun Wu <quark@fb.com>
parents:
28790
diff
changeset
|
357 abortmsg("error while waiting for cmdserver"); |
28060 | 358 } |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
359 return NULL; |
28060 | 360 } |
361 | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
362 /* 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
|
363 static hgclient_t *connectcmdserver(struct cmdserveropts *opts) |
28060 | 364 { |
35998
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
365 const char *sockname = |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
366 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
|
367 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
|
368 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
|
369 if (hgc) |
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
370 return hgc; |
28060 | 371 |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
372 /* 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
|
373 * 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
|
374 * 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
|
375 * 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
|
376 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
|
377 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
|
378 |
30625
937c52f06709
chg: start server at a unique address
Jun Wu <quark@fb.com>
parents:
30522
diff
changeset
|
379 debugmsg("start cmdserver at %s", opts->initsockname); |
28060 | 380 |
381 pid_t pid = fork(); | |
382 if (pid < 0) | |
383 abortmsg("failed to fork cmdserver process"); | |
384 if (pid == 0) { | |
385 execcmdserver(opts); | |
386 } else { | |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
387 hgc = retryconnectcmdserver(opts, pid); |
28060 | 388 } |
28196
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
389 |
87de4a22e8c2
chg: hold a lock file before connected to server
Jun Wu <quark@fb.com>
parents:
28194
diff
changeset
|
390 return hgc; |
28060 | 391 } |
392 | |
28455 | 393 static void killcmdserver(const struct cmdserveropts *opts) |
28060 | 394 { |
28455 | 395 /* resolve config hash */ |
396 char *resolvedpath = realpath(opts->sockname, NULL); | |
397 if (resolvedpath) { | |
398 unlink(resolvedpath); | |
399 free(resolvedpath); | |
28060 | 400 } |
401 } | |
402 | |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
403 /* 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
|
404 * 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
|
405 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
|
406 { |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
407 int needreconnect = 0; |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
408 if (!insts) |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
409 return needreconnect; |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
410 |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
411 assert(insts); |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
412 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
|
413 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
|
414 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
|
415 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
|
416 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
|
417 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
|
418 } 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
|
419 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
|
420 sizeof(opts->redirectsockname), "%s", |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
421 *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
|
422 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
|
423 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
|
424 needreconnect = 1; |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
425 } else if (strncmp(*pinst, "exit ", 5) == 0) { |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
426 int n = 0; |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
427 if (sscanf(*pinst + 5, "%d", &n) != 1) |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
428 abortmsg("cannot read the exit code"); |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28477
diff
changeset
|
429 exit(n); |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
430 } else if (strcmp(*pinst, "reconnect") == 0) { |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
431 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
|
432 } else { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
433 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
|
434 } |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
435 } |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
436 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
|
437 } |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
438 |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
439 /* |
45528
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
440 * 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
|
441 * |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
442 * 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
|
443 * 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
|
444 * 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
|
445 * correctly. |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
446 * |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
447 * 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
|
448 * 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
|
449 */ |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
450 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
|
451 { |
35998
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
452 enum { SERVE = 1, |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
453 DAEMON = 2, |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
454 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
|
455 }; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
456 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
|
457 int i; |
45528
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
458 /* 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
|
459 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
|
460 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
|
461 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
|
462 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
|
463 return 1; |
5eee6f4f3d0d
chg: fallback to original hg if stdio fds are missing
Jun Wu <quark@fb.com>
parents:
45015
diff
changeset
|
464 } |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
465 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
|
466 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
|
467 break; |
44621
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44308
diff
changeset
|
468 /* |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44308
diff
changeset
|
469 * 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
|
470 * 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
|
471 * 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
|
472 */ |
1e459ac4cb48
chg: be stricter about checking invocation of `serve` command
Pulkit Goyal <7895pulkit@gmail.com>
parents:
44308
diff
changeset
|
473 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
|
474 state |= SERVE; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
475 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
|
476 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
|
477 state |= DAEMON; |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
478 } |
34531
50788d1ae6cc
chg: just forward --time to command server
Yuya Nishihara <yuya@tcha.org>
parents:
31890
diff
changeset
|
479 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
|
480 } |
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 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
|
483 { |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
484 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
|
485 if (execvp(gethgcmd(), (char **)argv) < 0) |
28789
7f6e0a15189b
chg: replace abortmsg showing errno with abortmsgerrno
Jun Wu <quark@fb.com>
parents:
28787
diff
changeset
|
486 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
|
487 } |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
488 |
28060 | 489 int main(int argc, const char *argv[], const char *envp[]) |
490 { | |
491 if (getenv("CHGDEBUG")) | |
492 enabledebugmsg(); | |
493 | |
28787
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28769
diff
changeset
|
494 if (!getenv("HGPLAIN") && isatty(fileno(stderr))) |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28769
diff
changeset
|
495 enablecolor(); |
ea86cdcd9b50
chg: use color in debug/error messages conditionally
Jun Wu <quark@fb.com>
parents:
28769
diff
changeset
|
496 |
28261 | 497 if (getenv("CHGINTERNALMARK")) |
498 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
|
499 "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
|
500 "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
|
501 "path of real hg."); |
28261 | 502 |
28260
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
503 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
|
504 execoriginalhg(argv); |
0a17cfbe5429
chg: fallback to original hg for some unsupported commands or flags
Jun Wu <quark@fb.com>
parents:
28237
diff
changeset
|
505 |
28060 | 506 struct cmdserveropts opts; |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
507 initcmdserveropts(&opts); |
28060 | 508 setcmdserveropts(&opts); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
509 setcmdserverargs(&opts, argc, argv); |
28060 | 510 |
511 if (argc == 2) { | |
28455 | 512 if (strcmp(argv[1], "--kill-chg-daemon") == 0) { |
513 killcmdserver(&opts); | |
28060 | 514 return 0; |
515 } | |
516 } | |
517 | |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
518 hgclient_t *hgc; |
28358 | 519 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
|
520 while (1) { |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
521 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
|
522 if (!hgc) |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
523 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
|
524 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
|
525 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
|
526 int needreconnect = runinstructions(&opts, insts); |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
527 free(insts); |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
528 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
|
529 break; |
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
530 hgc_close(hgc); |
28358 | 531 if (++retry > 10) |
532 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
|
533 "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
|
534 "changes sensitive environment variables " |
9724f54923ec
chg: enable clang-format on all .c and .h files
Augie Fackler <augie@google.com>
parents:
34531
diff
changeset
|
535 "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
|
536 "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
|
537 gethgcmd()); |
28357
2f0f352d4196
chg: use validate to make sure the server is up to date
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
538 } |
28060 | 539 |
30690
e9ec42634ec8
chg: decouple hgclient from setupsignalhandler
Jun Wu <quark@fb.com>
parents:
30689
diff
changeset
|
540 setupsignalhandler(hgc_peerpid(hgc), hgc_peerpgid(hgc)); |
31890 | 541 atexit(waitpager); |
28060 | 542 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
|
543 restoresignalhandler(); |
28060 | 544 hgc_close(hgc); |
28167
66f6dad20c19
chg: pass sensitive command line flags to server
Jun Wu <quark@fb.com>
parents:
28086
diff
changeset
|
545 freecmdserveropts(&opts); |
29344 | 546 |
28060 | 547 return exitcode; |
548 } |