aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorReuben Thomas2016-12-01 15:21:57 +0000
committerReuben Thomas2017-08-30 21:59:38 +0100
commit98f01a13a3bf2a4db2dcc82a342ee017326de732 (patch)
tree70aac99762c0ee95026ec72fc307304b6700d372 /lib-src
parentdc313922d826b9f53cf1426ff36c8cc3f71d64c6 (diff)
downloademacs-98f01a13a3bf2a4db2dcc82a342ee017326de732.tar.gz
emacs-98f01a13a3bf2a4db2dcc82a342ee017326de732.zip
Add support for arguments in emacsclient's ALTERNATE_EDITOR (Bug #25082)
* lib-src/emacsclient.c (fail): Parse ALTERNATE_EDITOR, or corresponding command-line argument, into quote- or space-separated tokens. If a token starts with a quote, then it naturally is expected to end with a quote; escaping is not supported. This is enough to cope with the typical case of requiring the initial path to be quoted, common on Windows where it may contain spaces. * etc/NEWS: Document. * doc/emacs/misc.texi: Likewise. * doc/man/emacsclient.1: Tweak to remove the implication that only an editor can be specified (the manual already mentions a “command”). Fix a small error where “EDITOR” is referred to rather than “ALTERNATE_EDITOR”. * test/lib-src/emacsclient-tests.el: Add tests.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index f1d4e8976da..5e181ccacb1 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -110,6 +110,9 @@ char *w32_getenv (const char *);
110/* Name used to invoke this program. */ 110/* Name used to invoke this program. */
111const char *progname; 111const char *progname;
112 112
113/* The first argument to main. */
114int main_argc;
115
113/* The second argument to main. */ 116/* The second argument to main. */
114char **main_argv; 117char **main_argv;
115 118
@@ -201,6 +204,35 @@ xmalloc (size_t size)
201 return result; 204 return result;
202} 205}
203 206
207/* Like realloc but get fatal error if memory is exhausted. */
208
209static void *
210xrealloc (void *ptr, size_t size)
211{
212 void *result = realloc (ptr, size);
213 if (result == NULL)
214 {
215 perror ("realloc");
216 exit (EXIT_FAILURE);
217 }
218 return result;
219}
220
221/* Like strdup but get a fatal error if memory is exhausted. */
222char *xstrdup (const char *);
223
224char *
225xstrdup (const char *s)
226{
227 char *result = strdup (s);
228 if (result == NULL)
229 {
230 perror ("strdup");
231 exit (EXIT_FAILURE);
232 }
233 return result;
234}
235
204/* From sysdep.c */ 236/* From sysdep.c */
205#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME) 237#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
206 238
@@ -264,21 +296,6 @@ get_current_dir_name (void)
264 296
265#ifdef WINDOWSNT 297#ifdef WINDOWSNT
266 298
267/* Like strdup but get a fatal error if memory is exhausted. */
268char *xstrdup (const char *);
269
270char *
271xstrdup (const char *s)
272{
273 char *result = strdup (s);
274 if (result == NULL)
275 {
276 perror ("strdup");
277 exit (EXIT_FAILURE);
278 }
279 return result;
280}
281
282#define REG_ROOT "SOFTWARE\\GNU\\Emacs" 299#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
283 300
284char *w32_get_resource (HKEY, const char *, LPDWORD); 301char *w32_get_resource (HKEY, const char *, LPDWORD);
@@ -673,7 +690,7 @@ Report bugs with M-x report-emacs-bug.\n");
673} 690}
674 691
675/* Try to run a different command, or --if no alternate editor is 692/* Try to run a different command, or --if no alternate editor is
676 defined-- exit with an errorcode. 693 defined-- exit with an error code.
677 Uses argv, but gets it from the global variable main_argv. */ 694 Uses argv, but gets it from the global variable main_argv. */
678 695
679static _Noreturn void 696static _Noreturn void
@@ -681,9 +698,38 @@ fail (void)
681{ 698{
682 if (alternate_editor) 699 if (alternate_editor)
683 { 700 {
684 int i = optind - 1; 701 size_t extra_args_size = (main_argc - optind + 1) * sizeof (char *);
702 size_t new_argv_size = extra_args_size;
703 char **new_argv = NULL;
704 char *s = xstrdup (alternate_editor);
705 unsigned toks = 0;
706
707 /* Unpack alternate_editor's space-separated tokens into new_argv. */
708 for (char *tok = s; tok != NULL && *tok != '\0';)
709 {
710 /* Allocate new token. */
711 ++toks;
712 new_argv = xrealloc (new_argv, new_argv_size + toks * sizeof (char *));
713
714 /* Skip leading delimiters, and set separator, skipping any
715 opening quote. */
716 size_t skip = strspn (tok, " \"");
717 tok += skip;
718 char sep = (skip > 0 && tok[-1] == '"') ? '"' : ' ';
719
720 /* Record start of token. */
721 new_argv[toks - 1] = tok;
722
723 /* Find end of token and overwrite it with NUL. */
724 tok = strchr (tok, sep);
725 if (tok != NULL)
726 *tok++ = '\0';
727 }
728
729 /* Append main_argv arguments to new_argv. */
730 memcpy (&new_argv[toks], main_argv + optind, extra_args_size);
685 731
686 execvp (alternate_editor, main_argv + i); 732 execvp (*new_argv, new_argv);
687 message (true, "%s: error executing alternate editor \"%s\"\n", 733 message (true, "%s: error executing alternate editor \"%s\"\n",
688 progname, alternate_editor); 734 progname, alternate_editor);
689 } 735 }
@@ -696,6 +742,7 @@ fail (void)
696int 742int
697main (int argc, char **argv) 743main (int argc, char **argv)
698{ 744{
745 main_argc = argc;
699 main_argv = argv; 746 main_argv = argv;
700 progname = argv[0]; 747 progname = argv[0];
701 message (true, "%s: Sorry, the Emacs server is supported only\n" 748 message (true, "%s: Sorry, the Emacs server is supported only\n"
@@ -1629,6 +1676,7 @@ main (int argc, char **argv)
1629 int start_daemon_if_needed; 1676 int start_daemon_if_needed;
1630 int exit_status = EXIT_SUCCESS; 1677 int exit_status = EXIT_SUCCESS;
1631 1678
1679 main_argc = argc;
1632 main_argv = argv; 1680 main_argv = argv;
1633 progname = argv[0]; 1681 progname = argv[0];
1634 1682