aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2012-10-31 10:27:29 -0700
committerPaul Eggert2012-10-31 10:27:29 -0700
commit322aea6ddf7ec7fd71410d98ec1de69f219aff3e (patch)
tree5efe99d41566350e9793015cde6ebb656e1278e6
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
-rw-r--r--src/ChangeLog21
-rw-r--r--src/callproc.c23
-rw-r--r--src/conf_post.h8
-rw-r--r--src/dispnew.c2
-rw-r--r--src/emacs.c13
-rw-r--r--src/lisp.h1
-rw-r--r--src/process.c10
-rw-r--r--src/sysdep.c72
8 files changed, 115 insertions, 35 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4edb3a7007b..4dc18b6909b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,24 @@
12012-10-31 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix crash when using Emacs as commit editor for git (Bug#12697).
4 * callproc.c (setpgrp): Remove macro, as we now use setpgid
5 and it is configured in conf_post.h.
6 (Fcall_process): Don't invoke both setsid and setpgid; the former
7 is enough, if it exists.
8 * callproc.c (Fcall_process, child_setup):
9 * process.c (create_process): Use setpgid.
10 * conf_post.h (setpgid) [!HAVE_SETPGID]: New macro, which substitutes
11 for the real thing.
12 * dispnew.c (init_display): Initialize the foreground group
13 if we are running a tty display.
14 * emacs.c (main): Do not worry about setpgrp; init_display does it now.
15 * lisp.h (init_foreground_group): New decl.
16 * sysdep.c (inherited_pgroup): New static var.
17 (init_foreground_group, tcsetpgrp_without_stopping)
18 (narrow_foreground_group, widen_foreground_group): New functions.
19 (init_sys_modes): Narrow foreground group.
20 (reset_sys_modes): Widen foreground group.
21
12012-10-31 Michael Albinus <michael.albinus@gmx.de> 222012-10-31 Michael Albinus <michael.albinus@gmx.de>
2 23
3 * dbusbind.c: Fix cut'n'waste error. Use HAVE_DBUS_VALIDATE_INTERFACE. 24 * dbusbind.c: Fix cut'n'waste error. Use HAVE_DBUS_VALIDATE_INTERFACE.
diff --git a/src/callproc.c b/src/callproc.c
index b33882e54c2..c236f22fc86 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -64,13 +64,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
64#include "nsterm.h" 64#include "nsterm.h"
65#endif 65#endif
66 66
67#ifdef HAVE_SETPGID
68#if !defined (USG)
69#undef setpgrp
70#define setpgrp setpgid
71#endif
72#endif
73
74/* Pattern used by call-process-region to make temp files. */ 67/* Pattern used by call-process-region to make temp files. */
75static Lisp_Object Vtemp_file_name_pattern; 68static Lisp_Object Vtemp_file_name_pattern;
76 69
@@ -618,14 +611,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
618 { 611 {
619 if (fd[0] >= 0) 612 if (fd[0] >= 0)
620 emacs_close (fd[0]); 613 emacs_close (fd[0]);
614
621#ifdef HAVE_SETSID 615#ifdef HAVE_SETSID
622 setsid (); 616 setsid ();
623#endif
624#if defined (USG)
625 setpgrp ();
626#else 617#else
627 setpgrp (pid, pid); 618 setpgid (0, 0);
628#endif /* USG */ 619#endif
629 620
630 /* Emacs ignores SIGPIPE, but the child should not. */ 621 /* Emacs ignores SIGPIPE, but the child should not. */
631 signal (SIGPIPE, SIG_DFL); 622 signal (SIGPIPE, SIG_DFL);
@@ -1295,13 +1286,9 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1295 if (err != in && err != out) 1286 if (err != in && err != out)
1296 emacs_close (err); 1287 emacs_close (err);
1297 1288
1298#if defined (USG) 1289#if defined HAVE_SETPGID || ! (defined USG && defined SETPGRP_RELEASES_CTTY)
1299#ifndef SETPGRP_RELEASES_CTTY 1290 setpgid (pid, pid);
1300 setpgrp (); /* No arguments but equivalent in this case */
1301#endif 1291#endif
1302#else /* not USG */
1303 setpgrp (pid, pid);
1304#endif /* not USG */
1305 1292
1306 /* setpgrp_of_tty is incorrect here; it uses input_fd. */ 1293 /* setpgrp_of_tty is incorrect here; it uses input_fd. */
1307 tcsetpgrp (0, pid); 1294 tcsetpgrp (0, pid);
diff --git a/src/conf_post.h b/src/conf_post.h
index aa008107ba6..6056821d4a7 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -112,6 +112,14 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */
112#endif 112#endif
113/* End of gnulib-related stuff. */ 113/* End of gnulib-related stuff. */
114 114
115#ifndef HAVE_SETPGID
116# ifdef USG
117# define setpgid(pid, pgid) setpgrp ()
118# else
119# define setpgid(pid, pgid) setpgrp (pid, pgid)
120# endif
121#endif
122
115/* Define one of these for easier conditionals. */ 123/* Define one of these for easier conditionals. */
116#ifdef HAVE_X_WINDOWS 124#ifdef HAVE_X_WINDOWS
117/* We need a little extra space, see ../../lisp/loadup.el and the 125/* We need a little extra space, see ../../lisp/loadup.el and the
diff --git a/src/dispnew.c b/src/dispnew.c
index fa24408aa43..9f0e22fcdcb 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6283,6 +6283,8 @@ init_display (void)
6283 struct terminal *t; 6283 struct terminal *t;
6284 struct frame *f = XFRAME (selected_frame); 6284 struct frame *f = XFRAME (selected_frame);
6285 6285
6286 init_foreground_group ();
6287
6286 /* Open a display on the controlling tty. */ 6288 /* Open a display on the controlling tty. */
6287 t = init_tty (0, terminal_type, 1); /* Errors are fatal. */ 6289 t = init_tty (0, terminal_type, 1); /* Errors are fatal. */
6288 6290
diff --git a/src/emacs.c b/src/emacs.c
index 7f3228641ae..98e3f11f0cb 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1091,19 +1091,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1091#endif /* DOS_NT */ 1091#endif /* DOS_NT */
1092 } 1092 }
1093 1093
1094#if defined (HAVE_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
1094 if (! noninteractive) 1095 if (! noninteractive)
1095 { 1096 {
1096#if defined (USG5) && defined (INTERRUPT_INPUT) 1097 extern void malloc_enable_thread (void);
1097 setpgrp ();
1098#endif
1099#if defined (HAVE_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
1100 {
1101 extern void malloc_enable_thread (void);
1102 1098
1103 malloc_enable_thread (); 1099 malloc_enable_thread ();
1104 }
1105#endif
1106 } 1100 }
1101#endif
1107 1102
1108 init_signals (dumping); 1103 init_signals (dumping);
1109 1104
diff --git a/src/lisp.h b/src/lisp.h
index 4cf8fef0de3..3ec188b67c7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3474,6 +3474,7 @@ struct terminal;
3474extern char *get_current_dir_name (void); 3474extern char *get_current_dir_name (void);
3475#endif 3475#endif
3476extern void stuff_char (char c); 3476extern void stuff_char (char c);
3477extern void init_foreground_group (void);
3477extern void init_sigio (int); 3478extern void init_sigio (int);
3478extern void sys_subshell (void); 3479extern void sys_subshell (void);
3479extern void sys_suspend (void); 3480extern void sys_suspend (void);
diff --git a/src/process.c b/src/process.c
index 307e82819d6..77e99ead01f 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1759,12 +1759,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1759#endif 1759#endif
1760 } 1760 }
1761#else /* not HAVE_SETSID */ 1761#else /* not HAVE_SETSID */
1762#ifdef USG 1762 /* It's very important to call setpgid here and no time
1763 /* It's very important to call setpgrp here and no time
1764 afterwards. Otherwise, we lose our controlling tty which 1763 afterwards. Otherwise, we lose our controlling tty which
1765 is set when we open the pty. */ 1764 is set when we open the pty. */
1766 setpgrp (); 1765 setpgid (0, 0);
1767#endif /* USG */
1768#endif /* not HAVE_SETSID */ 1766#endif /* not HAVE_SETSID */
1769#if defined (LDISC1) 1767#if defined (LDISC1)
1770 if (pty_flag && xforkin >= 0) 1768 if (pty_flag && xforkin >= 0)
@@ -1802,11 +1800,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1802 /* In order to get a controlling terminal on some versions 1800 /* In order to get a controlling terminal on some versions
1803 of BSD, it is necessary to put the process in pgrp 0 1801 of BSD, it is necessary to put the process in pgrp 0
1804 before it opens the terminal. */ 1802 before it opens the terminal. */
1805#ifdef HAVE_SETPGID
1806 setpgid (0, 0); 1803 setpgid (0, 0);
1807#else
1808 setpgrp (0, 0);
1809#endif
1810#endif 1804#endif
1811 } 1805 }
1812#endif /* TIOCNOTTY */ 1806#endif /* TIOCNOTTY */
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