Show More
@@ -33,16 +33,13 b' struct cmdserveropts {' | |||||
33 | char sockname[UNIX_PATH_MAX]; |
|
33 | char sockname[UNIX_PATH_MAX]; | |
34 | char initsockname[UNIX_PATH_MAX]; |
|
34 | char initsockname[UNIX_PATH_MAX]; | |
35 | char redirectsockname[UNIX_PATH_MAX]; |
|
35 | char redirectsockname[UNIX_PATH_MAX]; | |
36 | char lockfile[UNIX_PATH_MAX]; |
|
|||
37 | size_t argsize; |
|
36 | size_t argsize; | |
38 | const char **args; |
|
37 | const char **args; | |
39 | int lockfd; |
|
|||
40 | int sockdirfd; |
|
38 | int sockdirfd; | |
41 | }; |
|
39 | }; | |
42 |
|
40 | |||
43 | static void initcmdserveropts(struct cmdserveropts *opts) { |
|
41 | static void initcmdserveropts(struct cmdserveropts *opts) { | |
44 | memset(opts, 0, sizeof(struct cmdserveropts)); |
|
42 | memset(opts, 0, sizeof(struct cmdserveropts)); | |
45 | opts->lockfd = -1; |
|
|||
46 | opts->sockdirfd = -1; |
|
43 | opts->sockdirfd = -1; | |
47 | } |
|
44 | } | |
48 |
|
45 | |||
@@ -50,7 +47,6 b' static void freecmdserveropts(struct cmd' | |||||
50 | free(opts->args); |
|
47 | free(opts->args); | |
51 | opts->args = NULL; |
|
48 | opts->args = NULL; | |
52 | opts->argsize = 0; |
|
49 | opts->argsize = 0; | |
53 | assert(opts->lockfd == -1 && "should be closed by unlockcmdserver()"); |
|
|||
54 | if (opts->sockdirfd >= 0) { |
|
50 | if (opts->sockdirfd >= 0) { | |
55 | close(opts->sockdirfd); |
|
51 | close(opts->sockdirfd); | |
56 | opts->sockdirfd = -1; |
|
52 | opts->sockdirfd = -1; | |
@@ -157,52 +153,15 b' static void setcmdserveropts(struct cmds' | |||||
157 |
|
153 | |||
158 | const char *basename = (envsockname) ? envsockname : sockdir; |
|
154 | const char *basename = (envsockname) ? envsockname : sockdir; | |
159 | const char *sockfmt = (envsockname) ? "%s" : "%s/server"; |
|
155 | const char *sockfmt = (envsockname) ? "%s" : "%s/server"; | |
160 | const char *lockfmt = (envsockname) ? "%s.lock" : "%s/lock"; |
|
|||
161 | r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename); |
|
156 | r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename); | |
162 | if (r < 0 || (size_t)r >= sizeof(opts->sockname)) |
|
157 | if (r < 0 || (size_t)r >= sizeof(opts->sockname)) | |
163 | abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
|
158 | abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); | |
164 | r = snprintf(opts->lockfile, sizeof(opts->lockfile), lockfmt, basename); |
|
|||
165 | if (r < 0 || (size_t)r >= sizeof(opts->lockfile)) |
|
|||
166 | abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
|
|||
167 | r = snprintf(opts->initsockname, sizeof(opts->initsockname), |
|
159 | r = snprintf(opts->initsockname, sizeof(opts->initsockname), | |
168 | "%s.%u", opts->sockname, (unsigned)getpid()); |
|
160 | "%s.%u", opts->sockname, (unsigned)getpid()); | |
169 | if (r < 0 || (size_t)r >= sizeof(opts->initsockname)) |
|
161 | if (r < 0 || (size_t)r >= sizeof(opts->initsockname)) | |
170 | abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); |
|
162 | abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r); | |
171 | } |
|
163 | } | |
172 |
|
164 | |||
173 | /* |
|
|||
174 | * Acquire a file lock that indicates a client is trying to start and connect |
|
|||
175 | * to a server, before executing a command. The lock is released upon exit or |
|
|||
176 | * explicit unlock. Will block if the lock is held by another process. |
|
|||
177 | */ |
|
|||
178 | static void lockcmdserver(struct cmdserveropts *opts) |
|
|||
179 | { |
|
|||
180 | if (opts->lockfd == -1) { |
|
|||
181 | opts->lockfd = open(opts->lockfile, |
|
|||
182 | O_RDWR | O_CREAT | O_NOFOLLOW, 0600); |
|
|||
183 | if (opts->lockfd == -1) |
|
|||
184 | abortmsgerrno("cannot create lock file %s", |
|
|||
185 | opts->lockfile); |
|
|||
186 | fsetcloexec(opts->lockfd); |
|
|||
187 | } |
|
|||
188 | int r = flock(opts->lockfd, LOCK_EX); |
|
|||
189 | if (r == -1) |
|
|||
190 | abortmsgerrno("cannot acquire lock"); |
|
|||
191 | } |
|
|||
192 |
|
||||
193 | /* |
|
|||
194 | * Release the file lock held by calling lockcmdserver. Will do nothing if |
|
|||
195 | * lockcmdserver is not called. |
|
|||
196 | */ |
|
|||
197 | static void unlockcmdserver(struct cmdserveropts *opts) |
|
|||
198 | { |
|
|||
199 | if (opts->lockfd == -1) |
|
|||
200 | return; |
|
|||
201 | flock(opts->lockfd, LOCK_UN); |
|
|||
202 | close(opts->lockfd); |
|
|||
203 | opts->lockfd = -1; |
|
|||
204 | } |
|
|||
205 |
|
||||
206 | static const char *gethgcmd(void) |
|
165 | static const char *gethgcmd(void) | |
207 | { |
|
166 | { | |
208 | static const char *hgcmd = NULL; |
|
167 | static const char *hgcmd = NULL; | |
@@ -308,14 +267,6 b' static hgclient_t *connectcmdserver(stru' | |||||
308 | if (hgc) |
|
267 | if (hgc) | |
309 | return hgc; |
|
268 | return hgc; | |
310 |
|
269 | |||
311 | lockcmdserver(opts); |
|
|||
312 | hgc = hgc_open(sockname); |
|
|||
313 | if (hgc) { |
|
|||
314 | unlockcmdserver(opts); |
|
|||
315 | debugmsg("cmdserver is started by another process"); |
|
|||
316 | return hgc; |
|
|||
317 | } |
|
|||
318 |
|
||||
319 | /* prevent us from being connected to an outdated server: we were |
|
270 | /* prevent us from being connected to an outdated server: we were | |
320 | * told by a server to redirect to opts->redirectsockname and that |
|
271 | * told by a server to redirect to opts->redirectsockname and that | |
321 | * address does not work. we do not want to connect to the server |
|
272 | * address does not work. we do not want to connect to the server | |
@@ -334,7 +285,6 b' static hgclient_t *connectcmdserver(stru' | |||||
334 | hgc = retryconnectcmdserver(opts, pid); |
|
285 | hgc = retryconnectcmdserver(opts, pid); | |
335 | } |
|
286 | } | |
336 |
|
287 | |||
337 | unlockcmdserver(opts); |
|
|||
338 | return hgc; |
|
288 | return hgc; | |
339 | } |
|
289 | } | |
340 |
|
290 |
General Comments 0
You need to be logged in to leave comments.
Login now