From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Dan Nicolaescu Newsgroups: gmane.emacs.bugs Subject: bug#1058: 23.0.60; emacs --daemon should not return until socket is ready Date: Mon, 6 Oct 2008 13:59:36 -0700 (PDT) Message-ID: <200810062059.m96KxaXM004646@mothra.ics.uci.edu> References: <1222782234_2281@mail.internode.on.net> <200810011651.m91GpAZQ010333@mothra.ics.uci.edu> <87k5csds03.fsf@elegiac.orebokech.com> <200810012332.m91NWJ4s014658@mothra.ics.uci.edu> <874p3vediy.fsf@elegiac.orebokech.com> <200810020814.m928Ed1C016380@mothra.ics.uci.edu> <87myhmdgr8.fsf@elegiac.orebokech.com> Reply-To: Dan Nicolaescu , 1058@emacsbugs.donarmstrong.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1223327442 6741 80.91.229.12 (6 Oct 2008 21:10:42 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 6 Oct 2008 21:10:42 +0000 (UTC) Cc: trentbuck@gmail.com, 1058@emacsbugs.donarmstrong.com To: Romain Francoise Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Oct 06 23:11:39 2008 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1KmxMe-00049Y-Uj for geb-bug-gnu-emacs@m.gmane.org; Mon, 06 Oct 2008 23:11:37 +0200 Original-Received: from localhost ([127.0.0.1]:37529 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KmxLb-0000Cl-84 for geb-bug-gnu-emacs@m.gmane.org; Mon, 06 Oct 2008 17:10:31 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KmxL7-0008UP-DP for bug-gnu-emacs@gnu.org; Mon, 06 Oct 2008 17:10:01 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KmxL6-0008Tx-Ap for bug-gnu-emacs@gnu.org; Mon, 06 Oct 2008 17:10:00 -0400 Original-Received: from [199.232.76.173] (port=37116 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KmxL6-0008Tu-5B for bug-gnu-emacs@gnu.org; Mon, 06 Oct 2008 17:10:00 -0400 Original-Received: from rzlab.ucr.edu ([138.23.92.77]:50205) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KmxL5-00040w-P3 for bug-gnu-emacs@gnu.org; Mon, 06 Oct 2008 17:10:00 -0400 Original-Received: from rzlab.ucr.edu (rzlab.ucr.edu [127.0.0.1]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id m96L9vSx017297; Mon, 6 Oct 2008 14:09:57 -0700 Original-Received: (from debbugs@localhost) by rzlab.ucr.edu (8.13.8/8.13.8/Submit) id m96L55Hn016259; Mon, 6 Oct 2008 14:05:05 -0700 X-Loop: don@donarmstrong.com Resent-From: Dan Nicolaescu Resent-To: bug-submit-list@donarmstrong.com Resent-CC: Emacs Bugs Resent-Date: Mon, 06 Oct 2008 21:05:05 +0000 Resent-Message-ID: Resent-Sender: don@donarmstrong.com X-Emacs-PR-Message: report 1058 X-Emacs-PR-Package: emacs X-Emacs-PR-Keywords: Original-Received: via spool by 1058-submit@emacsbugs.donarmstrong.com id=B1058.122332680114205 (code B ref 1058); Mon, 06 Oct 2008 21:05:05 +0000 Original-Received: (at 1058) by emacsbugs.donarmstrong.com; 6 Oct 2008 21:00:01 +0000 Original-Received: from sallyv2.ics.uci.edu (sallyv2.ics.uci.edu [128.195.1.120]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id m96KxvtR014199 for <1058@emacsbugs.donarmstrong.com>; Mon, 6 Oct 2008 13:59:58 -0700 Original-Received: from mothra.ics.uci.edu (mothra.ics.uci.edu [128.195.6.93]) by sallyv2.ics.uci.edu (8.13.7+Sun/8.13.7) with ESMTP id m96KxbfV026377; Mon, 6 Oct 2008 13:59:39 -0700 (PDT) Original-Received: (from dann@localhost) by mothra.ics.uci.edu (8.13.8+Sun/8.13.6/Submit) id m96KxaXM004646; Mon, 6 Oct 2008 13:59:36 -0700 (PDT) In-Reply-To: <87myhmdgr8.fsf@elegiac.orebokech.com> (Romain Francoise's message of "Thu, 02 Oct 2008 19:54:51 +0200") Original-Lines: 168 X-ICS-MailScanner-Information: Please contact the ISP for more information X-ICS-MailScanner-ID: m96KxbfV026377 X-ICS-MailScanner: Found to be clean X-ICS-MailScanner-SpamCheck: not spam, SpamAssassin (score=-0.263, required 5, autolearn=disabled, ALL_TRUSTED -1.44, FM_MULTI_ODD2 1.10, TW_RG 0.08) X-ICS-MailScanner-From: dann@mothra.ics.uci.edu X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Resent-Date: Mon, 06 Oct 2008 17:10:00 -0400 X-BeenThere: bug-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:21189 Archived-At: Romain Francoise writes: > Here's version one of a patch for this, please let me know what you > think. Here's a version based on your code that also moves detaching from the terminal later. emacs --daemon && emacsclient -c works. Errors in ~/.emacs show up in the *Messages* buffer (as they do when starting up normally). Only lightly tested. Looking at the patch again, I there aren't any new features here, so it can go in as a bug fix. Index: lisp/startup.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/startup.el,v retrieving revision 1.508 diff -u -3 -p -r1.508 startup.el --- lisp/startup.el 6 Oct 2008 16:16:30 -0000 1.508 +++ lisp/startup.el 6 Oct 2008 20:18:41 -0000 @@ -1219,7 +1219,7 @@ opening the first frame (e.g. open a con ;; processing all command line arguments to allow e.g. `server-name' ;; to be changed before the server starts. (when (daemonp) - (server-start)) + (daemon-detach-and-start-server)) ;; 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 6 Oct 2008 20:18:41 -0000 @@ -238,6 +238,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. */ +static int daemon_pipe[2]; + /* Save argv and argc. */ char **initial_argv; int initial_argc; @@ -1078,25 +1082,7 @@ main (int argc, char **argv) if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)) { #ifndef DOS_NT - pid_t f = fork (); - int nfd; - if (f > 0) - exit (0); - if (f < 0) - { - fprintf (stderr, "Cannot fork!\n"); - exit (1); - } - - nfd = open ("/dev/null", O_RDWR); - dup2 (nfd, 0); - dup2 (nfd, 1); - dup2 (nfd, 2); - close (nfd); is_daemon = 1; -#ifdef HAVE_SETSID - setsid(); -#endif #else /* DOS_NT */ fprintf (stderr, "This platform does not support the -daemon flag.\n"); exit (1); @@ -2393,6 +2379,87 @@ DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, return is_daemon ? Qt : Qnil; } + +DEFUN ("daemon-detach-and-start-server", Fdaemon_detach_and_start_server, Sdaemon_detach_and_start_server, 0, 0, 0, + doc: /* Detach from terminal and start the server */) + () +{ + static char daemon_initialized = 0; + pid_t f; + int nfd; + + if (!is_daemon) + error ("This function can only be called if emacs is run as a daemon"); + + if (daemon_initialized) + error ("The daemon has already been initialized"); + + if (NILP (Vafter_init_time)) + error ("This function can only be called after loading the init files"); + + /* Start as a daemon: fork a new child process which will run the + rest of the initialization code, then exit. + + We want to avoid exiting before the server socket is ready, so + use a pipe for synchronization. The parent waits for the child + to close its end of the pipe (using `daemon-initialized') + before exiting. */ + if (pipe (daemon_pipe) == -1) + { + fprintf (stderr, "Cannot pipe!\n"); + exit (1); + } + + f = fork (); + if (f > 0) + { + int retval; + char buf[1]; + + /* Close unused writing end of the pipe. */ + close (daemon_pipe[1]); + + /* Just wait for the child to close its end of the pipe. */ + do + { + retval = read (daemon_pipe[0], &buf, 1); + } + while (retval == -1 && errno == EINTR); + + if (retval < 0) + { + fprintf (stderr, "Error reading status from child\n"); + exit (1); + } + + close (daemon_pipe[0]); + exit (0); + } + if (f < 0) + { + fprintf (stderr, "Cannot fork!\n"); + exit (1); + } + + /* Close unused reading end of the pipe. */ + close (daemon_pipe[0]); + + nfd = open ("/dev/null", O_RDWR); + dup2 (nfd, 0); + dup2 (nfd, 1); + dup2 (nfd, 2); + close (nfd); + is_daemon = 1; +#ifdef HAVE_SETSID + setsid(); +#endif + call0 (intern ("server-start")); + + /* Closing the pipe will notify the parent that it can exit. */ + close (daemon_pipe[1]); + daemon_initialized = 1; +} + void syms_of_emacs () { @@ -2412,6 +2479,7 @@ syms_of_emacs () defsubr (&Sinvocation_name); defsubr (&Sinvocation_directory); defsubr (&Sdaemonp); + defsubr (&Sdaemon_detach_and_start_server); DEFVAR_LISP ("command-line-args", &Vcommand_line_args, doc: /* Args passed by shell to Emacs, as a list of strings.