src/emacs.c <w32_daemon_event> [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.
+2015-02-27 Mark Laws <mdl@60hz.org>
+
+ 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 <petewil0@googlemail.com> (tiny change)
Use ${EXEEXT} more uniformly in makefiles
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 */
}
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);
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
+2015-02-27 Mark Laws <mdl@60hz.org>
+
+ Support daemon mode on MS-Windows (bug#19688)
+ * server.el (server-process-filter): Force GUI frames on
+ MS-Windows in daemon mode, even if a TTY frame was requested.
+
+ * frameset.el (frameset-keep-original-display-p): Don't assume
+ windows-nt cannot be in daemon mode.
+
+ * frame.el (window-system-for-display): Don't assume windows-nt
+ cannot be in daemon mode.
+
2015-02-26 Ivan Shmakov <ivan@siamics.net>
* faces.el (face-list-p): Split from face-at-point.
Return nil if we don't know how to interpret DISPLAY."
;; MS-Windows doesn't know how to create a GUI frame in a -nw session.
(if (and (eq system-type 'windows-nt)
- (null (window-system)))
+ (null (window-system))
+ (not (daemonp)))
nil
(cl-loop for descriptor in display-format-alist
for pattern = (car descriptor)
(defun frameset-keep-original-display-p (force-display)
"True if saved frames' displays should be honored.
For the meaning of FORCE-DISPLAY, see `frameset-restore'."
- (cond ((daemonp) t)
- ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display?
+ (cond ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display?
+ ((daemonp) t)
(t (not force-display))))
(defun frameset-minibufferless-first-p (frame1 _frame2)
;; frame. If running a GUI server, force the frame
;; type to GUI. (Cygwin is perfectly happy with
;; multi-tty support, so don't override the user's
- ;; choice there.)
+ ;; choice there.) In daemon mode on Windows, we can't
+ ;; make tty frames, so force the frame type to GUI
+ ;; there too.
(when (and (eq system-type 'windows-nt)
- (eq window-system 'w32))
+ (or (daemonp)
+ (eq window-system 'w32)))
(push "-window-system" args-left)))
;; -position LINE[:COLUMN]: Set point to the given
terminal-frame)))))
(setq tty-name nil tty-type nil)
(if display (server-select-display display)))
- ((eq tty-name 'window-system)
+ ((or (and (eq system-type 'windows-nt)
+ (daemonp)
+ (setq display "w32"))
+ (eq tty-name 'window-system))
(server-create-window-system-frame display nowait proc
parent-id
frame-parameters))
+2015-02-27 Mark Laws <mdl@60hz.org>
+
+ Support daemon mode on MS-Windows (bug#19688)
+ * inc/ms-w32.h (W32_DAEMON_EVENT): New macro.
+
2015-01-16 Eli Zaretskii <eliz@gnu.org>
* Makefile.in (AM_V_CC, am__v_CC_, am__v_CC_0, am__v_CC_1)
#endif
#endif
+/* Event name for when emacsclient starts the Emacs daemon on Windows. */
+#define W32_DAEMON_EVENT "EmacsServerEvent"
/* ============================================================ */
+2015-02-27 Mark Laws <mdl@60hz.org>
+
+ Support daemon mode on MS-Windows (bug#19688)
+ * emacs.c <w32_daemon_event> [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.
+
+ * lisp.h (DAEMON_RUNNING): New macro, encapsulates Posix and
+ MS-Windows conditions for running in daemon mode.
+
+ * minibuf.c (read_minibuf): Use DAEMON_RUNNING.
+
+ * keyboard.c (kbd_buffer_get_event): Use DAEMON_RUNNING.
+
+ * dispnew.c (init_display) [WINDOWSNT]: Initialize frames/terminal
+ even in daemon mode.
+
2015-02-26 Jan Djärv <jan.h.d@swipnet.se>
* xmenu.c (create_and_show_popup_menu): Call XTranslateCoordinates,
}
#endif /* SIGWINCH */
- /* If running as a daemon, no need to initialize any frames/terminal. */
+ /* If running as a daemon, no need to initialize any frames/terminal,
+ except on Windows, where we at least want to initialize it. */
+#ifndef WINDOWSNT
if (IS_DAEMON)
return;
+#endif
/* If the user wants to use a window system, we shouldn't bother
initializing the terminal. This is especially important when the
/* Name for the server started by the daemon.*/
static char *daemon_name;
+#ifndef WINDOWSNT
/* Pipe used to send exit notification to the daemon parent at
startup. */
int daemon_pipe[2];
+#else
+HANDLE w32_daemon_event;
+#endif
/* Save argv and argc. */
char **initial_argv;
exit (0);
}
+#ifndef WINDOWSNT
/* Make sure IS_DAEMON starts up as false. */
daemon_pipe[1] = 0;
+#else
+ w32_daemon_event = NULL;
+#endif
if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)
|| argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args))
}
#endif /* DAEMON_MUST_EXEC */
- if (dname_arg)
- daemon_name = xstrdup (dname_arg);
/* Close unused reading end of the pipe. */
emacs_close (daemon_pipe[0]);
setsid ();
-#else /* DOS_NT */
+#elif defined(WINDOWSNT)
+ /* Indicate that we want daemon mode. */
+ w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_DAEMON_EVENT);
+ if (w32_daemon_event == NULL)
+ {
+ fprintf (stderr, "Couldn't create MS-Windows event for daemon: %s\n",
+ w32_strerror (0));
+ exit (1);
+ }
+#else /* MSDOS */
fprintf (stderr, "This platform does not support the -daemon flag.\n");
exit (1);
-#endif /* DOS_NT */
+#endif /* MSDOS */
+ if (dname_arg)
+ daemon_name = xstrdup (dname_arg);
}
#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
from the parent process and its tty file descriptors. */)
(void)
{
- int nfd;
bool err = 0;
if (!IS_DAEMON)
error ("This function can only be called if emacs is run as a daemon");
- if (daemon_pipe[1] < 0)
+ if (!DAEMON_RUNNING)
error ("The daemon has already been initialized");
if (NILP (Vafter_init_time))
error ("This function can only be called after loading the init files");
+#ifndef WINDOWSNT
+ int nfd;
/* Get rid of stdin, stdout and stderr. */
nfd = emacs_open ("/dev/null", O_RDWR, 0);
err |= emacs_close (daemon_pipe[1]) != 0;
/* Set it to an invalid value so we know we've already run this function. */
daemon_pipe[1] = -1;
+#else /* WINDOWSNT */
+ /* Signal the waiting emacsclient process. */
+ err |= SetEvent (w32_daemon_event) == 0;
+ err |= CloseHandle (w32_daemon_event) == 0;
+ /* Set it to an invalid value so we know we've already run this function. */
+ w32_daemon_event = INVALID_HANDLE_VALUE;
+#endif
if (err)
error ("I/O error during daemon initialization");
if (noninteractive
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
- || (IS_DAEMON && daemon_pipe[1] >= 0))
+ || (IS_DAEMON && DAEMON_RUNNING))
{
int c = getchar ();
XSETINT (obj, c);
extern bool no_site_lisp;
/* Pipe used to send exit notification to the daemon parent at
- startup. */
+ startup. On Windows, we use a kernel event instead. */
+#ifndef WINDOWSNT
extern int daemon_pipe[2];
#define IS_DAEMON (daemon_pipe[1] != 0)
+#define DAEMON_RUNNING (daemon_pipe[1] >= 0)
+#else /* WINDOWSNT */
+extern void *w32_daemon_event;
+#define IS_DAEMON (w32_daemon_event != NULL)
+#define DAEMON_RUNNING (w32_daemon_event != INVALID_HANDLE_VALUE)
+#endif
/* True if handling a fatal error already. */
extern bool fatal_error_in_progress;
if ((noninteractive
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
- || (IS_DAEMON && (daemon_pipe[1] >= 0)))
+ || (IS_DAEMON && DAEMON_RUNNING))
&& NILP (Vexecuting_kbd_macro))
{
val = read_minibuf_noninteractive (map, initial, prompt,