/* File handling. */
+/* Implementation note: this and the next functions work with ANSI
+ codepage encoded file names! */
int
open_input_file (file_data *p_file, char *filename)
{
void *file_base;
unsigned long size, upper_size;
- file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ file = CreateFileA (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (file == INVALID_HANDLE_VALUE)
return FALSE;
creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard
links to the same file, which defeats the purpose of these hard
links: being able to run previous builds. */
- DeleteFile (filename);
- file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ DeleteFileA (filename);
+ file = CreateFileA (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (file == INVALID_HANDLE_VALUE)
return FALSE;
unexec (const char *new_name, const char *old_name)
{
file_data in_file, out_file;
- char out_filename[MAX_PATH], in_filename[MAX_PATH];
+ char out_filename[MAX_PATH], in_filename[MAX_PATH], new_name_a[MAX_PATH];
unsigned long size;
char *p;
char *q;
*p = '/';
strcpy (out_filename, in_filename);
+ filename_to_ansi (new_name, new_name_a);
/* Change the base of the output filename to match the requested name. */
if ((p = strrchr (out_filename, '/')) == NULL)
abort ();
/* The filenames have already been expanded, and will be in Unix
format, so it is safe to expect an absolute name. */
- if ((q = strrchr (new_name, '/')) == NULL)
+ if ((q = strrchr (new_name_a, '/')) == NULL)
abort ();
strcpy (p, q);
#include <fcntl.h>
#include <signal.h>
#include <sys/file.h>
+#include <mbstring.h>
/* must include CRT headers *before* config.h */
#include <config.h>
return 0;
}
-/* To avoid Emacs changing directory, we just record here the directory
- the new process should start in. This is set just before calling
- sys_spawnve, and is not generally valid at any other time. */
+/* To avoid Emacs changing directory, we just record here the
+ directory the new process should start in. This is set just before
+ calling sys_spawnve, and is not generally valid at any other time.
+ Note that this directory's name is UTF-8 encoded. */
static char * process_dir;
static BOOL
SECURITY_DESCRIPTOR sec_desc;
#endif
DWORD flags;
- char dir[ MAXPATHLEN ];
+ char dir[ MAX_PATH ];
+ char *p;
if (cp == NULL) emacs_abort ();
sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */;
sec_attrs.bInheritHandle = FALSE;
- strcpy (dir, process_dir);
- unixtodos_filename (dir);
+ filename_to_ansi (process_dir, dir);
+ /* Can't use unixtodos_filename here, since that needs its file name
+ argument encoded in UTF-8. OTOH, process_dir, which _is_ in
+ UTF-8, points, to the directory computed by our caller, and we
+ don't want to modify that, either. */
+ for (p = dir; *p; p = CharNextA (p))
+ if (*p == '/')
+ *p = '\\';
flags = (!NILP (Vw32_start_process_share_console)
? CREATE_NEW_PROCESS_GROUP
: CREATE_NEW_CONSOLE);
if (NILP (Vw32_start_process_inherit_error_mode))
flags |= CREATE_DEFAULT_ERROR_MODE;
- if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
- flags, env, dir, &start, &cp->procinfo))
+ if (!CreateProcessA (exe, cmdline, &sec_attrs, NULL, TRUE,
+ flags, env, dir, &start, &cp->procinfo))
goto EH_Fail;
cp->pid = (int) cp->procinfo.dwProcessId;
# define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER
#endif
+/* Implementation note: This function works with file names encoded in
+ the current ANSI codepage. */
static void
w32_executable_type (char * filename,
int * is_dos_app,
char *sepchars = " \t*?";
/* This is for native w32 apps; modified below for Cygwin apps. */
char escape_char = '\\';
+ char cmdname_a[MAX_PATH];
/* We don't care about the other modes */
if (mode != _P_NOWAIT)
return -1;
}
- /* Handle executable names without an executable suffix. */
- program = build_string (cmdname);
- if (NILP (Ffile_executable_p (program)))
+ /* Handle executable names without an executable suffix. The caller
+ already searched exec-path and verified the file is executable,
+ but start-process doesn't do that for file names that are already
+ absolute. So we double-check this here, just in case. */
+ if (faccessat (AT_FDCWD, cmdname, X_OK, AT_EACCESS) != 0)
{
struct gcpro gcpro1;
+ program = build_string (cmdname);
full = Qnil;
GCPRO1 (program);
openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
errno = EINVAL;
return -1;
}
- program = full;
+ program = ENCODE_FILE (full);
+ cmdname = SDATA (program);
}
/* make sure argv[0] and cmdname are both in DOS format */
- cmdname = SDATA (program);
unixtodos_filename (cmdname);
+ /* argv[0] was encoded by caller using ENCODE_FILE, so it is in
+ UTF-8. All the other arguments are encoded by ENCODE_SYSTEM or
+ some such, and are in some ANSI codepage. We need to have
+ argv[0] encoded in ANSI codepage. */
+ filename_to_ansi (cmdname, cmdname_a);
+ /* We explicitly require that the command's file name be encodable
+ in the current ANSI codepage, because we will be invoking it via
+ the ANSI APIs. */
+ if (_mbspbrk (cmdname_a, "?"))
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ /* From here on, CMDNAME is an ANSI-encoded string. */
+ cmdname = cmdname_a
argv[0] = cmdname;
/* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows
while leaving the real app name as argv[0]. */
if (is_dos_app)
{
- cmdname = alloca (MAXPATHLEN);
+ char *p;
+
+ cmdname = alloca (MAX_PATH);
if (egetenv ("CMDPROXY"))
strcpy (cmdname, egetenv ("CMDPROXY"));
else
strcpy (cmdname, SDATA (Vinvocation_directory));
strcat (cmdname, "cmdproxy.exe");
}
- unixtodos_filename (cmdname);
+
+ /* Can't use unixtodos_filename here, since that needs its file
+ name argument encoded in UTF-8. */
+ for (p = cmdname; *p; p = CharNextA (p))
+ if (*p == '/')
+ *p = '\\';
}
/* we have to do some conjuring here to put argv and envp into the