aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2013-12-06 17:55:08 +0200
committerEli Zaretskii2013-12-06 17:55:08 +0200
commit17788cb3da557d2d5c2dda8f7dedb80999a48242 (patch)
tree4f461dd94bb0a1e9ae12905ee76fda853f2e8bbe
parent0cd7a14e577cae9c0713d1cfa549cfca3f0ca06c (diff)
downloademacs-17788cb3da557d2d5c2dda8f7dedb80999a48242.tar.gz
emacs-17788cb3da557d2d5c2dda8f7dedb80999a48242.zip
Converted spawnve, but not tested the result yet.
-rw-r--r--src/unexw32.c17
-rw-r--r--src/w32proc.c67
2 files changed, 62 insertions, 22 deletions
diff --git a/src/unexw32.c b/src/unexw32.c
index 5320ec1e371..3dfce22d757 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -120,6 +120,8 @@ _start (void)
120 120
121/* File handling. */ 121/* File handling. */
122 122
123/* Implementation note: this and the next functions work with ANSI
124 codepage encoded file names! */
123int 125int
124open_input_file (file_data *p_file, char *filename) 126open_input_file (file_data *p_file, char *filename)
125{ 127{
@@ -128,8 +130,8 @@ open_input_file (file_data *p_file, char *filename)
128 void *file_base; 130 void *file_base;
129 unsigned long size, upper_size; 131 unsigned long size, upper_size;
130 132
131 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, 133 file = CreateFileA (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
132 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 134 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
133 if (file == INVALID_HANDLE_VALUE) 135 if (file == INVALID_HANDLE_VALUE)
134 return FALSE; 136 return FALSE;
135 137
@@ -166,9 +168,9 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
166 creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard 168 creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard
167 links to the same file, which defeats the purpose of these hard 169 links to the same file, which defeats the purpose of these hard
168 links: being able to run previous builds. */ 170 links: being able to run previous builds. */
169 DeleteFile (filename); 171 DeleteFileA (filename);
170 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 172 file = CreateFileA (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
171 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 173 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
172 if (file == INVALID_HANDLE_VALUE) 174 if (file == INVALID_HANDLE_VALUE)
173 return FALSE; 175 return FALSE;
174 176
@@ -722,7 +724,7 @@ void
722unexec (const char *new_name, const char *old_name) 724unexec (const char *new_name, const char *old_name)
723{ 725{
724 file_data in_file, out_file; 726 file_data in_file, out_file;
725 char out_filename[MAX_PATH], in_filename[MAX_PATH]; 727 char out_filename[MAX_PATH], in_filename[MAX_PATH], new_name_a[MAX_PATH];
726 unsigned long size; 728 unsigned long size;
727 char *p; 729 char *p;
728 char *q; 730 char *q;
@@ -738,13 +740,14 @@ unexec (const char *new_name, const char *old_name)
738 *p = '/'; 740 *p = '/';
739 741
740 strcpy (out_filename, in_filename); 742 strcpy (out_filename, in_filename);
743 filename_to_ansi (new_name, new_name_a);
741 744
742 /* Change the base of the output filename to match the requested name. */ 745 /* Change the base of the output filename to match the requested name. */
743 if ((p = strrchr (out_filename, '/')) == NULL) 746 if ((p = strrchr (out_filename, '/')) == NULL)
744 abort (); 747 abort ();
745 /* The filenames have already been expanded, and will be in Unix 748 /* The filenames have already been expanded, and will be in Unix
746 format, so it is safe to expect an absolute name. */ 749 format, so it is safe to expect an absolute name. */
747 if ((q = strrchr (new_name, '/')) == NULL) 750 if ((q = strrchr (new_name_a, '/')) == NULL)
748 abort (); 751 abort ();
749 strcpy (p, q); 752 strcpy (p, q);
750 753
diff --git a/src/w32proc.c b/src/w32proc.c
index de4e9103173..76d8bb19cf8 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#include <fcntl.h> 30#include <fcntl.h>
31#include <signal.h> 31#include <signal.h>
32#include <sys/file.h> 32#include <sys/file.h>
33#include <mbstring.h>
33 34
34/* must include CRT headers *before* config.h */ 35/* must include CRT headers *before* config.h */
35#include <config.h> 36#include <config.h>
@@ -1056,9 +1057,10 @@ reader_thread (void *arg)
1056 return 0; 1057 return 0;
1057} 1058}
1058 1059
1059/* To avoid Emacs changing directory, we just record here the directory 1060/* To avoid Emacs changing directory, we just record here the
1060 the new process should start in. This is set just before calling 1061 directory the new process should start in. This is set just before
1061 sys_spawnve, and is not generally valid at any other time. */ 1062 calling sys_spawnve, and is not generally valid at any other time.
1063 Note that this directory's name is UTF-8 encoded. */
1062static char * process_dir; 1064static char * process_dir;
1063 1065
1064static BOOL 1066static BOOL
@@ -1071,7 +1073,8 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app,
1071 SECURITY_DESCRIPTOR sec_desc; 1073 SECURITY_DESCRIPTOR sec_desc;
1072#endif 1074#endif
1073 DWORD flags; 1075 DWORD flags;
1074 char dir[ MAXPATHLEN ]; 1076 char dir[ MAX_PATH ];
1077 char *p;
1075 1078
1076 if (cp == NULL) emacs_abort (); 1079 if (cp == NULL) emacs_abort ();
1077 1080
@@ -1101,16 +1104,22 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app,
1101 sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */; 1104 sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */;
1102 sec_attrs.bInheritHandle = FALSE; 1105 sec_attrs.bInheritHandle = FALSE;
1103 1106
1104 strcpy (dir, process_dir); 1107 filename_to_ansi (process_dir, dir);
1105 unixtodos_filename (dir); 1108 /* Can't use unixtodos_filename here, since that needs its file name
1109 argument encoded in UTF-8. OTOH, process_dir, which _is_ in
1110 UTF-8, points, to the directory computed by our caller, and we
1111 don't want to modify that, either. */
1112 for (p = dir; *p; p = CharNextA (p))
1113 if (*p == '/')
1114 *p = '\\';
1106 1115
1107 flags = (!NILP (Vw32_start_process_share_console) 1116 flags = (!NILP (Vw32_start_process_share_console)
1108 ? CREATE_NEW_PROCESS_GROUP 1117 ? CREATE_NEW_PROCESS_GROUP
1109 : CREATE_NEW_CONSOLE); 1118 : CREATE_NEW_CONSOLE);
1110 if (NILP (Vw32_start_process_inherit_error_mode)) 1119 if (NILP (Vw32_start_process_inherit_error_mode))
1111 flags |= CREATE_DEFAULT_ERROR_MODE; 1120 flags |= CREATE_DEFAULT_ERROR_MODE;
1112 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, 1121 if (!CreateProcessA (exe, cmdline, &sec_attrs, NULL, TRUE,
1113 flags, env, dir, &start, &cp->procinfo)) 1122 flags, env, dir, &start, &cp->procinfo))
1114 goto EH_Fail; 1123 goto EH_Fail;
1115 1124
1116 cp->pid = (int) cp->procinfo.dwProcessId; 1125 cp->pid = (int) cp->procinfo.dwProcessId;
@@ -1371,6 +1380,8 @@ waitpid (pid_t pid, int *status, int options)
1371# define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER 1380# define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER
1372#endif 1381#endif
1373 1382
1383/* Implementation note: This function works with file names encoded in
1384 the current ANSI codepage. */
1374static void 1385static void
1375w32_executable_type (char * filename, 1386w32_executable_type (char * filename,
1376 int * is_dos_app, 1387 int * is_dos_app,
@@ -1561,6 +1572,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1561 char *sepchars = " \t*?"; 1572 char *sepchars = " \t*?";
1562 /* This is for native w32 apps; modified below for Cygwin apps. */ 1573 /* This is for native w32 apps; modified below for Cygwin apps. */
1563 char escape_char = '\\'; 1574 char escape_char = '\\';
1575 char cmdname_a[MAX_PATH];
1564 1576
1565 /* We don't care about the other modes */ 1577 /* We don't care about the other modes */
1566 if (mode != _P_NOWAIT) 1578 if (mode != _P_NOWAIT)
@@ -1569,12 +1581,15 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1569 return -1; 1581 return -1;
1570 } 1582 }
1571 1583
1572 /* Handle executable names without an executable suffix. */ 1584 /* Handle executable names without an executable suffix. The caller
1573 program = build_string (cmdname); 1585 already searched exec-path and verified the file is executable,
1574 if (NILP (Ffile_executable_p (program))) 1586 but start-process doesn't do that for file names that are already
1587 absolute. So we double-check this here, just in case. */
1588 if (faccessat (AT_FDCWD, cmdname, X_OK, AT_EACCESS) != 0)
1575 { 1589 {
1576 struct gcpro gcpro1; 1590 struct gcpro gcpro1;
1577 1591
1592 program = build_string (cmdname);
1578 full = Qnil; 1593 full = Qnil;
1579 GCPRO1 (program); 1594 GCPRO1 (program);
1580 openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK)); 1595 openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
@@ -1584,12 +1599,27 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1584 errno = EINVAL; 1599 errno = EINVAL;
1585 return -1; 1600 return -1;
1586 } 1601 }
1587 program = full; 1602 program = ENCODE_FILE (full);
1603 cmdname = SDATA (program);
1588 } 1604 }
1589 1605
1590 /* make sure argv[0] and cmdname are both in DOS format */ 1606 /* make sure argv[0] and cmdname are both in DOS format */
1591 cmdname = SDATA (program);
1592 unixtodos_filename (cmdname); 1607 unixtodos_filename (cmdname);
1608 /* argv[0] was encoded by caller using ENCODE_FILE, so it is in
1609 UTF-8. All the other arguments are encoded by ENCODE_SYSTEM or
1610 some such, and are in some ANSI codepage. We need to have
1611 argv[0] encoded in ANSI codepage. */
1612 filename_to_ansi (cmdname, cmdname_a);
1613 /* We explicitly require that the command's file name be encodable
1614 in the current ANSI codepage, because we will be invoking it via
1615 the ANSI APIs. */
1616 if (_mbspbrk (cmdname_a, "?"))
1617 {
1618 errno = ENOENT;
1619 return -1;
1620 }
1621 /* From here on, CMDNAME is an ANSI-encoded string. */
1622 cmdname = cmdname_a
1593 argv[0] = cmdname; 1623 argv[0] = cmdname;
1594 1624
1595 /* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows 1625 /* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows
@@ -1607,7 +1637,9 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1607 while leaving the real app name as argv[0]. */ 1637 while leaving the real app name as argv[0]. */
1608 if (is_dos_app) 1638 if (is_dos_app)
1609 { 1639 {
1610 cmdname = alloca (MAXPATHLEN); 1640 char *p;
1641
1642 cmdname = alloca (MAX_PATH);
1611 if (egetenv ("CMDPROXY")) 1643 if (egetenv ("CMDPROXY"))
1612 strcpy (cmdname, egetenv ("CMDPROXY")); 1644 strcpy (cmdname, egetenv ("CMDPROXY"));
1613 else 1645 else
@@ -1615,7 +1647,12 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1615 strcpy (cmdname, SDATA (Vinvocation_directory)); 1647 strcpy (cmdname, SDATA (Vinvocation_directory));
1616 strcat (cmdname, "cmdproxy.exe"); 1648 strcat (cmdname, "cmdproxy.exe");
1617 } 1649 }
1618 unixtodos_filename (cmdname); 1650
1651 /* Can't use unixtodos_filename here, since that needs its file
1652 name argument encoded in UTF-8. */
1653 for (p = cmdname; *p; p = CharNextA (p))
1654 if (*p == '/')
1655 *p = '\\';
1619 } 1656 }
1620 1657
1621 /* we have to do some conjuring here to put argv and envp into the 1658 /* we have to do some conjuring here to put argv and envp into the