summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2022-04-17 17:20:03 +0300
committerEli Zaretskii <eliz@gnu.org>2022-04-17 17:20:03 +0300
commit5a63af876bc131b07e066aa9d60780de0562bcb0 (patch)
tree5897563f39ec6da237688abc887572d042bc73be /src/w32.c
parent56d5a4079423aa22d2203a342439df7359eb1c18 (diff)
downloademacs-5a63af876bc131b07e066aa9d60780de0562bcb0.tar.gz
Fix 'restart-emacs' on MS-Windows
* src/w32.c (w32_reexec_emacs): New function, emulation of 'execvp' on Posix systems. * src/w32.h (w32_reexec_emacs): Add prototype. * src/emacs.c (main) [WINDOWSNT]: Save the original command line and working directory. (Fkill_emacs) [WINDOWSNT]: Call 'w32_reexec_emacs' instead of 'execvp'. (Bug#17036)
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/w32.c b/src/w32.c
index 0dc874eac40..acd7d004e53 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10614,6 +10614,49 @@ realpath (const char *file_name, char *resolved_name)
return xstrdup (tgt);
}
+/* A replacement for Posix execvp, used to restart Emacs. This is
+ needed because the low-level Windows API to start processes accepts
+ the command-line arguments as a single string, so we cannot safely
+ use the MSVCRT execvp emulation, because elements of argv[] that
+ have embedded blanks and tabs will not be passed correctly to the
+ restarted Emacs. */
+int
+w32_reexec_emacs (char *cmd_line, const char *wdir)
+{
+ STARTUPINFO si;
+ SECURITY_ATTRIBUTES sec_attrs;
+ BOOL status;
+ PROCESS_INFORMATION proc_info;
+
+ GetStartupInfo (&si); /* Use the same startup info as the caller. */
+ sec_attrs.nLength = sizeof (sec_attrs);
+ sec_attrs.lpSecurityDescriptor = NULL;
+ sec_attrs.bInheritHandle = FALSE;
+
+ /* Make sure we are in the original directory, in case the command
+ line specifies the program as a relative file name. */
+ chdir (wdir);
+
+ status = CreateProcess (NULL, /* program */
+ cmd_line, /* command line */
+ &sec_attrs, /* process attributes */
+ NULL, /* thread attributes */
+ TRUE, /* inherit handles? */
+ NORMAL_PRIORITY_CLASS,
+ NULL, /* environment */
+ wdir, /* initial directory */
+ &si, /* startup info */
+ &proc_info);
+ if (status)
+ {
+ CloseHandle (proc_info.hThread);
+ CloseHandle (proc_info.hProcess);
+ exit (0);
+ }
+ errno = ENOEXEC;
+ return -1;
+}
+
/*
globals_of_w32 is used to initialize those global variables that
must always be initialized on startup even when the global variable