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)
This commit is contained in:
parent
56d5a40794
commit
5a63af876b
3 changed files with 58 additions and 0 deletions
12
src/emacs.c
12
src/emacs.c
|
@ -159,6 +159,10 @@ Lisp_Object empty_unibyte_string, empty_multibyte_string;
|
|||
#ifdef WINDOWSNT
|
||||
/* Cache for externally loaded libraries. */
|
||||
Lisp_Object Vlibrary_cache;
|
||||
/* Original command line string as received from the OS. */
|
||||
static char *initial_cmdline;
|
||||
/* Original working directory when invoked. */
|
||||
static const char *initial_wd;
|
||||
#endif
|
||||
|
||||
struct gflags gflags;
|
||||
|
@ -1319,6 +1323,7 @@ main (int argc, char **argv)
|
|||
}
|
||||
}
|
||||
init_heap (use_dynamic_heap);
|
||||
initial_cmdline = GetCommandLine ();
|
||||
#endif
|
||||
#if defined WINDOWSNT || defined HAVE_NTGUI
|
||||
/* Set global variables used to detect Windows version. Do this as
|
||||
|
@ -1465,6 +1470,9 @@ main (int argc, char **argv)
|
|||
#endif
|
||||
|
||||
emacs_wd = emacs_get_current_dir_name ();
|
||||
#ifdef WINDOWSNT
|
||||
initial_wd = emacs_wd;
|
||||
#endif
|
||||
#ifdef HAVE_PDUMPER
|
||||
if (dumped_with_pdumper_p ())
|
||||
pdumper_record_wd (emacs_wd);
|
||||
|
@ -2811,7 +2819,11 @@ killed. */
|
|||
(on some systems) with no argv. */
|
||||
if (initial_argc < 1)
|
||||
error ("No command line arguments known; unable to re-execute Emacs");
|
||||
#ifdef WINDOWSNT
|
||||
if (w32_reexec_emacs (initial_cmdline, initial_wd) < 1)
|
||||
#else
|
||||
if (execvp (*initial_argv, initial_argv) < 1)
|
||||
#endif
|
||||
error ("Unable to re-execute Emacs");
|
||||
}
|
||||
|
||||
|
|
43
src/w32.c
43
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
|
||||
|
|
|
@ -244,6 +244,9 @@ extern int w32_init_random (void *, ptrdiff_t);
|
|||
|
||||
extern Lisp_Object w32_read_registry (HKEY, Lisp_Object, Lisp_Object);
|
||||
|
||||
/* Used instead of execvp to restart Emacs. */
|
||||
extern int w32_reexec_emacs (char *, const char *);
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue