From 636b507bcc99120c6e9479541aa99fb737855de0 Mon Sep 17 00:00:00 2001 From: Dan Nicolaescu Date: Wed, 10 Dec 2008 07:56:51 +0000 Subject: [PATCH] * misc.texi (emacsclient Options): Describe what an empty string argument does for --alternate-editor. * emacsclient.1: Describe what an empty string argument does for --alternate-editor. * emacsclient.c (print_help_and_exit): Describe what an empty string argument does for --alternate-editor. (set_socket): Make it possible to not exit in case of an error. (start_daemon_and_retry_set_socket): New function. (main): Use it. Restore the NULL value for socket_name and server_file after the set_socket call. --- doc/emacs/ChangeLog | 5 +++ doc/emacs/misc.texi | 9 +++-- doc/man/ChangeLog | 5 +++ doc/man/emacsclient.1 | 2 + lib-src/ChangeLog | 9 +++++ lib-src/emacsclient.c | 86 ++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 106 insertions(+), 10 deletions(-) diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog index b8cc586536d..4d611b2233f 100644 --- a/doc/emacs/ChangeLog +++ b/doc/emacs/ChangeLog @@ -1,3 +1,8 @@ +2008-12-10 Dan Nicolaescu + + * misc.texi (emacsclient Options): Describe what an empty string + argument does for --alternate-editor. + 2008-12-09 Frank Schmitt * cmdargs.texi (Font X): Distinguish between client-side and diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 5c81f2ae004..4b2ee402073 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -1574,10 +1574,11 @@ listed below: @item -a @var{command} @itemx --alternate-editor=@var{command} Specify a command to run if @code{emacsclient} fails to contact Emacs. -This is useful when running @code{emacsclient} in a script. For -example, the following setting for the @env{EDITOR} environment -variable will always give you an editor, even if no Emacs server is -running: +This is useful when running @code{emacsclient} in a script. If +@var{command} is the empty string, then start Emacs in daemon mode and +try connecting again. For example, the following setting for the +@env{EDITOR} environment variable will always give you an editor, even +if no Emacs server is running: @example EDITOR="emacsclient --alternate-editor emacs +%d %s" diff --git a/doc/man/ChangeLog b/doc/man/ChangeLog index 4da2f2db177..32148a54c7e 100644 --- a/doc/man/ChangeLog +++ b/doc/man/ChangeLog @@ -1,3 +1,8 @@ +2008-12-10 Dan Nicolaescu + + * emacsclient.1: Describe what an empty string argument does for + --alternate-editor. + 2008-11-27 Dan Nicolaescu * emacsclient.1: Mention -nw and -c. Fix the character for --help. diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1 index ce5829d8d0d..73bf432136e 100644 --- a/doc/man/emacsclient.1 +++ b/doc/man/emacsclient.1 @@ -72,6 +72,8 @@ This can also be specified via the `EMACS_SERVER_FILE' environment variable. .B \-a, \-\-alternate-editor=EDITOR if the Emacs server is not running, run the specified editor instead. This can also be specified via the `ALTERNATE_EDITOR' environment variable. +If the value of EDITOR is the empty string, then Emacs is started in +daemon mode and emacsclient will try to connect to it. .TP .B \-d, \-\-display=DISPLAY tell the server to display the files on the given display. diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index acd9ef9f3cf..7cb4cda2013 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,12 @@ +2008-12-10 Dan Nicolaescu + + * emacsclient.c (print_help_and_exit): Describe what an empty + string argument does for --alternate-editor. + (set_socket): Make it possible to not exit in case of an error. + (start_daemon_and_retry_set_socket): New function. + (main): Use it. Restore the NULL value for socket_name and + server_file after the set_socket call. + 2008-12-03 Dan Nicolaescu * emacsclient.c: Include . diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 2a5b23faeaf..e96cf4ef358 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -616,6 +616,8 @@ The following OPTIONS are accepted:\n\ Set filename of the TCP authentication file\n\ -a, --alternate-editor=EDITOR\n\ Editor to fallback to if the server is not running\n\ + If EDITOR is the empty string, start Emacs in daemon\n\ + mode and try connecting again \n\ Report bugs to bug-gnu-emacs@gnu.org.\n", progname); exit (EXIT_SUCCESS); @@ -1294,7 +1296,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */ HSOCKET -set_socket () +set_socket (int no_exit_if_error) { HSOCKET s; @@ -1305,7 +1307,7 @@ set_socket () if (socket_name) { s = set_local_socket (); - if ((s != INVALID_SOCKET) || alternate_editor) + if ((s != INVALID_SOCKET) || no_exit_if_error) return s; message (TRUE, "%s: error accessing socket \"%s\"\n", progname, socket_name); @@ -1320,7 +1322,7 @@ set_socket () if (server_file) { s = set_tcp_socket (); - if ((s != INVALID_SOCKET) || alternate_editor) + if ((s != INVALID_SOCKET) || no_exit_if_error) return s; message (TRUE, "%s: error accessing server file \"%s\"\n", @@ -1338,7 +1340,7 @@ set_socket () /* Implicit server file. */ server_file = "server"; s = set_tcp_socket (); - if ((s != INVALID_SOCKET) || alternate_editor) + if ((s != INVALID_SOCKET) || no_exit_if_error) return s; /* No implicit or explicit socket, and no alternate editor. */ @@ -1408,6 +1410,52 @@ w32_give_focus () } #endif + +/* Start the emacs daemon and try to connect to it. */ + +void +start_daemon_and_retry_set_socket (void) +{ + pid_t dpid; + int status; + pid_t p; + + dpid = fork (); + + if (dpid > 0) + { + p = waitpid (dpid, &status, WUNTRACED | WCONTINUED); + + /* Try connecting again, the daemon should have started by + now. */ + message (TRUE, "daemon should have started, trying to connect again\n", dpid); + if ((emacs_socket = set_socket (1)) == INVALID_SOCKET) + message (TRUE, "Cannot connect even after starting the daemon\n"); + } + else if (dpid < 0) + { + fprintf (stderr, "Cannot fork!\n"); + exit (1); + } + else + { + char *d_argv[] = {"emacs", "--daemon", 0 }; + if (socket_name != NULL) + { + /* Pass --daemon=socket_name as argument. */ + char *deq = "--daemon="; + char *daemon_arg = alloca (strlen (deq) + + strlen (socket_name) + 1); + strcpy (daemon_arg, deq); + strcat (daemon_arg, socket_name); + d_argv[1] = daemon_arg; + } + execvp ("emacs", d_argv); + message (TRUE, "%s: error starting emacs daemon\n", progname); + } +} + + int main (argc, argv) int argc; @@ -1416,6 +1464,7 @@ main (argc, argv) int i, rl, needlf = 0; char *cwd, *str; char string[BUFSIZ+1]; + int null_socket_name, null_server_file, start_daemon_if_needed; main_argv = argv; progname = argv[0]; @@ -1431,9 +1480,34 @@ main (argc, argv) exit (EXIT_FAILURE); } - if ((emacs_socket = set_socket ()) == INVALID_SOCKET) - fail (); + /* If alternate_editor is the empty string, start the emacs daemon + in case of failure to connect. */ + start_daemon_if_needed = (alternate_editor + && (alternate_editor[0] == '\0')); + if (start_daemon_if_needed) + { + /* set_socket changes the values for socket_name and + server_file, we need to reset them, if they were NULL before + for the second call to set_socket. */ + null_socket_name = (socket_name == NULL); + null_server_file = (server_file == NULL); + } + if ((emacs_socket = set_socket (alternate_editor + || start_daemon_if_needed)) == INVALID_SOCKET) + if (start_daemon_if_needed) + { + /* Reset socket_name and server_file if they were NULL + before the set_socket call. */ + if (null_socket_name) + socket_name = NULL; + if (null_server_file) + server_file = NULL; + + start_daemon_and_retry_set_socket (); + } + else + fail (); cwd = get_current_dir_name (); if (cwd == 0) -- 2.39.5