diff options
| author | Jens Schmidt <jschmidt4gnu@vodafonemail.de> | 2025-04-02 22:48:31 +0200 |
|---|---|---|
| committer | Eli Zaretskii <eliz@gnu.org> | 2025-04-13 11:33:30 +0300 |
| commit | e82989757f42e95bf72a2a55de415a8162a55dc3 (patch) | |
| tree | a403b48a17f89cc6a001eeeaad84a4e4e5c685bb /src | |
| parent | 5665b446b7a5b2f6ff4d4e7ea9b2c91e0e733c92 (diff) | |
Use a pristine copy of argv to restart Emacs
argv as left after main has proccessed the command-line can differ
both in order and contents of the original command-line arguments,
which can lead to surprising results when restarting emacs on the
cooked argv through `kill-emacs'.
Starting from that observation, consistenly use variables
'initial_cmdline' on Windows, 'initial_argc', 'initial_argv' on
non-Windows, and 'initial_argv0' in all ports.
* src/lisp.h: Declare 'initial_argv0', limit declaration of
'initial_argv' and 'initial_argc' to non-Windows ports.
* src/emacs.c: Likewise, but for the definitions.
(init_cmdargs): Move initialization of 'initial_argv' and
'initial_argc' ...
(copy_args) [!WINDOWSNT]: ... to this new function ...
(main): ... and call that in 'main', also initializing
'initial_argv0' before the command-line processing.
* src/emacs.c (Fkill_emacs):
* src/pgtkterm.c (pgtk_term_init):
* src/sysdep.c (emacs_perror):
* src/xterm.c (x_term_init): Use 'initial_argv0' where only that
is required. (Bug#77389)
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs.c | 50 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/pgtkterm.c | 2 | ||||
| -rw-r--r-- | src/sysdep.c | 3 | ||||
| -rw-r--r-- | src/xterm.c | 2 |
5 files changed, 51 insertions, 9 deletions
diff --git a/src/emacs.c b/src/emacs.c index 6ff7b632c0f..79604d09a37 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -238,14 +238,32 @@ static int daemon_pipe[2]; HANDLE w32_daemon_event; #endif -/* Save argv and argc. */ +/* Save argv and argc. + + initial_argc, initial_argv: + A pristine copy of the command-line arguments as passed into main, + saved away before main has had a chance to modify them. On + Windows, we use initial_cmdline instead. + + initial_argv0: + argv[0] as passed into main. Available on all ports. + + initial_emacs_executable: + Path to the current executable. Based on argv[0] but verified to + point to an existing executable if non-NULL. */ +#ifndef WINDOWSNT char **initial_argv; int initial_argc; +#endif +char *initial_argv0; static char *initial_emacs_executable = NULL; /* The name of the working directory, or NULL if this info is unavailable. */ char const *emacs_wd; +#ifndef WINDOWSNT +static void copy_args (int argc, char **argv); +#endif static void sort_args (int argc, char **argv); static void syms_of_emacs (void); @@ -476,9 +494,6 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd) Lisp_Object raw_name; AUTO_STRING (slash_colon, "/:"); - initial_argv = argv; - initial_argc = argc; - #ifdef WINDOWSNT /* Must use argv[0] converted to UTF-8, as it begets many standard file and directory names. */ @@ -1396,6 +1411,11 @@ android_emacs_init (int argc, char **argv, char *dump_file) init_standard_fds (); atexit (close_output_streams); +#ifndef WINDOWSNT + copy_args (argc, argv); +#endif + initial_argv0 = argv[0]; + /* Command-line argument processing. The arguments in the argv[] array are sorted in the descending @@ -2696,6 +2716,26 @@ static const struct standard_args standard_args[] = { "-kill", "--kill", -10, 0 }, }; +#ifndef WINDOWSNT + +/* Copy the elements of ARGV (assumed to have ARGC elements) and store + the copy in initial_argv. Store ARGC in initial_argc. */ + +static void +copy_args (int argc, char **argv) +{ + char **new = xmalloc ((argc + 1) * sizeof *new); + int i; + new[0] = argv[0]; + for (i = 1; i < argc; i++) + new[i] = xstrdup (argv[i]); + new[argc] = argv[argc]; + initial_argv = new; + initial_argc = argc; +} + +#endif + /* Reorder the elements of ARGV (assumed to have ARGC elements) so that the highest priority ones come first. Do not change the order of elements of equal priority. @@ -2900,7 +2940,7 @@ killed. */ error ("Unknown Emacs executable"); if (!file_access_p (initial_emacs_executable, F_OK)) - error ("Emacs executable \"%s\" can't be found", initial_argv[0]); + error ("Emacs executable \"%s\" can't be found", initial_argv0); } #endif diff --git a/src/lisp.h b/src/lisp.h index 243e8cc7f36..bca58b9c12d 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -5136,8 +5136,11 @@ extern void init_frame_once (void); extern void syms_of_frame (void); /* Defined in emacs.c. */ +#ifndef WINDOWSNT extern char **initial_argv; extern int initial_argc; +#endif +extern char *initial_argv0; extern char const *emacs_wd; #if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK) || defined (HAVE_NS) extern bool display_arg; diff --git a/src/pgtkterm.c b/src/pgtkterm.c index a2e23a5616b..3d59a239ccd 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -7075,7 +7075,7 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) argv[argc] = 0; argc = 0; - argv[argc++] = initial_argv[0]; + argv[argc++] = initial_argv0; if (strlen (dpy_name) != 0) { diff --git a/src/sysdep.c b/src/sysdep.c index a161b4af100..042de2acf80 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2854,8 +2854,7 @@ emacs_perror (char const *message) { int err = errno; char const *error_string = emacs_strerror (err); - char const *command = (initial_argv && initial_argv[0] - ? initial_argv[0] : "emacs"); + char const *command = (initial_argv0 ? initial_argv0 : "emacs"); /* Write it out all at once, if it's short; this is less likely to be interleaved with other output. */ char buf[min (PIPE_BUF, MAX_ALLOCA)]; diff --git a/src/xterm.c b/src/xterm.c index b21efd5a2a2..18a9231e75a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -30619,7 +30619,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) argv[argc] = 0; argc = 0; - argv[argc++] = initial_argv[0]; + argv[argc++] = initial_argv0; if (! NILP (display_name)) { |
