/* Client process that communicates with GNU Emacs acting as server.
-Copyright (C) 1986-1987, 1994, 1999-2014 Free Software Foundation, Inc.
+Copyright (C) 1986-1987, 1994, 1999-2016 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
/* Name used to invoke this program. */
const char *progname;
-/* The second argument to main. */
+/* The second argument to main. */
char **main_argv;
/* Nonzero means don't wait for a response from Emacs. --no-wait. */
int nowait = 0;
-/* Nonzero means don't print messages for successful operations. --quiet. */
+/* Nonzero means don't print messages for successful operations. --quiet. */
int quiet = 0;
/* Nonzero means args are expressions to be evaluated. --eval. */
/* The parent window ID, if we are opening a frame via XEmbed. */
char *parent_id = NULL;
-/* Nonzero means open a new Emacs frame on the current terminal. */
+/* Nonzero means open a new Emacs frame on the current terminal. */
int tty = 0;
/* If non-NULL, the name of an editor to fallback to if the server
int emacs_pid = 0;
/* If non-NULL, a string that should form a frame parameter alist to
- be used for the new frame */
+ be used for the new frame. */
const char *frame_parameters = NULL;
static _Noreturn void print_help_and_exit (void);
break;
default:
- message (true, "Try `%s --help' for more information\n", progname);
+ message (true, "Try '%s --help' for more information\n", progname);
exit (EXIT_FAILURE);
break;
}
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);
/* Open up an AF_INET socket. */
if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
+ /* Since we have an alternate to try out, this is not an error
+ yet; popping out a modal dialog at this stage would make -a
+ option totally useless for emacsclientw -- the user will
+ still get an error message if the alternate editor fails. */
+#ifdef WINDOWSNT
+ if(!(w32_window_app () && alternate_editor))
+#endif
sock_err_message ("socket");
return INVALID_SOCKET;
}
/* Set up the socket. */
if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
{
+#ifdef WINDOWSNT
+ if(!(w32_window_app () && alternate_editor))
+#endif
sock_err_message ("connect");
return INVALID_SOCKET;
}
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
if ((argc - optind < 1) && !eval && current_frame)
{
message (true, "%s: file name or argument required\n"
- "Try `%s --help' for more information\n",
+ "Try '%s --help' for more information\n",
progname, progname);
exit (EXIT_FAILURE);
}