Subject: Re: bug#1058: 23.0.60; emacs --daemon should not return until socket is ready

From: Dan Nicolaescu <[email-masked]>
Date: Tue, 14 Oct 2008 00:26:17 -0700 (PDT)

Stefan Monnier <[email-masked]> writes:

  > >> > -(defun server-start (&optional leave-dead)
  > >> > +(defun server-start (&optional leave-dead server-arg)
  > >> >    "Allow this Emacs process to be a server for client processes.
  > >> >  This starts a server communications subprocess through which
  > >> >  client \"editors\" can send your editing commands to this Emacs
  > >> > @@ -463,6 +463,8 @@ kill any existing server communications 
  > >> >      (when server-process
  > >> >        ;; kill it dead!
  > >> >        (ignore-errors (delete-process server-process)))
  > >> > +    (when (stringp server-arg)
  > >> > +      (setq server-name server-arg))
  > >> 
  > >> Changing the global var like this is an ugly hack.
  > 
  > > Sure, it can be moved before the call to `sever-start'
  > > I also wanted to make that variable obsolete and make the functional
  > > interface the preferred method.
  > 
  > There's no need or reason to make it obsolete.  You basically want to
  > replace the last two lines above with
  > 
  >     (unless (stringp server-arg)
  >       (setq server-arg server-name))
  > 
  > and then pass server-arg where it's needed.

Ah, OK.  I had the impression that server-name was needed for other
functions to work correctly, but that is not the case.
Updated patch follows.

Now it's your choice if you want this patch now or later.  I'll update
the docs when checking it in.

Index: lisp/server.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/server.el,v
retrieving revision 1.168
diff -u -3 -p -r1.168 server.el
--- lisp/server.el	24 Sep 2008 20:12:02 -0000	1.168
+++ lisp/server.el	14 Oct 2008 07:16:41 -0000
@@ -446,7 +446,7 @@ Creates the directory if necessary and m
       (error "The directory %s is unsafe" dir))))
 
 ;;;###autoload
-(defun server-start (&optional leave-dead)
+(defun server-start (&optional leave-dead server-arg)
   "Allow this Emacs process to be a server for client processes.
 This starts a server communications subprocess through which
 client \"editors\" can send your editing commands to this Emacs
@@ -463,9 +463,11 @@ kill any existing server communications 
     (when server-process
       ;; kill it dead!
       (ignore-errors (delete-process server-process)))
+    (unless (stringp server-arg)
+      (setq server-arg server-name))
     ;; Delete the socket files made by previous server invocations.
     (condition-case ()
-	(delete-file (expand-file-name server-name server-socket-dir))
+	(delete-file (expand-file-name server-arg server-socket-dir))
       (error nil))
     ;; If this Emacs already had a server, clear out associated status.
     (while server-clients
@@ -476,7 +478,7 @@ kill any existing server communications 
 	  (server-log (message "Server stopped"))
 	  (setq server-process nil))
       (let* ((server-dir (if server-use-tcp server-auth-dir server-socket-dir))
-	     (server-file (expand-file-name server-name server-dir)))
+	     (server-file (expand-file-name server-arg server-dir)))
 	;; Make sure there is a safe directory in which to place the socket.
 	(server-ensure-safe-dir server-dir)
 	;; Remove any leftover socket or authentication file.
@@ -491,7 +493,7 @@ kill any existing server communications 
 	  (add-hook 'kill-emacs-hook (lambda () (server-mode -1))) ;Cleanup upon exit.
 	  (setq server-process
 		(apply #'make-network-process
-		       :name server-name
+		       :name server-arg
 		       :server t
 		       :noquery t
 		       :sentinel 'server-sentinel
Index: lisp/startup.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/startup.el,v
retrieving revision 1.513
diff -u -3 -p -r1.513 startup.el
--- lisp/startup.el	12 Oct 2008 16:59:01 -0000	1.513
+++ lisp/startup.el	14 Oct 2008 07:16:41 -0000
@@ -1212,8 +1212,8 @@ the `--debug-init' option to view a comp
   ;; This is done after loading the user's init file and after
   ;; processing all command line arguments to allow e.g. `server-name'
   ;; to be changed before the server starts.
-  (when (daemonp)
-    (server-start))
+  (let ((dn (daemonp)))
+    (when dn (server-start nil dn)))
 
   ;; Run emacs-session-restore (session management) if started by
   ;; the session manager and we have a session manager connection.
Index: src/emacs.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/emacs.c,v
retrieving revision 1.448
diff -u -3 -p -r1.448 emacs.c
--- src/emacs.c	6 Oct 2008 16:16:56 -0000	1.448
+++ src/emacs.c	14 Oct 2008 07:16:41 -0000
@@ -237,6 +237,8 @@ int noninteractive1;
 
 /* Nonzero means Emacs was started as a daemon.  */
 int is_daemon = 0;
+/* Name for the server started by the daemon.*/
+static char *daemon_name;
 
 /* Save argv and argc.  */
 char **initial_argv;
@@ -792,6 +794,7 @@ main (int argc, char **argv)
 #endif
   int no_loadup = 0;
   char *junk = 0;
+  char *dname_arg = 0;
 
 #if GC_MARK_STACK
   extern Lisp_Object *stack_base;
@@ -1074,8 +1077,8 @@ main (int argc, char **argv)
       printf (USAGE4, bug_reporting_address ());
       exit (0);
     }
-
-  if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args))
+  if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)
+      || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args))
     {
 #ifndef DOS_NT
       pid_t f = fork ();
@@ -1088,6 +1091,8 @@ main (int argc, char **argv)
 	  exit (1);
 	}
 
+      if (dname_arg)
+      	daemon_name = xstrdup (dname_arg);
       nfd = open ("/dev/null", O_RDWR);
       dup2 (nfd, 0);
       dup2 (nfd, 1);
@@ -2387,10 +2392,17 @@ decode_env_path (evarname, defalt)
 }
 
 DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0,
-       doc: /* Return t if the current emacs process is a daemon.  */)
+       doc: /* Return non-nil if the current emacs process is a daemon.
+If the daemon was give a name argument, return that name. */)
   ()
 {
-  return is_daemon ? Qt : Qnil;
+  if (is_daemon)
+    if (daemon_name)
+      return build_string (daemon_name);
+    else
+      return Qt;
+  else
+    return Qnil;
 }
 
 void