aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorPaul Eggert2012-10-31 10:27:29 -0700
committerPaul Eggert2012-10-31 10:27:29 -0700
commit322aea6ddf7ec7fd71410d98ec1de69f219aff3e (patch)
tree5efe99d41566350e9793015cde6ebb656e1278e6 /src/sysdep.c
parent220cb2bd70c65041417554cc2dc10edb4a53de5c (diff)
downloademacs-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.c72
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
707static pid_t inherited_pgroup;
708
709void
710init_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. */
723static void
724tcsetpgrp_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. */
740static void
741narrow_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. */
748static void
749widen_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