From 20f8b12cb667d99bd62dda338558c797f29f6861 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Thu, 1 Dec 2016 15:21:57 +0000 Subject: [PATCH 5/5] Add support for arguments in ALTERNATE_EDITOR to emacsclient * lib-src/emacsclient.c (fail): Parse ALTERNATE_EDITOR, or corresponding command-line argument, into space-separated tokens. * etc/NEWS: Document. --- etc/NEWS | 4 +++ lib-src/emacsclient.c | 73 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 33b8a42..c4f4569 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -268,6 +268,10 @@ variable of this kind to swap modifiers in Emacs. --- ** New input methods: 'cyrillic-tuvan', 'polish-prefix'. +++ +** emacsclient now accepts command-line options in ALTERNATE_EDITOR +and --alternate-editor. For example, ALTERNATE_EDITOR="emacs -Q -nw". + * Editing Changes in Emacs 26.1 diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 2909d63..b561db6 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -109,6 +109,9 @@ char *w32_getenv (const char *); /* Name used to invoke this program. */ const char *progname; +/* The first argument to main. */ +int main_argc; + /* The second argument to main. */ char **main_argv; @@ -192,6 +195,35 @@ xmalloc (size_t size) return result; } +/* Like realloc but get fatal error if memory is exhausted. */ + +static void * +xrealloc (void *ptr, size_t size) +{ + void *result = realloc (ptr, size); + if (result == NULL) + { + perror ("realloc"); + exit (EXIT_FAILURE); + } + return result; +} + +/* Like strdup but get a fatal error if memory is exhausted. */ +char *xstrdup (const char *); + +char * +xstrdup (const char *s) +{ + char *result = strdup (s); + if (result == NULL) + { + perror ("strdup"); + exit (EXIT_FAILURE); + } + return result; +} + /* From sysdep.c */ #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME) @@ -255,21 +287,6 @@ get_current_dir_name (void) #ifdef WINDOWSNT -/* Like strdup but get a fatal error if memory is exhausted. */ -char *xstrdup (const char *); - -char * -xstrdup (const char *s) -{ - char *result = strdup (s); - if (result == NULL) - { - perror ("strdup"); - exit (EXIT_FAILURE); - } - return result; -} - #define REG_ROOT "SOFTWARE\\GNU\\Emacs" char *w32_get_resource (HKEY, const char *, LPDWORD); @@ -651,7 +668,7 @@ Report bugs with M-x report-emacs-bug.\n"); } /* Try to run a different command, or --if no alternate editor is - defined-- exit with an errorcode. + defined-- exit with an decoderde. Uses argv, but gets it from the global variable main_argv. */ static _Noreturn void @@ -659,9 +676,27 @@ fail (void) { if (alternate_editor) { - int i = optind - 1; + size_t extra_args_size = (main_argc - optind + 1) * sizeof (char *); + size_t new_argv_size = extra_args_size; + char **new_argv = NULL; + /* Needed because strtok overwrites its input. */ + char *s = xstrdup (alternate_editor); + unsigned toks = 0; + char *tok = strtok(s, " "); + + /* Unpack alternate_editor's space-separated tokens into new_argv. */ + do + { + toks++; + new_argv = xrealloc (new_argv, new_argv_size + toks * sizeof (char *)); + new_argv[toks - 1] = tok; + } + while ((tok = strtok (NULL, " "))); + + /* Append main_argv arguments to new_argv. */ + memcpy (&new_argv[toks], main_argv + optind, extra_args_size); - execvp (alternate_editor, main_argv + i); + execvp (s, new_argv); message (true, "%s: error executing alternate editor \"%s\"\n", progname, alternate_editor); } @@ -674,6 +709,7 @@ fail (void) int main (int argc, char **argv) { + main_argc = argc; main_argv = argv; progname = argv[0]; message (true, "%s: Sorry, the Emacs server is supported only\n" @@ -1607,6 +1643,7 @@ main (int argc, char **argv) int start_daemon_if_needed; int exit_status = EXIT_SUCCESS; + main_argc = argc; main_argv = argv; progname = argv[0]; -- 2.7.4