aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Schmidt2025-04-02 22:48:31 +0200
committerEli Zaretskii2025-04-13 11:33:30 +0300
commite82989757f42e95bf72a2a55de415a8162a55dc3 (patch)
treea403b48a17f89cc6a001eeeaad84a4e4e5c685bb
parent5665b446b7a5b2f6ff4d4e7ea9b2c91e0e733c92 (diff)
downloademacs-e82989757f42e95bf72a2a55de415a8162a55dc3.tar.gz
emacs-e82989757f42e95bf72a2a55de415a8162a55dc3.zip
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)
-rw-r--r--src/emacs.c50
-rw-r--r--src/lisp.h3
-rw-r--r--src/pgtkterm.c2
-rw-r--r--src/sysdep.c3
-rw-r--r--src/xterm.c2
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];
238HANDLE w32_daemon_event; 238HANDLE w32_daemon_event;
239#endif 239#endif
240 240
241/* Save argv and argc. */ 241/* Save argv and argc.
242
243 initial_argc, initial_argv:
244 A pristine copy of the command-line arguments as passed into main,
245 saved away before main has had a chance to modify them. On
246 Windows, we use initial_cmdline instead.
247
248 initial_argv0:
249 argv[0] as passed into main. Available on all ports.
250
251 initial_emacs_executable:
252 Path to the current executable. Based on argv[0] but verified to
253 point to an existing executable if non-NULL. */
254#ifndef WINDOWSNT
242char **initial_argv; 255char **initial_argv;
243int initial_argc; 256int initial_argc;
257#endif
258char *initial_argv0;
244static char *initial_emacs_executable = NULL; 259static char *initial_emacs_executable = NULL;
245 260
246/* The name of the working directory, or NULL if this info is unavailable. */ 261/* The name of the working directory, or NULL if this info is unavailable. */
247char const *emacs_wd; 262char const *emacs_wd;
248 263
264#ifndef WINDOWSNT
265static void copy_args (int argc, char **argv);
266#endif
249static void sort_args (int argc, char **argv); 267static void sort_args (int argc, char **argv);
250static void syms_of_emacs (void); 268static void syms_of_emacs (void);
251 269
@@ -476,9 +494,6 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
476 Lisp_Object raw_name; 494 Lisp_Object raw_name;
477 AUTO_STRING (slash_colon, "/:"); 495 AUTO_STRING (slash_colon, "/:");
478 496
479 initial_argv = argv;
480 initial_argc = argc;
481
482#ifdef WINDOWSNT 497#ifdef WINDOWSNT
483 /* Must use argv[0] converted to UTF-8, as it begets many standard 498 /* Must use argv[0] converted to UTF-8, as it begets many standard
484 file and directory names. */ 499 file and directory names. */
@@ -1396,6 +1411,11 @@ android_emacs_init (int argc, char **argv, char *dump_file)
1396 init_standard_fds (); 1411 init_standard_fds ();
1397 atexit (close_output_streams); 1412 atexit (close_output_streams);
1398 1413
1414#ifndef WINDOWSNT
1415 copy_args (argc, argv);
1416#endif
1417 initial_argv0 = argv[0];
1418
1399 /* Command-line argument processing. 1419 /* Command-line argument processing.
1400 1420
1401 The arguments in the argv[] array are sorted in the descending 1421 The arguments in the argv[] array are sorted in the descending
@@ -2696,6 +2716,26 @@ static const struct standard_args standard_args[] =
2696 { "-kill", "--kill", -10, 0 }, 2716 { "-kill", "--kill", -10, 0 },
2697}; 2717};
2698 2718
2719#ifndef WINDOWSNT
2720
2721/* Copy the elements of ARGV (assumed to have ARGC elements) and store
2722 the copy in initial_argv. Store ARGC in initial_argc. */
2723
2724static void
2725copy_args (int argc, char **argv)
2726{
2727 char **new = xmalloc ((argc + 1) * sizeof *new);
2728 int i;
2729 new[0] = argv[0];
2730 for (i = 1; i < argc; i++)
2731 new[i] = xstrdup (argv[i]);
2732 new[argc] = argv[argc];
2733 initial_argv = new;
2734 initial_argc = argc;
2735}
2736
2737#endif
2738
2699/* Reorder the elements of ARGV (assumed to have ARGC elements) 2739/* Reorder the elements of ARGV (assumed to have ARGC elements)
2700 so that the highest priority ones come first. 2740 so that the highest priority ones come first.
2701 Do not change the order of elements of equal priority. 2741 Do not change the order of elements of equal priority.
@@ -2900,7 +2940,7 @@ killed. */
2900 error ("Unknown Emacs executable"); 2940 error ("Unknown Emacs executable");
2901 2941
2902 if (!file_access_p (initial_emacs_executable, F_OK)) 2942 if (!file_access_p (initial_emacs_executable, F_OK))
2903 error ("Emacs executable \"%s\" can't be found", initial_argv[0]); 2943 error ("Emacs executable \"%s\" can't be found", initial_argv0);
2904 } 2944 }
2905#endif 2945#endif
2906 2946
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);
5136extern void syms_of_frame (void); 5136extern void syms_of_frame (void);
5137 5137
5138/* Defined in emacs.c. */ 5138/* Defined in emacs.c. */
5139#ifndef WINDOWSNT
5139extern char **initial_argv; 5140extern char **initial_argv;
5140extern int initial_argc; 5141extern int initial_argc;
5142#endif
5143extern char *initial_argv0;
5141extern char const *emacs_wd; 5144extern char const *emacs_wd;
5142#if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK) || defined (HAVE_NS) 5145#if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK) || defined (HAVE_NS)
5143extern bool display_arg; 5146extern 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)
7075 argv[argc] = 0; 7075 argv[argc] = 0;
7076 7076
7077 argc = 0; 7077 argc = 0;
7078 argv[argc++] = initial_argv[0]; 7078 argv[argc++] = initial_argv0;
7079 7079
7080 if (strlen (dpy_name) != 0) 7080 if (strlen (dpy_name) != 0)
7081 { 7081 {
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)
2854{ 2854{
2855 int err = errno; 2855 int err = errno;
2856 char const *error_string = emacs_strerror (err); 2856 char const *error_string = emacs_strerror (err);
2857 char const *command = (initial_argv && initial_argv[0] 2857 char const *command = (initial_argv0 ? initial_argv0 : "emacs");
2858 ? initial_argv[0] : "emacs");
2859 /* Write it out all at once, if it's short; this is less likely to 2858 /* Write it out all at once, if it's short; this is less likely to
2860 be interleaved with other output. */ 2859 be interleaved with other output. */
2861 char buf[min (PIPE_BUF, MAX_ALLOCA)]; 2860 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)
30619 argv[argc] = 0; 30619 argv[argc] = 0;
30620 30620
30621 argc = 0; 30621 argc = 0;
30622 argv[argc++] = initial_argv[0]; 30622 argv[argc++] = initial_argv0;
30623 30623
30624 if (! NILP (display_name)) 30624 if (! NILP (display_name))
30625 { 30625 {