diff options
| author | Eli Zaretskii | 2013-12-06 17:55:08 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2013-12-06 17:55:08 +0200 |
| commit | 17788cb3da557d2d5c2dda8f7dedb80999a48242 (patch) | |
| tree | 4f461dd94bb0a1e9ae12905ee76fda853f2e8bbe /src | |
| parent | 0cd7a14e577cae9c0713d1cfa549cfca3f0ca06c (diff) | |
| download | emacs-17788cb3da557d2d5c2dda8f7dedb80999a48242.tar.gz emacs-17788cb3da557d2d5c2dda8f7dedb80999a48242.zip | |
Converted spawnve, but not tested the result yet.
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexw32.c | 17 | ||||
| -rw-r--r-- | src/w32proc.c | 67 |
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! */ | ||
| 123 | int | 125 | int |
| 124 | open_input_file (file_data *p_file, char *filename) | 126 | open_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 | |||
| 722 | unexec (const char *new_name, const char *old_name) | 724 | unexec (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. */ | ||
| 1062 | static char * process_dir; | 1064 | static char * process_dir; |
| 1063 | 1065 | ||
| 1064 | static BOOL | 1066 | static 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. */ | ||
| 1374 | static void | 1385 | static void |
| 1375 | w32_executable_type (char * filename, | 1386 | w32_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 |