equal
deleted
inserted
replaced
232 hgcmd = (HGPATH); |
232 hgcmd = (HGPATH); |
233 #else |
233 #else |
234 hgcmd = "hg"; |
234 hgcmd = "hg"; |
235 #endif |
235 #endif |
236 } |
236 } |
237 /* Set $CHGHG to the path to the seleted hg executable if it wasn't |
|
238 * already set. This has the effect of ensuring that a new command |
|
239 * server will be spawned if the existing command server is running from |
|
240 * an executable at a different path. */ |
|
241 if (setenv("CHGHG", hgcmd, 1) != 0) |
|
242 abortmsgerrno("failed to setenv"); |
|
243 return hgcmd; |
237 return hgcmd; |
244 } |
238 } |
245 |
239 |
246 static void execcmdserver(const char *hgcmd, const struct cmdserveropts *opts) |
240 static void execcmdserver(const struct cmdserveropts *opts) |
247 { |
241 { |
248 |
242 const char *hgcmd = gethgcmd(); |
249 const char *baseargv[] = { |
243 const char *baseargv[] = { |
250 hgcmd, "serve", "--no-profile", "--cmdserver", |
244 hgcmd, "serve", "--no-profile", "--cmdserver", |
251 "chgunix", "--address", opts->initsockname, "--daemon-postexec", |
245 "chgunix", "--address", opts->initsockname, "--daemon-postexec", |
252 "chdir:/", |
246 "chdir:/", |
253 }; |
247 }; |
380 if (sockname == opts->redirectsockname) |
374 if (sockname == opts->redirectsockname) |
381 unlink(opts->sockname); |
375 unlink(opts->sockname); |
382 |
376 |
383 debugmsg("start cmdserver at %s", opts->initsockname); |
377 debugmsg("start cmdserver at %s", opts->initsockname); |
384 |
378 |
385 /* Get the path to the hg executable before we fork because this |
|
386 * function might update the environment, and we want this to be |
|
387 * reflected in both the parent and child processes. */ |
|
388 const char *hgcmd = gethgcmd(); |
|
389 |
|
390 pid_t pid = fork(); |
379 pid_t pid = fork(); |
391 if (pid < 0) |
380 if (pid < 0) |
392 abortmsg("failed to fork cmdserver process"); |
381 abortmsg("failed to fork cmdserver process"); |
393 if (pid == 0) { |
382 if (pid == 0) { |
394 execcmdserver(hgcmd, opts); |
383 execcmdserver(opts); |
395 } else { |
384 } else { |
396 hgc = retryconnectcmdserver(opts, pid); |
385 hgc = retryconnectcmdserver(opts, pid); |
397 } |
386 } |
398 |
387 |
399 return hgc; |
388 return hgc; |
523 killcmdserver(&opts); |
512 killcmdserver(&opts); |
524 return 0; |
513 return 0; |
525 } |
514 } |
526 } |
515 } |
527 |
516 |
|
517 /* Set $CHGHG to the path of the hg executable we intend to use. This |
|
518 * is a no-op if $CHGHG was expliclty specified, but otherwise this |
|
519 * ensures that we will spawn a new command server if we connect to an |
|
520 * existing one running from a different executable. This should only |
|
521 * only be needed when chg is built with HGPATHREL since otherwise the |
|
522 * hg executable used when CHGHG is absent should be deterministic. |
|
523 * */ |
|
524 if (setenv("CHGHG", gethgcmd(), 1) != 0) |
|
525 abortmsgerrno("failed to setenv"); |
|
526 |
528 hgclient_t *hgc; |
527 hgclient_t *hgc; |
529 size_t retry = 0; |
528 size_t retry = 0; |
530 while (1) { |
529 while (1) { |
531 hgc = connectcmdserver(&opts); |
530 hgc = connectcmdserver(&opts); |
532 if (!hgc) |
531 if (!hgc) |