GNU bug report logs - #554
OSX: with-temp-buffer kills unrelated processes

Previous Next

Package: emacs;

Reported by: Markus Triska <markus.triska <at> gmx.at>

Date: Sun, 13 Jul 2008 17:50:03 UTC

Severity: normal

Done: Chong Yidong <cyd <at> stupidchicken.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Markus Triska <markus.triska <at> gmx.at>
To: YAMAMOTO Mitsuharu <mituharu <at> math.s.chiba-u.ac.jp>
Cc: 554 <at> debbugs.gnu.org
Subject: bug#554: OSX: with-temp-buffer kills unrelated processes
Date: Wed, 16 Jul 2008 17:27:47 +0200
YAMAMOTO Mitsuharu <mituharu <at> math.s.chiba-u.ac.jp> writes:

> OK, close-on-exec seems to be usable for the `fork' case.  How about
> the patch below?

Thank you very much; I've tested the following adapted version of your
patch with the latest CVS trunk of Emacs, and the problem seems gone.

All the best,
Markus


diff --git a/src/callproc.c b/src/callproc.c
index a6de766..3d61e64 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1047,8 +1047,8 @@ add_env (char **env, char **new_env, char *string)
    Therefore, the superior process must save and restore the value
    of environ around the vfork and the call to this function.
 
-   SET_PGRP is nonzero if we should put the subprocess into a separate
-   process group.
+   RET_ON_FAIL is nonzero if we should return from the function on
+   failure of execvp rather than calling _exit.
 
    CURRENT_DIR is an elisp string giving the path of the current
    directory the subprocess should have.  Since we can't really signal
@@ -1056,10 +1056,10 @@ add_env (char **env, char **new_env, char *string)
    executable directory by the parent.  */
 
 int
-child_setup (in, out, err, new_argv, set_pgrp, current_dir)
+child_setup (in, out, err, new_argv, ret_on_fail, current_dir)
      int in, out, err;
      register char **new_argv;
-     int set_pgrp;
+     int ret_on_fail;
      Lisp_Object current_dir;
 {
   char **env;
@@ -1291,7 +1291,8 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
   emacs_write (1, "Can't exec program: ", 20);
   emacs_write (1, new_argv[0], strlen (new_argv[0]));
   emacs_write (1, "\n", 1);
-  _exit (1);
+  if (!ret_on_fail)
+    _exit (1);
 #endif /* not WINDOWSNT */
 #endif /* not MSDOS */
 }
diff --git a/src/process.c b/src/process.c
index c82584a..b0bebeb 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1851,6 +1851,9 @@ create_process (process, new_argv, current_dir)
   int inchannel, outchannel;
   pid_t pid;
   int sv[2];
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+  int wait_child_setup[2];
+#endif
 #ifdef POSIX_SIGNALS
   sigset_t procmask;
   sigset_t blocked;
@@ -1893,12 +1896,6 @@ create_process (process, new_argv, current_dir)
 #endif
       if (forkin < 0)
 	report_file_error ("Opening pty", Qnil);
-#if defined (DONT_REOPEN_PTY)
-      /* In the case that vfork is defined as fork, the parent process
-	 (Emacs) may send some data before the child process completes
-	 tty options setup.  So we setup tty before forking.  */
-      child_setup_tty (forkout);
-#endif /* DONT_REOPEN_PTY */
 #else
       forkin = forkout = -1;
 #endif /* not USG, or USG_SUBTTY_WORKS */
@@ -1924,6 +1921,25 @@ create_process (process, new_argv, current_dir)
       forkin = sv[0];
     }
 
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+    {
+      int tem;
+
+      tem = pipe (wait_child_setup);
+      if (tem < 0)
+	report_file_error ("Creating pipe", Qnil);
+      tem = fcntl (wait_child_setup[1], F_GETFD, 0);
+      if (tem >= 0)
+	tem = fcntl (wait_child_setup[1], F_SETFD, tem | FD_CLOEXEC);
+      if (tem < 0)
+	{
+	  emacs_close (wait_child_setup[0]);
+	  emacs_close (wait_child_setup[1]);
+	  report_file_error ("Setting file descriptor flags", Qnil);
+	}
+    }
+#endif
+
 #if 0
   /* Replaced by close_process_descs */
   set_exclusive_use (inchannel);
@@ -2150,16 +2166,21 @@ create_process (process, new_argv, current_dir)
 #endif /* SIGCHLD */
 #endif /* !POSIX_SIGNALS */
 
-#if !defined (DONT_REOPEN_PTY)
 	if (pty_flag)
 	  child_setup_tty (xforkout);
-#endif /* not DONT_REOPEN_PTY */
 #ifdef WINDOWSNT
 	pid = child_setup (xforkin, xforkout, xforkout,
 			   new_argv, 1, current_dir);
 #else  /* not WINDOWSNT */
+#ifdef FD_CLOEXEC
+	emacs_close (wait_child_setup[0]);
+#endif
 	child_setup (xforkin, xforkout, xforkout,
 		     new_argv, 1, current_dir);
+#ifdef FD_CLOEXEC
+	emacs_close (wait_child_setup[0]);
+#endif
+	_exit (1);
 #endif /* not WINDOWSNT */
       }
     environ = save_environ;
@@ -2211,6 +2232,21 @@ create_process (process, new_argv, current_dir)
       else
 #endif
 	XPROCESS (process)->tty_name = Qnil;
+
+#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
+      /* Wait for child_setup to complete in case that vfork is
+	 actually defined as fork.  The descriptor wait_child_setup[1]
+	 of a pipe is closed at the child side either by close-on-exec
+	 on successful execvp or by the explicit emacs_close call
+	 before _exit above.  */
+      {
+	char dummy;
+
+	emacs_close (wait_child_setup[1]);
+	emacs_read (wait_child_setup[0], &dummy, 1);
+	emacs_close (wait_child_setup[0]);
+      }
+#endif
     }
 
   /* Restore the signal state whether vfork succeeded or not.







This bug report was last modified 16 years and 328 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.