contrib/chg/chg.c
changeset 29429 cf99de051385
parent 29370 3ddf4d0c4170
child 29440 009cc6c89d0f
equal deleted inserted replaced
29428:247ea0dfdb94 29429:cf99de051385
   336 		unlink(resolvedpath);
   336 		unlink(resolvedpath);
   337 		free(resolvedpath);
   337 		free(resolvedpath);
   338 	}
   338 	}
   339 }
   339 }
   340 
   340 
       
   341 static pid_t pagerpid = 0;
   341 static pid_t peerpid = 0;
   342 static pid_t peerpid = 0;
   342 
   343 
   343 static void forwardsignal(int sig)
   344 static void forwardsignal(int sig)
   344 {
   345 {
   345 	assert(peerpid > 0);
   346 	assert(peerpid > 0);
   376 		goto error;
   377 		goto error;
   377 	return;
   378 	return;
   378 
   379 
   379 error:
   380 error:
   380 	abortmsgerrno("failed to handle stop signal");
   381 	abortmsgerrno("failed to handle stop signal");
       
   382 }
       
   383 
       
   384 static void handlechildsignal(int sig)
       
   385 {
       
   386 	if (peerpid == 0 || pagerpid == 0)
       
   387 		return;
       
   388 	/* if pager exits, notify the server with SIGPIPE immediately.
       
   389 	 * otherwise the server won't get SIGPIPE if it does not write
       
   390 	 * anything. (issue5278) */
       
   391 	if (waitpid(pagerpid, NULL, WNOHANG) == pagerpid)
       
   392 		kill(peerpid, SIGPIPE);
   381 }
   393 }
   382 
   394 
   383 static void setupsignalhandler(pid_t pid)
   395 static void setupsignalhandler(pid_t pid)
   384 {
   396 {
   385 	if (pid <= 0)
   397 	if (pid <= 0)
   414 		goto error;
   426 		goto error;
   415 	sa.sa_handler = handlestopsignal;
   427 	sa.sa_handler = handlestopsignal;
   416 	sa.sa_flags = SA_RESTART;
   428 	sa.sa_flags = SA_RESTART;
   417 	if (sigaction(SIGTSTP, &sa, NULL) < 0)
   429 	if (sigaction(SIGTSTP, &sa, NULL) < 0)
   418 		goto error;
   430 		goto error;
       
   431 	/* get notified when pager exits */
       
   432 	sa.sa_handler = handlechildsignal;
       
   433 	sa.sa_flags = SA_RESTART;
       
   434 	if (sigaction(SIGCHLD, &sa, NULL) < 0)
       
   435 		goto error;
   419 
   436 
   420 	return;
   437 	return;
   421 
   438 
   422 error:
   439 error:
   423 	abortmsgerrno("failed to set up signal handlers");
   440 	abortmsgerrno("failed to set up signal handlers");
   439 	if (sigaction(SIGWINCH, &sa, NULL) < 0)
   456 	if (sigaction(SIGWINCH, &sa, NULL) < 0)
   440 		goto error;
   457 		goto error;
   441 	if (sigaction(SIGCONT, &sa, NULL) < 0)
   458 	if (sigaction(SIGCONT, &sa, NULL) < 0)
   442 		goto error;
   459 		goto error;
   443 	if (sigaction(SIGTSTP, &sa, NULL) < 0)
   460 	if (sigaction(SIGTSTP, &sa, NULL) < 0)
       
   461 		goto error;
       
   462 	if (sigaction(SIGCHLD, &sa, NULL) < 0)
   444 		goto error;
   463 		goto error;
   445 
   464 
   446 	/* ignore Ctrl+C while shutting down to make pager exits cleanly */
   465 	/* ignore Ctrl+C while shutting down to make pager exits cleanly */
   447 	sa.sa_handler = SIG_IGN;
   466 	sa.sa_handler = SIG_IGN;
   448 	if (sigaction(SIGINT, &sa, NULL) < 0)
   467 	if (sigaction(SIGINT, &sa, NULL) < 0)
   636 				 "wrapper, wrap chg instead of hg.",
   655 				 "wrapper, wrap chg instead of hg.",
   637 				 gethgcmd());
   656 				 gethgcmd());
   638 	}
   657 	}
   639 
   658 
   640 	setupsignalhandler(hgc_peerpid(hgc));
   659 	setupsignalhandler(hgc_peerpid(hgc));
   641 	pid_t pagerpid = setuppager(hgc, argv + 1, argc - 1);
   660 	pagerpid = setuppager(hgc, argv + 1, argc - 1);
   642 	int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
   661 	int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
   643 	restoresignalhandler();
   662 	restoresignalhandler();
   644 	hgc_close(hgc);
   663 	hgc_close(hgc);
   645 	freecmdserveropts(&opts);
   664 	freecmdserveropts(&opts);
   646 	if (pagerpid)
   665 	if (pagerpid)