contrib/chg/chg.c
branchstable
changeset 50431 c2a1f8668606
parent 50430 d06e43cd393f
equal deleted inserted replaced
50430:d06e43cd393f 50431:c2a1f8668606
   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)