From 805fe507087b9675a010a30a8a8840587ffdf5be Mon Sep 17 00:00:00 2001 From: Mark Laws Date: Fri, 27 Feb 2015 12:43:30 +0200 Subject: Support daemon mode on MS-Windows (bug#19688) src/emacs.c [WINDOWSNT]: New global var. (main) [WINDOWSNT]: Initialize it to NULL. Create the event to signal clients we are ready for connections. (Fdaemon_initialized): Use DAEMON_RUNNING. [WINDOWSNT]: MS-Windows specific code to signal clients we are ready for connections. src/lisp.h (DAEMON_RUNNING): New macro, encapsulates Posix and MS-Windows conditions for running in daemon mode. src/minibuf.c (read_minibuf): Use DAEMON_RUNNING. src/keyboard.c (kbd_buffer_get_event): Use DAEMON_RUNNING. src/dispnew.c (init_display) [WINDOWSNT]: Initialize frames/terminal even in daemon mode. nt/inc/ms-w32.h (W32_DAEMON_EVENT): New macro. lib-src/emacsclient.c (decode_options) [WINDOWSNT]: Don't reject empty arguments for --alternate-editor. (print_help_and_exit) [WINDOWSNT]: Don't refrain from advertising empty arguments for --alternate-editor. (start_daemon_and_retry_set_socket) [WINDOWSNT]: MS-Windows specific code to start Emacs in daemon mode and wait for it to be ready for client connections. lisp/server.el (server-process-filter): Force GUI frames on MS-Windows in daemon mode, even if a TTY frame was requested. lisp/frameset.el (frameset-keep-original-display-p): Don't assume windows-nt cannot be in daemon mode. lisp/frame.el (window-system-for-display): Don't assume windows-nt cannot be in daemon mode. --- lib-src/ChangeLog | 11 +++++++ lib-src/emacsclient.c | 81 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 82 insertions(+), 10 deletions(-) (limited to 'lib-src') diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 5c55bcea506..83855afa675 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,14 @@ +2015-02-27 Mark Laws + + Support daemon mode on MS-Windows (bug#19688) + * emacsclient.c (decode_options) [WINDOWSNT]: Don't reject empty + arguments for --alternate-editor. + (print_help_and_exit) [WINDOWSNT]: Don't refrain from advertising + empty arguments for --alternate-editor. + (start_daemon_and_retry_set_socket) [WINDOWSNT]: MS-Windows + specific code to start Emacs in daemon mode and wait for it to be + ready for client connections. + 2015-02-23 Pete Williamson (tiny change) Use ${EXEEXT} more uniformly in makefiles diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index a04dda6408f..806275f5b1d 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -595,13 +595,6 @@ decode_options (int argc, char **argv) display = NULL; tty = 1; } - - if (alternate_editor && alternate_editor[0] == '\0') - { - message (true, "--alternate-editor argument or ALTERNATE_EDITOR variable cannot be\n\ -an empty string"); - exit (EXIT_FAILURE); - } #endif /* WINDOWSNT */ } @@ -642,10 +635,8 @@ The following OPTIONS are accepted:\n\ Set filename of the TCP authentication file\n\ -a EDITOR, --alternate-editor=EDITOR\n\ Editor to fallback to if the server is not running\n" -#ifndef WINDOWSNT " If EDITOR is the empty string, start Emacs in daemon\n\ mode and try connecting again\n" -#endif /* not WINDOWSNT */ "\n\ Report bugs with M-x report-emacs-bug.\n"); exit (EXIT_SUCCESS); @@ -1511,7 +1502,77 @@ start_daemon_and_retry_set_socket (void) execvp ("emacs", d_argv); message (true, "%s: error starting emacs daemon\n", progname); } -#endif /* WINDOWSNT */ +#else /* WINDOWSNT */ + DWORD wait_result; + HANDLE w32_daemon_event; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory (&si, sizeof si); + si.cb = sizeof si; + ZeroMemory (&pi, sizeof pi); + + /* We start Emacs in daemon mode, and then wait for it to signal us + it is ready to accept client connections, by asserting an event + whose name is known to the daemon (defined by nt/inc/ms-w32.h). */ + + if (!CreateProcess (NULL, "emacs --daemon", NULL, NULL, FALSE, + CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) + { + char* msg = NULL; + + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_ARGUMENT_ARRAY, + NULL, GetLastError (), 0, (LPTSTR)&msg, 0, NULL); + message (true, "%s: error starting emacs daemon (%s)\n", progname, msg); + exit (EXIT_FAILURE); + } + + w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_DAEMON_EVENT); + if (w32_daemon_event == NULL) + { + message (true, "Couldn't create Windows daemon event"); + exit (EXIT_FAILURE); + } + if ((wait_result = WaitForSingleObject (w32_daemon_event, INFINITE)) + != WAIT_OBJECT_0) + { + char *msg = NULL; + + switch (wait_result) + { + case WAIT_ABANDONED: + msg = "The daemon exited unexpectedly"; + break; + case WAIT_TIMEOUT: + /* Can't happen due to INFINITE. */ + default: + case WAIT_FAILED: + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_ARGUMENT_ARRAY, + NULL, GetLastError (), 0, (LPTSTR)&msg, 0, NULL); + break; + } + message (true, "Error: Could not start the Emacs daemon: %s\n", msg); + exit (EXIT_FAILURE); + } + CloseHandle (w32_daemon_event); + + /* Try connecting, the daemon should have started by now. */ + /* It's just a progress message, so don't pop a dialog if this is + emacsclientw. */ + if (!w32_window_app ()) + message (true, + "Emacs daemon should have started, trying to connect again\n"); + if ((emacs_socket = set_socket (1)) == INVALID_SOCKET) + { + message (true, + "Error: Cannot connect even after starting the Emacs daemon\n"); + exit (EXIT_FAILURE); + } +#endif /* WINDOWSNT */ } int -- cgit v1.2.1