diff options
| author | Paul Eggert | 2012-10-31 10:27:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-10-31 10:27:29 -0700 |
| commit | 322aea6ddf7ec7fd71410d98ec1de69f219aff3e (patch) | |
| tree | 5efe99d41566350e9793015cde6ebb656e1278e6 /src/sysdep.c | |
| parent | 220cb2bd70c65041417554cc2dc10edb4a53de5c (diff) | |
| download | emacs-322aea6ddf7ec7fd71410d98ec1de69f219aff3e.tar.gz emacs-322aea6ddf7ec7fd71410d98ec1de69f219aff3e.zip | |
Fix crash when using Emacs as commit editor for git.
* callproc.c (setpgrp): Remove macro, as we now use setpgid
and it is configured in conf_post.h.
(Fcall_process): Don't invoke both setsid and setpgid; the former
is enough, if it exists.
* callproc.c (Fcall_process, child_setup):
* process.c (create_process): Use setpgid.
* conf_post.h (setpgid) [!HAVE_SETPGID]: New macro, which substitutes
for the real thing.
* dispnew.c (init_display): Initialize the foreground group
if we are running a tty display.
* emacs.c (main): Do not worry about setpgrp; init_display does it now.
* lisp.h (init_foreground_group): New decl.
* sysdep.c (inherited_pgroup): New static var.
(init_foreground_group, tcsetpgrp_without_stopping)
(narrow_foreground_group, widen_foreground_group): New functions.
(init_sys_modes): Narrow foreground group.
(reset_sys_modes): Widen foreground group.
Fixes: debbugs:12697
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index c7174e91612..63eac5d9e09 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -683,6 +683,75 @@ ignore_sigio (void) | |||
| 683 | } | 683 | } |
| 684 | 684 | ||
| 685 | 685 | ||
| 686 | /* Saving and restoring the process group of Emacs's terminal. */ | ||
| 687 | |||
| 688 | /* The process group of which Emacs was a member when it initially | ||
| 689 | started. | ||
| 690 | |||
| 691 | If Emacs was in its own process group (i.e. inherited_pgroup == | ||
| 692 | getpid ()), then we know we're running under a shell with job | ||
| 693 | control (Emacs would never be run as part of a pipeline). | ||
| 694 | Everything is fine. | ||
| 695 | |||
| 696 | If Emacs was not in its own process group, then we know we're | ||
| 697 | running under a shell (or a caller) that doesn't know how to | ||
| 698 | separate itself from Emacs (like sh). Emacs must be in its own | ||
| 699 | process group in order to receive SIGIO correctly. In this | ||
| 700 | situation, we put ourselves in our own pgroup, forcibly set the | ||
| 701 | tty's pgroup to our pgroup, and make sure to restore and reinstate | ||
| 702 | the tty's pgroup just like any other terminal setting. If | ||
| 703 | inherited_group was not the tty's pgroup, then we'll get a | ||
| 704 | SIGTTmumble when we try to change the tty's pgroup, and a CONT if | ||
| 705 | it goes foreground in the future, which is what should happen. */ | ||
| 706 | |||
| 707 | static pid_t inherited_pgroup; | ||
| 708 | |||
| 709 | void | ||
| 710 | init_foreground_group (void) | ||
| 711 | { | ||
| 712 | pid_t pgrp = EMACS_GETPGRP (0); | ||
| 713 | inherited_pgroup = getpid () == pgrp ? 0 : pgrp; | ||
| 714 | } | ||
| 715 | |||
| 716 | /* Safely set a controlling terminal FD's process group to PGID. | ||
| 717 | If we are not in the foreground already, POSIX requires tcsetpgrp | ||
| 718 | to deliver a SIGTTOU signal, which would stop us. This is an | ||
| 719 | annoyance, so temporarily ignore the signal. | ||
| 720 | |||
| 721 | In practice, platforms lacking SIGTTOU also lack tcsetpgrp, so | ||
| 722 | skip all this unless SIGTTOU is defined. */ | ||
| 723 | static void | ||
| 724 | tcsetpgrp_without_stopping (int fd, pid_t pgid) | ||
| 725 | { | ||
| 726 | #ifdef SIGTTOU | ||
| 727 | signal_handler_t handler; | ||
| 728 | block_input (); | ||
| 729 | handler = signal (SIGTTOU, SIG_IGN); | ||
| 730 | tcsetpgrp (fd, pgid); | ||
| 731 | signal (SIGTTOU, handler); | ||
| 732 | unblock_input (); | ||
| 733 | #endif | ||
| 734 | } | ||
| 735 | |||
| 736 | /* Split off the foreground process group to Emacs alone. When we are | ||
| 737 | in the foreground, but not started in our own process group, | ||
| 738 | redirect the tty device handle FD to point to our own process | ||
| 739 | group. FD must be the file descriptor of the controlling tty. */ | ||
| 740 | static void | ||
| 741 | narrow_foreground_group (int fd) | ||
| 742 | { | ||
| 743 | if (inherited_pgroup && setpgid (0, 0) == 0) | ||
| 744 | tcsetpgrp_without_stopping (fd, getpid ()); | ||
| 745 | } | ||
| 746 | |||
| 747 | /* Set the tty to our original foreground group. */ | ||
| 748 | static void | ||
| 749 | widen_foreground_group (int fd) | ||
| 750 | { | ||
| 751 | if (inherited_pgroup && setpgid (0, inherited_pgroup) == 0) | ||
| 752 | tcsetpgrp_without_stopping (fd, inherited_pgroup); | ||
| 753 | } | ||
| 754 | |||
| 686 | /* Getting and setting emacs_tty structures. */ | 755 | /* Getting and setting emacs_tty structures. */ |
| 687 | 756 | ||
| 688 | /* Set *TC to the parameters associated with the terminal FD. | 757 | /* Set *TC to the parameters associated with the terminal FD. |
| @@ -799,6 +868,8 @@ init_sys_modes (struct tty_display_info *tty_out) | |||
| 799 | if (!tty_out->output) | 868 | if (!tty_out->output) |
| 800 | return; /* The tty is suspended. */ | 869 | return; /* The tty is suspended. */ |
| 801 | 870 | ||
| 871 | narrow_foreground_group (fileno (tty_out->input)); | ||
| 872 | |||
| 802 | if (! tty_out->old_tty) | 873 | if (! tty_out->old_tty) |
| 803 | tty_out->old_tty = xmalloc (sizeof *tty_out->old_tty); | 874 | tty_out->old_tty = xmalloc (sizeof *tty_out->old_tty); |
| 804 | 875 | ||
| @@ -1231,6 +1302,7 @@ reset_sys_modes (struct tty_display_info *tty_out) | |||
| 1231 | dos_ttcooked (); | 1302 | dos_ttcooked (); |
| 1232 | #endif | 1303 | #endif |
| 1233 | 1304 | ||
| 1305 | widen_foreground_group (fileno (tty_out->input)); | ||
| 1234 | } | 1306 | } |
| 1235 | 1307 | ||
| 1236 | #ifdef HAVE_PTYS | 1308 | #ifdef HAVE_PTYS |