From fc0127715c4cea8bc2fc26ebe69592d412555a07 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Tue, 28 Oct 2008 01:02:44 +0000 Subject: [PATCH] * xdisp.c (pos_visible_p, redisplay_internal, message3_nolog) (message2_nolog): Check FRAME_INITIAL_P instead of noninteractively. * emacs.c (is_daemon): Remove. (main): Don't set is_daemon. (IS_DAEMON): New macro. (Fdaemonp, Fdaemon_initialized): Use it. (Fdaemon_initialized): Wrtie a char into the pipe to make sure the parent exits. (syms_of_emacs): Explicitly initialize daemon_pipe[1]. --- src/ChangeLog | 13 +++++++++++++ src/emacs.c | 39 ++++++++++++++++++++++++++++++++------- src/xdisp.c | 10 +++++----- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6562ef022d7..ba79e504b53 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2008-10-28 Stefan Monnier + + * xdisp.c (pos_visible_p, redisplay_internal, message3_nolog) + (message2_nolog): Check FRAME_INITIAL_P instead of noninteractively. + + * emacs.c (is_daemon): Remove. + (main): Don't set is_daemon. + (IS_DAEMON): New macro. + (Fdaemonp, Fdaemon_initialized): Use it. + (Fdaemon_initialized): Wrtie a char into the pipe to make sure the + parent exits. + (syms_of_emacs): Explicitly initialize daemon_pipe[1]. + 2008-10-27 Chong Yidong * nsterm.m (ns_draw_window_cursor): When hbar cursor is on diff --git a/src/emacs.c b/src/emacs.c index 6f54291a514..b3dee7776a2 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -235,8 +235,6 @@ int noninteractive; 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; @@ -244,6 +242,8 @@ static char *daemon_name; startup. */ static int daemon_pipe[2]; +#define IS_DAEMON (daemon_pipe[1] != 0) + /* Save argv and argc. */ char **initial_argv; int initial_argc; @@ -1086,6 +1086,20 @@ main (int argc, char **argv) /* Start as a daemon: fork a new child process which will run the rest of the initialization code, then exit. + Detaching a daemon requires the following steps: + - fork + - setsid + - exit the parent + - close the tty file-descriptors + + We only want to do the last 2 steps once the daemon is ready to + serve requests, i.e. after loading .emacs (initialization). + OTOH initialization may start subprocesses (e.g. ispell) and these + should be run from the proper process (the one that will end up + running as daemon) and with the proper "session id" in order for + them to keep working after detaching, so fork and setsid need to be + performed before initialization. + 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') @@ -1131,7 +1145,6 @@ main (int argc, char **argv) daemon_name = xstrdup (dname_arg); /* Close unused reading end of the pipe. */ close (daemon_pipe[0]); - is_daemon = 1; #ifdef HAVE_SETSID setsid(); #endif @@ -2429,7 +2442,7 @@ DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0, If the daemon was given a name argument, return that name. */) () { - if (is_daemon) + if (IS_DAEMON) if (daemon_name) return build_string (daemon_name); else @@ -2439,12 +2452,14 @@ If the daemon was given a name argument, return that name. */) } DEFUN ("daemon-initialized", Fdaemon_initialized, Sdaemon_initialized, 0, 0, 0, - doc: /* Mark the Emacs daemon as being initialized. */) + doc: /* Mark the Emacs daemon as being initialized. +This finishes the daemonization process by doing the other half of detaching +from the parent process and its tty file descriptors. */) () { int nfd; - if (!is_daemon) + if (!IS_DAEMON) error ("This function can only be called if emacs is run as a daemon"); if (daemon_pipe[1] < 0) @@ -2460,7 +2475,14 @@ DEFUN ("daemon-initialized", Fdaemon_initialized, Sdaemon_initialized, 0, 0, 0, dup2 (nfd, 2); close (nfd); - /* Closing the pipe will notify the parent that it can exit. */ + /* Closing the pipe will notify the parent that it can exit. + FIXME: In case some other process inherited the pipe, closing it here + won't notify the parent because it's still open elsewhere, so we + additionally send a byte, just to make sure the parent really exits. + Instead, we should probably close the pipe in start-process and + call-process to make sure the pipe is never inherited by + subprocesses. */ + write (daemon_pipe[1], "\n", 1); close (daemon_pipe[1]); /* Set it to an invalid value so we know we've already run this function. */ daemon_pipe[1] = -1; @@ -2584,6 +2606,9 @@ was found. */); doc: /* Value of `current-time' after loading the init files. This is nil during initialization. */); Vafter_init_time = Qnil; + + /* Make sure IS_DAEMON starts up as false. */ + daemon_pipe[1] = 0; } /* arch-tag: 7bfd356a-c720-4612-8ab6-aa4222931c2e diff --git a/src/xdisp.c b/src/xdisp.c index d6ac67a7333..5509d1e65ed 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1323,7 +1323,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos) int visible_p = 0; struct buffer *old_buffer = NULL; - if (noninteractive) + if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w)))) return visible_p; if (XBUFFER (w->buffer) != current_buffer) @@ -7891,7 +7891,7 @@ message2_nolog (m, nbytes, multibyte) struct frame *sf = SELECTED_FRAME (); message_enable_multibyte = multibyte; - if (noninteractive) + if (FRAME_INITIAL_P (sf)) { if (noninteractive_need_newline) putc ('\n', stderr); @@ -7990,7 +7990,7 @@ message3_nolog (m, nbytes, multibyte) struct frame *sf = SELECTED_FRAME (); message_enable_multibyte = multibyte; - if (noninteractive) + if (FRAME_INITIAL_P (sf)) { if (noninteractive_need_newline) putc ('\n', stderr); @@ -8088,7 +8088,7 @@ message_with_string (m, string, log) putc ('\n', stderr); noninteractive_need_newline = 0; fprintf (stderr, m, SDATA (string)); - if (cursor_in_echo_area == 0) + if (!cursor_in_echo_area) fprintf (stderr, "\n"); fflush (stderr); } @@ -11300,7 +11300,7 @@ redisplay_internal (preserve_echo_area) /* No redisplay if running in batch mode or frame is not yet fully initialized, or redisplay is explicitly turned off by setting Vinhibit_redisplay. */ - if (noninteractive + if (FRAME_INITIAL_P (SELECTED_FRAME ()) || !NILP (Vinhibit_redisplay)) return; -- 2.39.2