equal
deleted
inserted
replaced
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) |