From: Paul Eggert <eggert@cs.ucla.edu>
To: 12697@debbugs.gnu.org
Cc: Matthew Leach <matthew@mattleach.net>,
Andreas Schwab <schwab@linux-m68k.org>
Subject: bug#12697: Emacs crashes when using it as the commit editor for git
Date: Fri, 26 Oct 2012 22:31:21 -0700 [thread overview]
Message-ID: <508B71A9.40509@cs.ucla.edu> (raw)
In-Reply-To: <87vce38tqp.fsf@matt-laptop.i-did-not-set--mail-host-address--so-tickle-me>
[-- Attachment #1: Type: text/plain, Size: 391 bytes --]
I tried Andreas's suggestion of disabling ISIG, but
this didn't work on Solaris, and it doesn't look like
it'd work on any host where USABLE_SIGIO is false.
Instead, how about the attached patch? It reenables
the BSD_PGRPS idea, although reimplemented, as the old
code can't easily be resurrected as-is. I haven't
thought about how this affects the Windows port, so
I'll CC: this to Eli.
[-- Attachment #2: git-commit.txt --]
[-- Type: text/plain, Size: 8107 bytes --]
=== modified file 'src/ChangeLog'
--- src/ChangeLog 2012-10-26 09:46:46 +0000
+++ src/ChangeLog 2012-10-27 05:22:54 +0000
@@ -1,3 +1,24 @@
+2012-10-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix crash when using Emacs as commit editor for git (Bug#12697).
+ * 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.
+
2012-10-26 Eli Zaretskii <eliz@gnu.org>
* w32fns.c (w32_wnd_proc) <WM_MOUSEMOVE>: Don't enable tracking of
=== modified file 'src/callproc.c'
--- src/callproc.c 2012-10-19 19:25:18 +0000
+++ src/callproc.c 2012-10-27 05:22:54 +0000
@@ -64,13 +64,6 @@
#include "nsterm.h"
#endif
-#ifdef HAVE_SETPGID
-#if !defined (USG)
-#undef setpgrp
-#define setpgrp setpgid
-#endif
-#endif
-
/* Pattern used by call-process-region to make temp files. */
static Lisp_Object Vtemp_file_name_pattern;
@@ -618,14 +611,12 @@
{
if (fd[0] >= 0)
emacs_close (fd[0]);
+
#ifdef HAVE_SETSID
setsid ();
+#else
+ setpgid (0, 0);
#endif
-#if defined (USG)
- setpgrp ();
-#else
- setpgrp (pid, pid);
-#endif /* USG */
/* Emacs ignores SIGPIPE, but the child should not. */
signal (SIGPIPE, SIG_DFL);
@@ -1295,13 +1286,9 @@
if (err != in && err != out)
emacs_close (err);
-#if defined (USG)
-#ifndef SETPGRP_RELEASES_CTTY
- setpgrp (); /* No arguments but equivalent in this case */
+#if defined HAVE_SETPGID || ! (defined USG && defined SETPGRP_RELEASES_CTTY)
+ setpgid (pid, pid);
#endif
-#else /* not USG */
- setpgrp (pid, pid);
-#endif /* not USG */
/* setpgrp_of_tty is incorrect here; it uses input_fd. */
tcsetpgrp (0, pid);
=== modified file 'src/conf_post.h'
--- src/conf_post.h 2012-10-19 19:25:18 +0000
+++ src/conf_post.h 2012-10-27 05:07:17 +0000
@@ -112,6 +112,14 @@
#endif
/* End of gnulib-related stuff. */
+#ifndef HAVE_SETPGID
+# ifdef USG
+# define setpgid(pid, pgid) setpgrp ()
+# else
+# define setpgid(pid, pgid) setpgrp (pid, pgid)
+# endif
+#endif
+
/* Define one of these for easier conditionals. */
#ifdef HAVE_X_WINDOWS
/* We need a little extra space, see ../../lisp/loadup.el and the
=== modified file 'src/dispnew.c'
--- src/dispnew.c 2012-10-17 19:02:44 +0000
+++ src/dispnew.c 2012-10-27 05:07:17 +0000
@@ -6283,6 +6283,8 @@
struct terminal *t;
struct frame *f = XFRAME (selected_frame);
+ init_foreground_group ();
+
/* Open a display on the controlling tty. */
t = init_tty (0, terminal_type, 1); /* Errors are fatal. */
=== modified file 'src/emacs.c'
--- src/emacs.c 2012-10-25 04:35:39 +0000
+++ src/emacs.c 2012-10-27 05:07:17 +0000
@@ -1091,19 +1091,14 @@
#endif /* DOS_NT */
}
- if (! noninteractive)
- {
-#if defined (USG5) && defined (INTERRUPT_INPUT)
- setpgrp ();
-#endif
#if defined (HAVE_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
- {
- extern void malloc_enable_thread (void);
+ if (! noninteractive)
+ {
+ extern void malloc_enable_thread (void);
- malloc_enable_thread ();
- }
+ malloc_enable_thread ();
+ }
#endif
- }
init_signals (dumping);
=== modified file 'src/lisp.h'
--- src/lisp.h 2012-10-21 07:23:34 +0000
+++ src/lisp.h 2012-10-27 05:07:17 +0000
@@ -3474,6 +3474,7 @@
extern char *get_current_dir_name (void);
#endif
extern void stuff_char (char c);
+extern void init_foreground_group (void);
extern void init_sigio (int);
extern void sys_subshell (void);
extern void sys_suspend (void);
=== modified file 'src/process.c'
--- src/process.c 2012-10-19 19:25:18 +0000
+++ src/process.c 2012-10-27 05:07:17 +0000
@@ -1759,12 +1759,10 @@
#endif
}
#else /* not HAVE_SETSID */
-#ifdef USG
- /* It's very important to call setpgrp here and no time
+ /* It's very important to call setpgid here and no time
afterwards. Otherwise, we lose our controlling tty which
is set when we open the pty. */
- setpgrp ();
-#endif /* USG */
+ setpgid (0, 0);
#endif /* not HAVE_SETSID */
#if defined (LDISC1)
if (pty_flag && xforkin >= 0)
@@ -1802,11 +1800,7 @@
/* In order to get a controlling terminal on some versions
of BSD, it is necessary to put the process in pgrp 0
before it opens the terminal. */
-#ifdef HAVE_SETPGID
setpgid (0, 0);
-#else
- setpgrp (0, 0);
-#endif
#endif
}
#endif /* TIOCNOTTY */
=== modified file 'src/sysdep.c'
--- src/sysdep.c 2012-10-25 04:35:39 +0000
+++ src/sysdep.c 2012-10-27 05:07:17 +0000
@@ -683,6 +683,70 @@
}
\f
+/* Saving and restoring the process group of Emacs's terminal. */
+
+/* The process group of which Emacs was a member when it initially
+ started.
+
+ If Emacs was in its own process group (i.e. inherited_pgroup ==
+ getpid ()), then we know we're running under a shell with job
+ control (Emacs would never be run as part of a pipeline).
+ Everything is fine.
+
+ If Emacs was not in its own process group, then we know we're
+ running under a shell (or a caller) that doesn't know how to
+ separate itself from Emacs (like sh). Emacs must be in its own
+ process group in order to receive SIGIO correctly. In this
+ situation, we put ourselves in our own pgroup, forcibly set the
+ tty's pgroup to our pgroup, and make sure to restore and reinstate
+ the tty's pgroup just like any other terminal setting. If
+ inherited_group was not the tty's pgroup, then we'll get a
+ SIGTTmumble when we try to change the tty's pgroup, and a CONT if
+ it goes foreground in the future, which is what should happen. */
+
+static pid_t inherited_pgroup;
+
+void
+init_foreground_group (void)
+{
+ pid_t pgrp = EMACS_GETPGRP (0);
+ inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
+}
+
+/* Safely set a controlling terminal FD's process group to PGID.
+ If we are not in the foreground already, POSIX requires tcsetpgrp
+ to deliver a SIGTTOU signal, which would stop us. This is an
+ annoyance, so temporarily ignore the signal. */
+static void
+tcsetpgrp_without_stopping (int fd, pid_t pgid)
+{
+ signal_handler_t handler;
+ block_input ();
+ handler = signal (SIGTTOU, SIG_IGN);
+ tcsetpgrp (fd, pgid);
+ signal (SIGTTOU, handler);
+ unblock_input ();
+}
+
+/* Split off the foreground process group to Emacs alone. When we are
+ in the foreground, but not started in our own process group,
+ redirect the tty device handle FD to point to our own process
+ group. FD must be the file descriptor of the controlling tty. */
+static void
+narrow_foreground_group (int fd)
+{
+ if (inherited_pgroup && setpgid (0, 0) == 0)
+ tcsetpgrp_without_stopping (fd, getpid ());
+}
+
+/* Set the tty to our original foreground group. */
+static void
+widen_foreground_group (int fd)
+{
+ if (inherited_pgroup && setpgid (0, inherited_pgroup) == 0)
+ tcsetpgrp_without_stopping (fd, inherited_pgroup);
+}
+\f
/* Getting and setting emacs_tty structures. */
/* Set *TC to the parameters associated with the terminal FD.
@@ -799,6 +863,8 @@
if (!tty_out->output)
return; /* The tty is suspended. */
+ narrow_foreground_group (fileno (tty_out->input));
+
if (! tty_out->old_tty)
tty_out->old_tty = xmalloc (sizeof *tty_out->old_tty);
@@ -1231,6 +1297,7 @@
dos_ttcooked ();
#endif
+ widen_foreground_group (fileno (tty_out->input));
}
\f
#ifdef HAVE_PTYS
next prev parent reply other threads:[~2012-10-27 5:31 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-21 20:17 bug#12697: 24.2; Emacs crashes when using it as the commit editor for git Matthew Leach
2012-10-22 8:26 ` Andreas Schwab
2012-10-22 17:15 ` Eli Zaretskii
2012-10-22 17:39 ` Andreas Schwab
2012-10-22 20:22 ` Eli Zaretskii
2012-10-22 21:34 ` Andreas Schwab
2012-10-27 5:31 ` Paul Eggert [this message]
2012-10-27 7:52 ` bug#12697: " Eli Zaretskii
2012-10-28 18:57 ` Paul Eggert
2012-10-31 17:28 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=508B71A9.40509@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=12697@debbugs.gnu.org \
--cc=matthew@mattleach.net \
--cc=schwab@linux-m68k.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.