GNU bug report logs - #1058
23.0.60; emacs --daemon should not return until socket is ready

Previous Next

Package: emacs;

Reported by: SRS0+wOMF+22+gmail.com=trentbuck <at> internode.on.net

Date: Tue, 30 Sep 2008 14:10:04 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: Romain Francoise <romain <at> orebokech.com>
To: Dan Nicolaescu <dann <at> ics.uci.edu>
Cc: 1058 <at> debbugs.gnu.org, trentbuck <at> gmail.com
Subject: bug#1058: 23.0.60; emacs --daemon should not return until socket is ready
Date: Wed, 01 Oct 2008 21:39:40 +0200
Hi Dan, Trent,

Dan Nicolaescu <dann <at> ics.uci.edu> writes:

> Just curious, what do you get if you do:
> emacs -Q --daemon; while ! ls /tmp/emacs1187/; do sleep 1; done

Yes, the delay is caused by my change to load the init file before
starting the server.

> Unfortunately ATM I don't see an easy way to do that.
> Ideas/patches are certainly welcome.

It's easy to do, but not very clean.  WDYT?


diff --git a/lisp/startup.el b/lisp/startup.el
index 5bd73f9..d9e37be 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1224,7 +1224,8 @@ opening the first frame (e.g. open a connection to an X server).")
   ;; processing all command line arguments to allow e.g. `server-name'
   ;; to be changed before the server starts.
   (when (daemonp)
-    (server-start))
+    (server-start)
+    (daemon-detach-parent))
 
   ;; Run emacs-session-restore (session management) if started by
   ;; the session manager and we have a session manager connection.
diff --git a/src/emacs.c b/src/emacs.c
index f94d2d3..a2842d4 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -235,6 +235,10 @@ int noninteractive1;
 /* Nonzero means Emacs was started as a daemon.  */
 int is_daemon = 0;
 
+/* Pipe used to send exit notification to the daemon parent at
+   startup.  */
+int daemon_pipe[2];
+
 /* Save argv and argc.  */
 char **initial_argv;
 int initial_argc;
@@ -1074,16 +1078,31 @@ main (int argc, char **argv)
   if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args))
     {
 #ifndef DOS_NT
+      if (pipe (daemon_pipe) == -1)
+	{
+	  fprintf (stderr, "Cannot pipe!\n");
+	  exit (1);
+	}
       pid_t f = fork ();
       int nfd;
       if (f > 0)
-	exit (0);
+	{
+	  char buf[2];
+	  close (daemon_pipe[1]);
+	  /* Wait for the child to close its end of the pipe before
+	     exiting.  */
+	  while (read (daemon_pipe[0], &buf, 1) < 0)
+	    sleep (0.1);
+	  close (daemon_pipe[0]);
+	  exit (0);
+	}
       if (f < 0)
 	{
 	  fprintf (stderr, "Cannot fork!\n");
 	  exit (1);
 	}
 
+      close (daemon_pipe[0]);
       nfd = open ("/dev/null", O_RDWR);
       dup2 (nfd, 0);
       dup2 (nfd, 1);
@@ -2389,6 +2408,16 @@ DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0,
   return is_daemon ? Qt : Qnil;
 }
 
+DEFUN ("daemon-detach-parent", Fdaemon_detach_parent, Sdaemon_detach_parent,
+       0, 0, 0,
+       doc: /* Detach Emacs from its invocation parent if it was started as a daemon.  */)
+  ()
+{
+  if (is_daemon)
+    close (daemon_pipe[1]);
+  return Qt;
+}
+
 void
 syms_of_emacs ()
 {
@@ -2408,6 +2437,7 @@ syms_of_emacs ()
   defsubr (&Sinvocation_name);
   defsubr (&Sinvocation_directory);
   defsubr (&Sdaemonp);
+  defsubr (&Sdaemon_detach_parent);
 
   DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
 	       doc: /* Args passed by shell to Emacs, as a list of strings.




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

Previous Next


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