diff options
| author | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
|---|---|---|
| committer | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
| commit | 39372e1a1032521be74575bb06f95a3898fbae30 (patch) | |
| tree | 754bd242a23d2358ea116126fcb0a629947bd9ec /src/w32proc.c | |
| parent | 6a3121904d76e3b2f63007341d48c5c1af55de80 (diff) | |
| parent | e11aaee266da52937a3a031cb108fe13f68958c3 (diff) | |
| download | emacs-39372e1a1032521be74575bb06f95a3898fbae30.tar.gz emacs-39372e1a1032521be74575bb06f95a3898fbae30.zip | |
merge from trunk
Diffstat (limited to 'src/w32proc.c')
| -rw-r--r-- | src/w32proc.c | 844 |
1 files changed, 681 insertions, 163 deletions
diff --git a/src/w32proc.c b/src/w32proc.c index 599cb3c3227..cdb257391ce 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Process support for GNU Emacs on the Microsoft Windows API. | 1 | /* Process support for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1992, 1995, 1999-2013 Free Software Foundation, Inc. | 2 | |
| 3 | Copyright (C) 1992, 1995, 1999-2015 Free Software Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -21,14 +22,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 21 | Adapted from alarm.c by Tim Fleehart | 22 | Adapted from alarm.c by Tim Fleehart |
| 22 | */ | 23 | */ |
| 23 | 24 | ||
| 25 | #include <mingw_time.h> | ||
| 24 | #include <stdio.h> | 26 | #include <stdio.h> |
| 25 | #include <stdlib.h> | 27 | #include <stdlib.h> |
| 26 | #include <errno.h> | 28 | #include <errno.h> |
| 27 | #include <ctype.h> | 29 | #include <ctype.h> |
| 28 | #include <io.h> | 30 | #include <io.h> |
| 29 | #include <fcntl.h> | 31 | #include <fcntl.h> |
| 32 | #include <unistd.h> | ||
| 30 | #include <signal.h> | 33 | #include <signal.h> |
| 31 | #include <sys/file.h> | 34 | #include <sys/file.h> |
| 35 | #include <mbstring.h> | ||
| 36 | #include <locale.h> | ||
| 32 | 37 | ||
| 33 | /* must include CRT headers *before* config.h */ | 38 | /* must include CRT headers *before* config.h */ |
| 34 | #include <config.h> | 39 | #include <config.h> |
| @@ -40,8 +45,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 40 | #undef kill | 45 | #undef kill |
| 41 | 46 | ||
| 42 | #include <windows.h> | 47 | #include <windows.h> |
| 43 | #ifdef __GNUC__ | 48 | #if defined(__GNUC__) && !defined(__MINGW64__) |
| 44 | /* This definition is missing from mingw32 headers. */ | 49 | /* This definition is missing from mingw.org headers, but not MinGW64 |
| 50 | headers. */ | ||
| 45 | extern BOOL WINAPI IsValidLocale (LCID, DWORD); | 51 | extern BOOL WINAPI IsValidLocale (LCID, DWORD); |
| 46 | #endif | 52 | #endif |
| 47 | 53 | ||
| @@ -54,12 +60,9 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD); | |||
| 54 | #include "w32.h" | 60 | #include "w32.h" |
| 55 | #include "w32common.h" | 61 | #include "w32common.h" |
| 56 | #include "w32heap.h" | 62 | #include "w32heap.h" |
| 57 | #include "systime.h" | 63 | #include "syswait.h" /* for WNOHANG */ |
| 58 | #include "syswait.h" | ||
| 59 | #include "process.h" | ||
| 60 | #include "syssignal.h" | 64 | #include "syssignal.h" |
| 61 | #include "w32term.h" | 65 | #include "w32term.h" |
| 62 | #include "dispextern.h" /* for xstrcasecmp */ | ||
| 63 | #include "coding.h" | 66 | #include "coding.h" |
| 64 | 67 | ||
| 65 | #define RVA_TO_PTR(var,section,filedata) \ | 68 | #define RVA_TO_PTR(var,section,filedata) \ |
| @@ -67,8 +70,6 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD); | |||
| 67 | + ((DWORD_PTR)(var) - (section)->VirtualAddress) \ | 70 | + ((DWORD_PTR)(var) - (section)->VirtualAddress) \ |
| 68 | + (filedata).file_base)) | 71 | + (filedata).file_base)) |
| 69 | 72 | ||
| 70 | Lisp_Object Qhigh, Qlow; | ||
| 71 | |||
| 72 | /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */ | 73 | /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */ |
| 73 | static signal_handler sig_handlers[NSIG]; | 74 | static signal_handler sig_handlers[NSIG]; |
| 74 | 75 | ||
| @@ -562,7 +563,7 @@ init_timers (void) | |||
| 562 | static int | 563 | static int |
| 563 | start_timer_thread (int which) | 564 | start_timer_thread (int which) |
| 564 | { | 565 | { |
| 565 | DWORD exit_code; | 566 | DWORD exit_code, tid; |
| 566 | HANDLE th; | 567 | HANDLE th; |
| 567 | struct itimer_data *itimer = | 568 | struct itimer_data *itimer = |
| 568 | (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; | 569 | (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; |
| @@ -600,7 +601,7 @@ start_timer_thread (int which) | |||
| 600 | the way of threads we start to wait for subprocesses. See also | 601 | the way of threads we start to wait for subprocesses. See also |
| 601 | new_child below. */ | 602 | new_child below. */ |
| 602 | itimer->timer_thread = CreateThread (NULL, 64 * 1024, timer_loop, | 603 | itimer->timer_thread = CreateThread (NULL, 64 * 1024, timer_loop, |
| 603 | (void *)itimer, 0x00010000, NULL); | 604 | (void *)itimer, 0x00010000, &tid); |
| 604 | 605 | ||
| 605 | if (!itimer->timer_thread) | 606 | if (!itimer->timer_thread) |
| 606 | { | 607 | { |
| @@ -783,6 +784,138 @@ alarm (int seconds) | |||
| 783 | #endif | 784 | #endif |
| 784 | } | 785 | } |
| 785 | 786 | ||
| 787 | |||
| 788 | |||
| 789 | /* Here's an overview of how support for subprocesses and | ||
| 790 | network/serial streams is implemented on MS-Windows. | ||
| 791 | |||
| 792 | The management of both subprocesses and network/serial streams | ||
| 793 | circles around the child_procs[] array, which can record up to the | ||
| 794 | grand total of MAX_CHILDREN (= 32) of these. (The reasons for the | ||
| 795 | 32 limitation will become clear below.) Each member of | ||
| 796 | child_procs[] is a child_process structure, defined on w32.h. | ||
| 797 | |||
| 798 | A related data structure is the fd_info[] array, which holds twice | ||
| 799 | as many members, 64, and records the information about file | ||
| 800 | descriptors used for communicating with subprocesses and | ||
| 801 | network/serial devices. Each member of the array is the filedesc | ||
| 802 | structure, which records the Windows handle for communications, | ||
| 803 | such as the read end of the pipe to a subprocess, a socket handle, | ||
| 804 | etc. | ||
| 805 | |||
| 806 | Both these arrays reference each other: there's a member of | ||
| 807 | child_process structure that records the corresponding file | ||
| 808 | descriptor, and there's a member of filedesc structure that holds a | ||
| 809 | pointer to the corresponding child_process. | ||
| 810 | |||
| 811 | Whenever Emacs starts a subprocess or opens a network/serial | ||
| 812 | stream, the function new_child is called to prepare a new | ||
| 813 | child_process structure. new_child looks for the first vacant slot | ||
| 814 | in the child_procs[] array, initializes it, and starts a "reader | ||
| 815 | thread" that will watch the output of the subprocess/stream and its | ||
| 816 | status. (If no vacant slot can be found, new_child returns a | ||
| 817 | failure indication to its caller, and the higher-level Emacs | ||
| 818 | primitive that called it will then fail with EMFILE or EAGAIN.) | ||
| 819 | |||
| 820 | The reader thread started by new_child communicates with the main | ||
| 821 | (a.k.a. "Lisp") thread via two event objects and a status, all of | ||
| 822 | them recorded by the members of the child_process structure in | ||
| 823 | child_procs[]. The event objects serve as semaphores between the | ||
| 824 | reader thread and the 'pselect' emulation in sys_select, as follows: | ||
| 825 | |||
| 826 | . Initially, the reader thread is waiting for the char_consumed | ||
| 827 | event to become signaled by sys_select, which is an indication | ||
| 828 | for the reader thread to go ahead and try reading more stuff | ||
| 829 | from the subprocess/stream. | ||
| 830 | |||
| 831 | . The reader thread then attempts to read by calling a | ||
| 832 | blocking-read function. When the read call returns, either | ||
| 833 | successfully or with some failure indication, the reader thread | ||
| 834 | updates the status of the read accordingly, and signals the 2nd | ||
| 835 | event object, char_avail, on whose handle sys_select is | ||
| 836 | waiting. This tells sys_select that the file descriptor | ||
| 837 | allocated for the subprocess or the the stream is ready to be | ||
| 838 | read from. | ||
| 839 | |||
| 840 | When the subprocess exits or the network/serial stream is closed, | ||
| 841 | the reader thread sets the status accordingly and exits. It also | ||
| 842 | exits when the main thread sets the status to STATUS_READ_ERROR | ||
| 843 | and/or the char_avail and char_consumed event handles become NULL; | ||
| 844 | this is how delete_child, called by Emacs when a subprocess or a | ||
| 845 | stream is terminated, terminates the reader thread as part of | ||
| 846 | deleting the child_process object. | ||
| 847 | |||
| 848 | The sys_select function emulates the Posix 'pselect' function; it | ||
| 849 | is needed because the Windows 'select' function supports only | ||
| 850 | network sockets, while Emacs expects 'pselect' to work for any file | ||
| 851 | descriptor, including pipes and serial streams. | ||
| 852 | |||
| 853 | When sys_select is called, it uses the information in fd_info[] | ||
| 854 | array to convert the file descriptors which it was asked to watch | ||
| 855 | into Windows handles. In general, the handle to watch is the | ||
| 856 | handle of the char_avail event of the child_process structure that | ||
| 857 | corresponds to the file descriptor. In addition, for subprocesses, | ||
| 858 | sys_select watches one more handle: the handle for the subprocess, | ||
| 859 | so that it could emulate the SIGCHLD signal when the subprocess | ||
| 860 | exits. | ||
| 861 | |||
| 862 | If file descriptor zero (stdin) doesn't have its bit set in the | ||
| 863 | 'rfds' argument to sys_select, the function always watches for | ||
| 864 | keyboard interrupts, to be able to interrupt the wait and return | ||
| 865 | when the user presses C-g. | ||
| 866 | |||
| 867 | Having collected the handles to watch, sys_select calls | ||
| 868 | WaitForMultipleObjects to wait for any one of them to become | ||
| 869 | signaled. Since WaitForMultipleObjects can only watch up to 64 | ||
| 870 | handles, Emacs on Windows is limited to maximum 32 child_process | ||
| 871 | objects (since a subprocess consumes 2 handles to be watched, see | ||
| 872 | above). | ||
| 873 | |||
| 874 | When any of the handles become signaled, sys_select does whatever | ||
| 875 | is appropriate for the corresponding child_process object: | ||
| 876 | |||
| 877 | . If it's a handle to the char_avail event, sys_select marks the | ||
| 878 | corresponding bit in 'rfds', and Emacs will then read from that | ||
| 879 | file descriptor. | ||
| 880 | |||
| 881 | . If it's a handle to the process, sys_select calls the SIGCHLD | ||
| 882 | handler, to inform Emacs of the fact that the subprocess | ||
| 883 | exited. | ||
| 884 | |||
| 885 | The waitpid emulation works very similar to sys_select, except that | ||
| 886 | it only watches handles of subprocesses, and doesn't synchronize | ||
| 887 | with the reader thread. | ||
| 888 | |||
| 889 | Because socket descriptors on Windows are handles, while Emacs | ||
| 890 | expects them to be file descriptors, all low-level I/O functions, | ||
| 891 | such as 'read' and 'write', and all socket operations, like | ||
| 892 | 'connect', 'recvfrom', 'accept', etc., are redirected to the | ||
| 893 | corresponding 'sys_*' functions, which must convert a file | ||
| 894 | descriptor to a handle using the fd_info[] array, and then invoke | ||
| 895 | the corresponding Windows API on the handle. Most of these | ||
| 896 | redirected 'sys_*' functions are implemented on w32.c. | ||
| 897 | |||
| 898 | When the file descriptor was produced by functions such as 'open', | ||
| 899 | the corresponding handle is obtained by calling _get_osfhandle. To | ||
| 900 | produce a file descriptor for a socket handle, which has no file | ||
| 901 | descriptor as far as Windows is concerned, the function | ||
| 902 | socket_to_fd opens the null device; the resulting file descriptor | ||
| 903 | will never be used directly in any I/O API, but serves as an index | ||
| 904 | into the fd_info[] array, where the socket handle is stored. The | ||
| 905 | SOCK_HANDLE macro retrieves the handle when given the file | ||
| 906 | descriptor. | ||
| 907 | |||
| 908 | The function sys_kill emulates the Posix 'kill' functionality to | ||
| 909 | terminate other processes. It does that by attaching to the | ||
| 910 | foreground window of the process and sending a Ctrl-C or Ctrl-BREAK | ||
| 911 | signal to the process; if that doesn't work, then it calls | ||
| 912 | TerminateProcess to forcibly terminate the process. Note that this | ||
| 913 | only terminates the immediate process whose PID was passed to | ||
| 914 | sys_kill; it doesn't terminate the child processes of that process. | ||
| 915 | This means, for example, that an Emacs subprocess run through a | ||
| 916 | shell might not be killed, because sys_kill will only terminate the | ||
| 917 | shell. (In practice, however, such problems are very rare.) */ | ||
| 918 | |||
| 786 | /* Defined in <process.h> which conflicts with the local copy */ | 919 | /* Defined in <process.h> which conflicts with the local copy */ |
| 787 | #define _P_NOWAIT 1 | 920 | #define _P_NOWAIT 1 |
| 788 | 921 | ||
| @@ -860,8 +993,6 @@ new_child (void) | |||
| 860 | cp->pid = -1; | 993 | cp->pid = -1; |
| 861 | cp->procinfo.hProcess = NULL; | 994 | cp->procinfo.hProcess = NULL; |
| 862 | cp->status = STATUS_READ_ERROR; | 995 | cp->status = STATUS_READ_ERROR; |
| 863 | cp->input_file = NULL; | ||
| 864 | cp->pending_deletion = 0; | ||
| 865 | 996 | ||
| 866 | /* use manual reset event so that select() will function properly */ | 997 | /* use manual reset event so that select() will function properly */ |
| 867 | cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL); | 998 | cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL); |
| @@ -910,21 +1041,6 @@ delete_child (child_process *cp) | |||
| 910 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) | 1041 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) |
| 911 | return; | 1042 | return; |
| 912 | 1043 | ||
| 913 | /* Delete the child's temporary input file, if any, that is pending | ||
| 914 | deletion. */ | ||
| 915 | if (cp->input_file) | ||
| 916 | { | ||
| 917 | if (cp->pending_deletion) | ||
| 918 | { | ||
| 919 | if (unlink (cp->input_file)) | ||
| 920 | DebPrint (("delete_child.unlink (%s) failed, errno: %d\n", | ||
| 921 | cp->input_file, errno)); | ||
| 922 | cp->pending_deletion = 0; | ||
| 923 | } | ||
| 924 | xfree (cp->input_file); | ||
| 925 | cp->input_file = NULL; | ||
| 926 | } | ||
| 927 | |||
| 928 | /* reap thread if necessary */ | 1044 | /* reap thread if necessary */ |
| 929 | if (cp->thrd) | 1045 | if (cp->thrd) |
| 930 | { | 1046 | { |
| @@ -990,6 +1106,18 @@ find_child_pid (DWORD pid) | |||
| 990 | return NULL; | 1106 | return NULL; |
| 991 | } | 1107 | } |
| 992 | 1108 | ||
| 1109 | void | ||
| 1110 | release_listen_threads (void) | ||
| 1111 | { | ||
| 1112 | int i; | ||
| 1113 | |||
| 1114 | for (i = child_proc_count - 1; i >= 0; i--) | ||
| 1115 | { | ||
| 1116 | if (CHILD_ACTIVE (&child_procs[i]) | ||
| 1117 | && (fd_info[child_procs[i].fd].flags & FILE_LISTEN)) | ||
| 1118 | child_procs[i].status = STATUS_READ_ERROR; | ||
| 1119 | } | ||
| 1120 | } | ||
| 993 | 1121 | ||
| 994 | /* Thread proc for child process and socket reader threads. Each thread | 1122 | /* Thread proc for child process and socket reader threads. Each thread |
| 995 | is normally blocked until woken by select() to check for input by | 1123 | is normally blocked until woken by select() to check for input by |
| @@ -1013,7 +1141,9 @@ reader_thread (void *arg) | |||
| 1013 | { | 1141 | { |
| 1014 | int rc; | 1142 | int rc; |
| 1015 | 1143 | ||
| 1016 | if (cp->fd >= 0 && fd_info[cp->fd].flags & FILE_LISTEN) | 1144 | if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_CONNECT) != 0) |
| 1145 | rc = _sys_wait_connect (cp->fd); | ||
| 1146 | else if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_LISTEN) != 0) | ||
| 1017 | rc = _sys_wait_accept (cp->fd); | 1147 | rc = _sys_wait_accept (cp->fd); |
| 1018 | else | 1148 | else |
| 1019 | rc = _sys_read_ahead (cp->fd); | 1149 | rc = _sys_read_ahead (cp->fd); |
| @@ -1033,8 +1163,8 @@ reader_thread (void *arg) | |||
| 1033 | return 1; | 1163 | return 1; |
| 1034 | } | 1164 | } |
| 1035 | 1165 | ||
| 1036 | if (rc == STATUS_READ_ERROR) | 1166 | if (rc == STATUS_READ_ERROR || rc == STATUS_CONNECT_FAILED) |
| 1037 | return 1; | 1167 | return 2; |
| 1038 | 1168 | ||
| 1039 | /* If the read died, the child has died so let the thread die */ | 1169 | /* If the read died, the child has died so let the thread die */ |
| 1040 | if (rc == STATUS_READ_FAILED) | 1170 | if (rc == STATUS_READ_FAILED) |
| @@ -1060,14 +1190,15 @@ reader_thread (void *arg) | |||
| 1060 | return 0; | 1190 | return 0; |
| 1061 | } | 1191 | } |
| 1062 | 1192 | ||
| 1063 | /* To avoid Emacs changing directory, we just record here the directory | 1193 | /* To avoid Emacs changing directory, we just record here the |
| 1064 | the new process should start in. This is set just before calling | 1194 | directory the new process should start in. This is set just before |
| 1065 | sys_spawnve, and is not generally valid at any other time. */ | 1195 | calling sys_spawnve, and is not generally valid at any other time. |
| 1196 | Note that this directory's name is UTF-8 encoded. */ | ||
| 1066 | static char * process_dir; | 1197 | static char * process_dir; |
| 1067 | 1198 | ||
| 1068 | static BOOL | 1199 | static BOOL |
| 1069 | create_child (char *exe, char *cmdline, char *env, int is_gui_app, | 1200 | create_child (char *exe, char *cmdline, char *env, int is_gui_app, |
| 1070 | int * pPid, child_process *cp) | 1201 | pid_t * pPid, child_process *cp) |
| 1071 | { | 1202 | { |
| 1072 | STARTUPINFO start; | 1203 | STARTUPINFO start; |
| 1073 | SECURITY_ATTRIBUTES sec_attrs; | 1204 | SECURITY_ATTRIBUTES sec_attrs; |
| @@ -1075,7 +1206,9 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app, | |||
| 1075 | SECURITY_DESCRIPTOR sec_desc; | 1206 | SECURITY_DESCRIPTOR sec_desc; |
| 1076 | #endif | 1207 | #endif |
| 1077 | DWORD flags; | 1208 | DWORD flags; |
| 1078 | char dir[ MAXPATHLEN ]; | 1209 | char dir[ MAX_PATH ]; |
| 1210 | char *p; | ||
| 1211 | const char *ext; | ||
| 1079 | 1212 | ||
| 1080 | if (cp == NULL) emacs_abort (); | 1213 | if (cp == NULL) emacs_abort (); |
| 1081 | 1214 | ||
| @@ -1105,16 +1238,31 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app, | |||
| 1105 | sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */; | 1238 | sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */; |
| 1106 | sec_attrs.bInheritHandle = FALSE; | 1239 | sec_attrs.bInheritHandle = FALSE; |
| 1107 | 1240 | ||
| 1108 | strcpy (dir, process_dir); | 1241 | filename_to_ansi (process_dir, dir); |
| 1109 | unixtodos_filename (dir); | 1242 | /* Can't use unixtodos_filename here, since that needs its file name |
| 1243 | argument encoded in UTF-8. OTOH, process_dir, which _is_ in | ||
| 1244 | UTF-8, points, to the directory computed by our caller, and we | ||
| 1245 | don't want to modify that, either. */ | ||
| 1246 | for (p = dir; *p; p = CharNextA (p)) | ||
| 1247 | if (*p == '/') | ||
| 1248 | *p = '\\'; | ||
| 1249 | |||
| 1250 | /* CreateProcess handles batch files as exe specially. This special | ||
| 1251 | handling fails when both the batch file and arguments are quoted. | ||
| 1252 | We pass NULL as exe to avoid the special handling. */ | ||
| 1253 | if (exe && cmdline[0] == '"' && | ||
| 1254 | (ext = strrchr (exe, '.')) && | ||
| 1255 | (xstrcasecmp (ext, ".bat") == 0 | ||
| 1256 | || xstrcasecmp (ext, ".cmd") == 0)) | ||
| 1257 | exe = NULL; | ||
| 1110 | 1258 | ||
| 1111 | flags = (!NILP (Vw32_start_process_share_console) | 1259 | flags = (!NILP (Vw32_start_process_share_console) |
| 1112 | ? CREATE_NEW_PROCESS_GROUP | 1260 | ? CREATE_NEW_PROCESS_GROUP |
| 1113 | : CREATE_NEW_CONSOLE); | 1261 | : CREATE_NEW_CONSOLE); |
| 1114 | if (NILP (Vw32_start_process_inherit_error_mode)) | 1262 | if (NILP (Vw32_start_process_inherit_error_mode)) |
| 1115 | flags |= CREATE_DEFAULT_ERROR_MODE; | 1263 | flags |= CREATE_DEFAULT_ERROR_MODE; |
| 1116 | if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, | 1264 | if (!CreateProcessA (exe, cmdline, &sec_attrs, NULL, TRUE, |
| 1117 | flags, env, dir, &start, &cp->procinfo)) | 1265 | flags, env, dir, &start, &cp->procinfo)) |
| 1118 | goto EH_Fail; | 1266 | goto EH_Fail; |
| 1119 | 1267 | ||
| 1120 | cp->pid = (int) cp->procinfo.dwProcessId; | 1268 | cp->pid = (int) cp->procinfo.dwProcessId; |
| @@ -1132,7 +1280,7 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app, | |||
| 1132 | return FALSE; | 1280 | return FALSE; |
| 1133 | } | 1281 | } |
| 1134 | 1282 | ||
| 1135 | /* create_child doesn't know what emacs' file handle will be for waiting | 1283 | /* create_child doesn't know what emacs's file handle will be for waiting |
| 1136 | on output from the child, so we need to make this additional call | 1284 | on output from the child, so we need to make this additional call |
| 1137 | to register the handle with the process | 1285 | to register the handle with the process |
| 1138 | This way the select emulator knows how to match file handles with | 1286 | This way the select emulator knows how to match file handles with |
| @@ -1169,45 +1317,6 @@ register_child (pid_t pid, int fd) | |||
| 1169 | fd_info[fd].cp = cp; | 1317 | fd_info[fd].cp = cp; |
| 1170 | } | 1318 | } |
| 1171 | 1319 | ||
| 1172 | /* Record INFILE as an input file for process PID. */ | ||
| 1173 | void | ||
| 1174 | record_infile (pid_t pid, char *infile) | ||
| 1175 | { | ||
| 1176 | child_process *cp; | ||
| 1177 | |||
| 1178 | /* INFILE should never be NULL, since xstrdup would have signaled | ||
| 1179 | memory full condition in that case, see callproc.c where this | ||
| 1180 | function is called. */ | ||
| 1181 | eassert (infile); | ||
| 1182 | |||
| 1183 | cp = find_child_pid ((DWORD)pid); | ||
| 1184 | if (cp == NULL) | ||
| 1185 | { | ||
| 1186 | DebPrint (("record_infile is unable to find pid %lu\n", pid)); | ||
| 1187 | return; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | cp->input_file = infile; | ||
| 1191 | } | ||
| 1192 | |||
| 1193 | /* Mark the input file INFILE of the corresponding subprocess as | ||
| 1194 | temporary, to be deleted when the subprocess exits. */ | ||
| 1195 | void | ||
| 1196 | record_pending_deletion (char *infile) | ||
| 1197 | { | ||
| 1198 | child_process *cp; | ||
| 1199 | |||
| 1200 | eassert (infile); | ||
| 1201 | |||
| 1202 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | ||
| 1203 | if (CHILD_ACTIVE (cp) | ||
| 1204 | && cp->input_file && xstrcasecmp (cp->input_file, infile) == 0) | ||
| 1205 | { | ||
| 1206 | cp->pending_deletion = 1; | ||
| 1207 | break; | ||
| 1208 | } | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | /* Called from waitpid when a process exits. */ | 1320 | /* Called from waitpid when a process exits. */ |
| 1212 | static void | 1321 | static void |
| 1213 | reap_subprocess (child_process *cp) | 1322 | reap_subprocess (child_process *cp) |
| @@ -1414,22 +1523,27 @@ waitpid (pid_t pid, int *status, int options) | |||
| 1414 | # define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER | 1523 | # define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER |
| 1415 | #endif | 1524 | #endif |
| 1416 | 1525 | ||
| 1417 | static void | 1526 | /* Implementation note: This function works with file names encoded in |
| 1527 | the current ANSI codepage. */ | ||
| 1528 | static int | ||
| 1418 | w32_executable_type (char * filename, | 1529 | w32_executable_type (char * filename, |
| 1419 | int * is_dos_app, | 1530 | int * is_dos_app, |
| 1420 | int * is_cygnus_app, | 1531 | int * is_cygnus_app, |
| 1532 | int * is_msys_app, | ||
| 1421 | int * is_gui_app) | 1533 | int * is_gui_app) |
| 1422 | { | 1534 | { |
| 1423 | file_data executable; | 1535 | file_data executable; |
| 1424 | char * p; | 1536 | char * p; |
| 1537 | int retval = 0; | ||
| 1425 | 1538 | ||
| 1426 | /* Default values in case we can't tell for sure. */ | 1539 | /* Default values in case we can't tell for sure. */ |
| 1427 | *is_dos_app = FALSE; | 1540 | *is_dos_app = FALSE; |
| 1428 | *is_cygnus_app = FALSE; | 1541 | *is_cygnus_app = FALSE; |
| 1542 | *is_msys_app = FALSE; | ||
| 1429 | *is_gui_app = FALSE; | 1543 | *is_gui_app = FALSE; |
| 1430 | 1544 | ||
| 1431 | if (!open_input_file (&executable, filename)) | 1545 | if (!open_input_file (&executable, filename)) |
| 1432 | return; | 1546 | return -1; |
| 1433 | 1547 | ||
| 1434 | p = strrchr (filename, '.'); | 1548 | p = strrchr (filename, '.'); |
| 1435 | 1549 | ||
| @@ -1447,7 +1561,8 @@ w32_executable_type (char * filename, | |||
| 1447 | extension, which is defined in the registry. */ | 1561 | extension, which is defined in the registry. */ |
| 1448 | p = egetenv ("COMSPEC"); | 1562 | p = egetenv ("COMSPEC"); |
| 1449 | if (p) | 1563 | if (p) |
| 1450 | w32_executable_type (p, is_dos_app, is_cygnus_app, is_gui_app); | 1564 | retval = w32_executable_type (p, is_dos_app, is_cygnus_app, is_msys_app, |
| 1565 | is_gui_app); | ||
| 1451 | } | 1566 | } |
| 1452 | else | 1567 | else |
| 1453 | { | 1568 | { |
| @@ -1500,29 +1615,40 @@ w32_executable_type (char * filename, | |||
| 1500 | #endif | 1615 | #endif |
| 1501 | if (data_dir) | 1616 | if (data_dir) |
| 1502 | { | 1617 | { |
| 1503 | /* Look for cygwin.dll in DLL import list. */ | 1618 | /* Look for Cygwin DLL in the DLL import list. */ |
| 1504 | IMAGE_DATA_DIRECTORY import_dir = | 1619 | IMAGE_DATA_DIRECTORY import_dir = |
| 1505 | data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT]; | 1620 | data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT]; |
| 1506 | IMAGE_IMPORT_DESCRIPTOR * imports; | 1621 | IMAGE_IMPORT_DESCRIPTOR * imports = |
| 1507 | IMAGE_SECTION_HEADER * section; | 1622 | RVA_TO_PTR (import_dir.VirtualAddress, |
| 1508 | 1623 | rva_to_section (import_dir.VirtualAddress, | |
| 1509 | section = rva_to_section (import_dir.VirtualAddress, nt_header); | 1624 | nt_header), |
| 1510 | imports = RVA_TO_PTR (import_dir.VirtualAddress, section, | 1625 | executable); |
| 1511 | executable); | ||
| 1512 | 1626 | ||
| 1513 | for ( ; imports->Name; imports++) | 1627 | for ( ; imports->Name; imports++) |
| 1514 | { | 1628 | { |
| 1629 | IMAGE_SECTION_HEADER * section = | ||
| 1630 | rva_to_section (imports->Name, nt_header); | ||
| 1515 | char * dllname = RVA_TO_PTR (imports->Name, section, | 1631 | char * dllname = RVA_TO_PTR (imports->Name, section, |
| 1516 | executable); | 1632 | executable); |
| 1517 | 1633 | ||
| 1518 | /* The exact name of the cygwin dll has changed with | 1634 | /* The exact name of the Cygwin DLL has changed with |
| 1519 | various releases, but hopefully this will be reasonably | 1635 | various releases, but hopefully this will be |
| 1520 | future proof. */ | 1636 | reasonably future-proof. */ |
| 1521 | if (strncmp (dllname, "cygwin", 6) == 0) | 1637 | if (strncmp (dllname, "cygwin", 6) == 0) |
| 1522 | { | 1638 | { |
| 1523 | *is_cygnus_app = TRUE; | 1639 | *is_cygnus_app = TRUE; |
| 1524 | break; | 1640 | break; |
| 1525 | } | 1641 | } |
| 1642 | else if (strncmp (dllname, "msys-", 5) == 0) | ||
| 1643 | { | ||
| 1644 | /* This catches both MSYS 1.x and MSYS2 | ||
| 1645 | executables (the DLL name is msys-1.0.dll and | ||
| 1646 | msys-2.0.dll, respectively). There doesn't | ||
| 1647 | seem to be a reason to distinguish between | ||
| 1648 | the two, for now. */ | ||
| 1649 | *is_msys_app = TRUE; | ||
| 1650 | break; | ||
| 1651 | } | ||
| 1526 | } | 1652 | } |
| 1527 | } | 1653 | } |
| 1528 | } | 1654 | } |
| @@ -1530,6 +1656,7 @@ w32_executable_type (char * filename, | |||
| 1530 | 1656 | ||
| 1531 | unwind: | 1657 | unwind: |
| 1532 | close_file_data (&executable); | 1658 | close_file_data (&executable); |
| 1659 | return retval; | ||
| 1533 | } | 1660 | } |
| 1534 | 1661 | ||
| 1535 | static int | 1662 | static int |
| @@ -1588,7 +1715,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1588 | int arglen, numenv; | 1715 | int arglen, numenv; |
| 1589 | pid_t pid; | 1716 | pid_t pid; |
| 1590 | child_process *cp; | 1717 | child_process *cp; |
| 1591 | int is_dos_app, is_cygnus_app, is_gui_app; | 1718 | int is_dos_app, is_cygnus_app, is_msys_app, is_gui_app; |
| 1592 | int do_quoting = 0; | 1719 | int do_quoting = 0; |
| 1593 | /* We pass our process ID to our children by setting up an environment | 1720 | /* We pass our process ID to our children by setting up an environment |
| 1594 | variable in their environment. */ | 1721 | variable in their environment. */ |
| @@ -1599,11 +1726,12 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1599 | argument being split into two or more. Arguments with wildcards | 1726 | argument being split into two or more. Arguments with wildcards |
| 1600 | are also quoted, for consistency with posix platforms, where wildcards | 1727 | are also quoted, for consistency with posix platforms, where wildcards |
| 1601 | are not expanded if we run the program directly without a shell. | 1728 | are not expanded if we run the program directly without a shell. |
| 1602 | Some extra whitespace characters need quoting in Cygwin programs, | 1729 | Some extra whitespace characters need quoting in Cygwin/MSYS programs, |
| 1603 | so this list is conditionally modified below. */ | 1730 | so this list is conditionally modified below. */ |
| 1604 | char *sepchars = " \t*?"; | 1731 | char *sepchars = " \t*?"; |
| 1605 | /* This is for native w32 apps; modified below for Cygwin apps. */ | 1732 | /* This is for native w32 apps; modified below for Cygwin/MSUS apps. */ |
| 1606 | char escape_char = '\\'; | 1733 | char escape_char = '\\'; |
| 1734 | char cmdname_a[MAX_PATH]; | ||
| 1607 | 1735 | ||
| 1608 | /* We don't care about the other modes */ | 1736 | /* We don't care about the other modes */ |
| 1609 | if (mode != _P_NOWAIT) | 1737 | if (mode != _P_NOWAIT) |
| @@ -1612,53 +1740,100 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1612 | return -1; | 1740 | return -1; |
| 1613 | } | 1741 | } |
| 1614 | 1742 | ||
| 1615 | /* Handle executable names without an executable suffix. */ | 1743 | /* Handle executable names without an executable suffix. The caller |
| 1616 | program = build_string (cmdname); | 1744 | already searched exec-path and verified the file is executable, |
| 1617 | if (NILP (Ffile_executable_p (program))) | 1745 | but start-process doesn't do that for file names that are already |
| 1746 | absolute. So we double-check this here, just in case. */ | ||
| 1747 | if (faccessat (AT_FDCWD, cmdname, X_OK, AT_EACCESS) != 0) | ||
| 1618 | { | 1748 | { |
| 1619 | struct gcpro gcpro1; | 1749 | program = build_string (cmdname); |
| 1620 | |||
| 1621 | full = Qnil; | 1750 | full = Qnil; |
| 1622 | GCPRO1 (program); | 1751 | openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK), 0); |
| 1623 | openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK)); | ||
| 1624 | UNGCPRO; | ||
| 1625 | if (NILP (full)) | 1752 | if (NILP (full)) |
| 1626 | { | 1753 | { |
| 1627 | errno = EINVAL; | 1754 | errno = EINVAL; |
| 1628 | return -1; | 1755 | return -1; |
| 1629 | } | 1756 | } |
| 1630 | program = full; | 1757 | program = ENCODE_FILE (full); |
| 1758 | cmdname = SSDATA (program); | ||
| 1759 | } | ||
| 1760 | else | ||
| 1761 | { | ||
| 1762 | char *p = alloca (strlen (cmdname) + 1); | ||
| 1763 | |||
| 1764 | /* Don't change the command name we were passed by our caller | ||
| 1765 | (unixtodos_filename below will destructively mirror forward | ||
| 1766 | slashes). */ | ||
| 1767 | cmdname = strcpy (p, cmdname); | ||
| 1631 | } | 1768 | } |
| 1632 | 1769 | ||
| 1633 | /* make sure argv[0] and cmdname are both in DOS format */ | 1770 | /* make sure argv[0] and cmdname are both in DOS format */ |
| 1634 | cmdname = SDATA (program); | ||
| 1635 | unixtodos_filename (cmdname); | 1771 | unixtodos_filename (cmdname); |
| 1772 | /* argv[0] was encoded by caller using ENCODE_FILE, so it is in | ||
| 1773 | UTF-8. All the other arguments are encoded by ENCODE_SYSTEM or | ||
| 1774 | some such, and are in some ANSI codepage. We need to have | ||
| 1775 | argv[0] encoded in ANSI codepage. */ | ||
| 1776 | filename_to_ansi (cmdname, cmdname_a); | ||
| 1777 | /* We explicitly require that the command's file name be encodable | ||
| 1778 | in the current ANSI codepage, because we will be invoking it via | ||
| 1779 | the ANSI APIs. */ | ||
| 1780 | if (_mbspbrk ((unsigned char *)cmdname_a, (const unsigned char *)"?")) | ||
| 1781 | { | ||
| 1782 | errno = ENOENT; | ||
| 1783 | return -1; | ||
| 1784 | } | ||
| 1785 | /* From here on, CMDNAME is an ANSI-encoded string. */ | ||
| 1786 | cmdname = cmdname_a; | ||
| 1636 | argv[0] = cmdname; | 1787 | argv[0] = cmdname; |
| 1637 | 1788 | ||
| 1638 | /* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows | 1789 | /* Determine whether program is a 16-bit DOS executable, or a 32-bit |
| 1639 | executable that is implicitly linked to the Cygnus dll (implying it | 1790 | Windows executable that is implicitly linked to the Cygnus or |
| 1640 | was compiled with the Cygnus GNU toolchain and hence relies on | 1791 | MSYS dll (implying it was compiled with the Cygnus/MSYS GNU |
| 1641 | cygwin.dll to parse the command line - we use this to decide how to | 1792 | toolchain and hence relies on cygwin.dll or MSYS DLL to parse the |
| 1642 | escape quote chars in command line args that must be quoted). | 1793 | command line - we use this to decide how to escape quote chars in |
| 1794 | command line args that must be quoted). | ||
| 1643 | 1795 | ||
| 1644 | Also determine whether it is a GUI app, so that we don't hide its | 1796 | Also determine whether it is a GUI app, so that we don't hide its |
| 1645 | initial window unless specifically requested. */ | 1797 | initial window unless specifically requested. */ |
| 1646 | w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_gui_app); | 1798 | w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_msys_app, |
| 1799 | &is_gui_app); | ||
| 1647 | 1800 | ||
| 1648 | /* On Windows 95, if cmdname is a DOS app, we invoke a helper | 1801 | /* On Windows 95, if cmdname is a DOS app, we invoke a helper |
| 1649 | application to start it by specifying the helper app as cmdname, | 1802 | application to start it by specifying the helper app as cmdname, |
| 1650 | while leaving the real app name as argv[0]. */ | 1803 | while leaving the real app name as argv[0]. */ |
| 1651 | if (is_dos_app) | 1804 | if (is_dos_app) |
| 1652 | { | 1805 | { |
| 1653 | cmdname = alloca (MAXPATHLEN); | 1806 | char *p; |
| 1807 | |||
| 1808 | cmdname = alloca (MAX_PATH); | ||
| 1654 | if (egetenv ("CMDPROXY")) | 1809 | if (egetenv ("CMDPROXY")) |
| 1655 | strcpy (cmdname, egetenv ("CMDPROXY")); | 1810 | { |
| 1811 | /* Implementation note: since process-environment, where | ||
| 1812 | 'egetenv' looks, is encoded in the system codepage, we | ||
| 1813 | don't need to encode the cmdproxy file name if we get it | ||
| 1814 | from the environment. */ | ||
| 1815 | strcpy (cmdname, egetenv ("CMDPROXY")); | ||
| 1816 | } | ||
| 1656 | else | 1817 | else |
| 1657 | { | 1818 | { |
| 1658 | strcpy (cmdname, SDATA (Vinvocation_directory)); | 1819 | char *q = lispstpcpy (cmdname, |
| 1659 | strcat (cmdname, "cmdproxy.exe"); | 1820 | /* exec-directory needs to be encoded. */ |
| 1821 | ansi_encode_filename (Vexec_directory)); | ||
| 1822 | /* If we are run from the source tree, use cmdproxy.exe from | ||
| 1823 | the same source tree. */ | ||
| 1824 | for (p = q - 2; p > cmdname; p = CharPrevA (cmdname, p)) | ||
| 1825 | if (*p == '/') | ||
| 1826 | break; | ||
| 1827 | if (*p == '/' && xstrcasecmp (p, "/lib-src/") == 0) | ||
| 1828 | q = stpcpy (p, "/nt/"); | ||
| 1829 | strcpy (q, "cmdproxy.exe"); | ||
| 1660 | } | 1830 | } |
| 1661 | unixtodos_filename (cmdname); | 1831 | |
| 1832 | /* Can't use unixtodos_filename here, since that needs its file | ||
| 1833 | name argument encoded in UTF-8. */ | ||
| 1834 | for (p = cmdname; *p; p = CharNextA (p)) | ||
| 1835 | if (*p == '/') | ||
| 1836 | *p = '\\'; | ||
| 1662 | } | 1837 | } |
| 1663 | 1838 | ||
| 1664 | /* we have to do some conjuring here to put argv and envp into the | 1839 | /* we have to do some conjuring here to put argv and envp into the |
| @@ -1699,10 +1874,10 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1699 | if (INTEGERP (Vw32_quote_process_args)) | 1874 | if (INTEGERP (Vw32_quote_process_args)) |
| 1700 | escape_char = XINT (Vw32_quote_process_args); | 1875 | escape_char = XINT (Vw32_quote_process_args); |
| 1701 | else | 1876 | else |
| 1702 | escape_char = is_cygnus_app ? '"' : '\\'; | 1877 | escape_char = (is_cygnus_app || is_msys_app) ? '"' : '\\'; |
| 1703 | } | 1878 | } |
| 1704 | 1879 | ||
| 1705 | /* Cygwin apps needs quoting a bit more often. */ | 1880 | /* Cygwin/MSYS apps need quoting a bit more often. */ |
| 1706 | if (escape_char == '"') | 1881 | if (escape_char == '"') |
| 1707 | sepchars = "\r\n\t\f '"; | 1882 | sepchars = "\r\n\t\f '"; |
| 1708 | 1883 | ||
| @@ -1720,7 +1895,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1720 | for ( ; *p; p++) | 1895 | for ( ; *p; p++) |
| 1721 | { | 1896 | { |
| 1722 | if (escape_char == '"' && *p == '\\') | 1897 | if (escape_char == '"' && *p == '\\') |
| 1723 | /* If it's a Cygwin app, \ needs to be escaped. */ | 1898 | /* If it's a Cygwin/MSYS app, \ needs to be escaped. */ |
| 1724 | arglen++; | 1899 | arglen++; |
| 1725 | else if (*p == '"') | 1900 | else if (*p == '"') |
| 1726 | { | 1901 | { |
| @@ -1776,12 +1951,12 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1776 | if (need_quotes) | 1951 | if (need_quotes) |
| 1777 | { | 1952 | { |
| 1778 | int escape_char_run = 0; | 1953 | int escape_char_run = 0; |
| 1779 | char * first; | 1954 | /* char * first; */ |
| 1780 | char * last; | 1955 | /* char * last; */ |
| 1781 | 1956 | ||
| 1782 | p = *targ; | 1957 | p = *targ; |
| 1783 | first = p; | 1958 | /* first = p; */ |
| 1784 | last = p + strlen (p) - 1; | 1959 | /* last = p + strlen (p) - 1; */ |
| 1785 | *parg++ = '"'; | 1960 | *parg++ = '"'; |
| 1786 | #if 0 | 1961 | #if 0 |
| 1787 | /* This version does not escape quotes if they occur at the | 1962 | /* This version does not escape quotes if they occur at the |
| @@ -1916,9 +2091,9 @@ extern int proc_buffered_char[]; | |||
| 1916 | 2091 | ||
| 1917 | int | 2092 | int |
| 1918 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | 2093 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, |
| 1919 | EMACS_TIME *timeout, sigset_t *ignored) | 2094 | struct timespec *timeout, sigset_t *ignored) |
| 1920 | { | 2095 | { |
| 1921 | SELECT_TYPE orfds; | 2096 | SELECT_TYPE orfds, owfds; |
| 1922 | DWORD timeout_ms, start_time; | 2097 | DWORD timeout_ms, start_time; |
| 1923 | int i, nh, nc, nr; | 2098 | int i, nh, nc, nr; |
| 1924 | DWORD active; | 2099 | DWORD active; |
| @@ -1936,25 +2111,42 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 1936 | return 0; | 2111 | return 0; |
| 1937 | } | 2112 | } |
| 1938 | 2113 | ||
| 1939 | /* Otherwise, we only handle rfds, so fail otherwise. */ | 2114 | /* Otherwise, we only handle rfds and wfds, so fail otherwise. */ |
| 1940 | if (rfds == NULL || wfds != NULL || efds != NULL) | 2115 | if ((rfds == NULL && wfds == NULL) || efds != NULL) |
| 1941 | { | 2116 | { |
| 1942 | errno = EINVAL; | 2117 | errno = EINVAL; |
| 1943 | return -1; | 2118 | return -1; |
| 1944 | } | 2119 | } |
| 1945 | 2120 | ||
| 1946 | orfds = *rfds; | 2121 | if (rfds) |
| 1947 | FD_ZERO (rfds); | 2122 | { |
| 2123 | orfds = *rfds; | ||
| 2124 | FD_ZERO (rfds); | ||
| 2125 | } | ||
| 2126 | else | ||
| 2127 | FD_ZERO (&orfds); | ||
| 2128 | if (wfds) | ||
| 2129 | { | ||
| 2130 | owfds = *wfds; | ||
| 2131 | FD_ZERO (wfds); | ||
| 2132 | } | ||
| 2133 | else | ||
| 2134 | FD_ZERO (&owfds); | ||
| 1948 | nr = 0; | 2135 | nr = 0; |
| 1949 | 2136 | ||
| 1950 | /* Always wait on interrupt_handle, to detect C-g (quit). */ | 2137 | /* If interrupt_handle is available and valid, always wait on it, to |
| 1951 | wait_hnd[0] = interrupt_handle; | 2138 | detect C-g (quit). */ |
| 1952 | fdindex[0] = -1; | 2139 | nh = 0; |
| 2140 | if (interrupt_handle && interrupt_handle != INVALID_HANDLE_VALUE) | ||
| 2141 | { | ||
| 2142 | wait_hnd[0] = interrupt_handle; | ||
| 2143 | fdindex[0] = -1; | ||
| 2144 | nh++; | ||
| 2145 | } | ||
| 1953 | 2146 | ||
| 1954 | /* Build a list of pipe handles to wait on. */ | 2147 | /* Build a list of pipe handles to wait on. */ |
| 1955 | nh = 1; | ||
| 1956 | for (i = 0; i < nfds; i++) | 2148 | for (i = 0; i < nfds; i++) |
| 1957 | if (FD_ISSET (i, &orfds)) | 2149 | if (FD_ISSET (i, &orfds) || FD_ISSET (i, &owfds)) |
| 1958 | { | 2150 | { |
| 1959 | if (i == 0) | 2151 | if (i == 0) |
| 1960 | { | 2152 | { |
| @@ -1968,16 +2160,28 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 1968 | 2160 | ||
| 1969 | /* Check for any emacs-generated input in the queue since | 2161 | /* Check for any emacs-generated input in the queue since |
| 1970 | it won't be detected in the wait */ | 2162 | it won't be detected in the wait */ |
| 1971 | if (detect_input_pending ()) | 2163 | if (rfds && detect_input_pending ()) |
| 1972 | { | 2164 | { |
| 1973 | FD_SET (i, rfds); | 2165 | FD_SET (i, rfds); |
| 1974 | return 1; | 2166 | return 1; |
| 1975 | } | 2167 | } |
| 2168 | else if (noninteractive) | ||
| 2169 | { | ||
| 2170 | if (handle_file_notifications (NULL)) | ||
| 2171 | return 1; | ||
| 2172 | } | ||
| 1976 | } | 2173 | } |
| 1977 | else | 2174 | else |
| 1978 | { | 2175 | { |
| 1979 | /* Child process and socket/comm port input. */ | 2176 | /* Child process and socket/comm port input. */ |
| 1980 | cp = fd_info[i].cp; | 2177 | cp = fd_info[i].cp; |
| 2178 | if (FD_ISSET (i, &owfds) | ||
| 2179 | && cp | ||
| 2180 | && (fd_info[i].flags & FILE_CONNECT) == 0) | ||
| 2181 | { | ||
| 2182 | DebPrint (("sys_select: fd %d is in wfds, but FILE_CONNECT is reset!\n", i)); | ||
| 2183 | cp = NULL; | ||
| 2184 | } | ||
| 1981 | if (cp) | 2185 | if (cp) |
| 1982 | { | 2186 | { |
| 1983 | int current_status = cp->status; | 2187 | int current_status = cp->status; |
| @@ -1986,6 +2190,8 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 1986 | { | 2190 | { |
| 1987 | /* Tell reader thread which file handle to use. */ | 2191 | /* Tell reader thread which file handle to use. */ |
| 1988 | cp->fd = i; | 2192 | cp->fd = i; |
| 2193 | /* Zero out the error code. */ | ||
| 2194 | cp->errcode = 0; | ||
| 1989 | /* Wake up the reader thread for this process */ | 2195 | /* Wake up the reader thread for this process */ |
| 1990 | cp->status = STATUS_READ_READY; | 2196 | cp->status = STATUS_READ_READY; |
| 1991 | if (!SetEvent (cp->char_consumed)) | 2197 | if (!SetEvent (cp->char_consumed)) |
| @@ -2073,6 +2279,11 @@ count_children: | |||
| 2073 | { | 2279 | { |
| 2074 | if (timeout) | 2280 | if (timeout) |
| 2075 | Sleep (timeout_ms); | 2281 | Sleep (timeout_ms); |
| 2282 | if (noninteractive) | ||
| 2283 | { | ||
| 2284 | if (handle_file_notifications (NULL)) | ||
| 2285 | return 1; | ||
| 2286 | } | ||
| 2076 | return 0; | 2287 | return 0; |
| 2077 | } | 2288 | } |
| 2078 | 2289 | ||
| @@ -2099,6 +2310,11 @@ count_children: | |||
| 2099 | } | 2310 | } |
| 2100 | else if (active == WAIT_TIMEOUT) | 2311 | else if (active == WAIT_TIMEOUT) |
| 2101 | { | 2312 | { |
| 2313 | if (noninteractive) | ||
| 2314 | { | ||
| 2315 | if (handle_file_notifications (NULL)) | ||
| 2316 | return 1; | ||
| 2317 | } | ||
| 2102 | return 0; | 2318 | return 0; |
| 2103 | } | 2319 | } |
| 2104 | else if (active >= WAIT_OBJECT_0 | 2320 | else if (active >= WAIT_OBJECT_0 |
| @@ -2166,7 +2382,7 @@ count_children: | |||
| 2166 | 2382 | ||
| 2167 | if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_AT_EOF) == 0) | 2383 | if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_AT_EOF) == 0) |
| 2168 | fd_info[cp->fd].flags |= FILE_SEND_SIGCHLD; | 2384 | fd_info[cp->fd].flags |= FILE_SEND_SIGCHLD; |
| 2169 | /* SIG_DFL for SIGCHLD is ignore */ | 2385 | /* SIG_DFL for SIGCHLD is ignored */ |
| 2170 | else if (sig_handlers[SIGCHLD] != SIG_DFL && | 2386 | else if (sig_handlers[SIGCHLD] != SIG_DFL && |
| 2171 | sig_handlers[SIGCHLD] != SIG_IGN) | 2387 | sig_handlers[SIGCHLD] != SIG_IGN) |
| 2172 | { | 2388 | { |
| @@ -2183,7 +2399,7 @@ count_children: | |||
| 2183 | errno = EINTR; | 2399 | errno = EINTR; |
| 2184 | return -1; | 2400 | return -1; |
| 2185 | } | 2401 | } |
| 2186 | else if (fdindex[active] == 0) | 2402 | else if (rfds && fdindex[active] == 0) |
| 2187 | { | 2403 | { |
| 2188 | /* Keyboard input available */ | 2404 | /* Keyboard input available */ |
| 2189 | FD_SET (0, rfds); | 2405 | FD_SET (0, rfds); |
| @@ -2191,9 +2407,33 @@ count_children: | |||
| 2191 | } | 2407 | } |
| 2192 | else | 2408 | else |
| 2193 | { | 2409 | { |
| 2194 | /* must be a socket or pipe - read ahead should have | 2410 | /* Must be a socket or pipe - read ahead should have |
| 2195 | completed, either succeeding or failing. */ | 2411 | completed, either succeeding or failing. If this handle |
| 2196 | FD_SET (fdindex[active], rfds); | 2412 | was waiting for an async 'connect', reset the connect |
| 2413 | flag, so it could read from now on. */ | ||
| 2414 | if (wfds && (fd_info[fdindex[active]].flags & FILE_CONNECT) != 0) | ||
| 2415 | { | ||
| 2416 | cp = fd_info[fdindex[active]].cp; | ||
| 2417 | if (cp) | ||
| 2418 | { | ||
| 2419 | /* Don't reset the FILE_CONNECT bit and don't | ||
| 2420 | acknowledge the read if the status is | ||
| 2421 | STATUS_CONNECT_FAILED or some other | ||
| 2422 | failure. That's because the thread exits in those | ||
| 2423 | cases, so it doesn't need the ACK, and we want to | ||
| 2424 | keep the FILE_CONNECT bit as evidence that the | ||
| 2425 | connect failed, to be checked in sys_read. */ | ||
| 2426 | if (cp->status == STATUS_READ_SUCCEEDED) | ||
| 2427 | { | ||
| 2428 | fd_info[cp->fd].flags &= ~FILE_CONNECT; | ||
| 2429 | cp->status = STATUS_READ_ACKNOWLEDGED; | ||
| 2430 | } | ||
| 2431 | ResetEvent (cp->char_avail); | ||
| 2432 | } | ||
| 2433 | FD_SET (fdindex[active], wfds); | ||
| 2434 | } | ||
| 2435 | else if (rfds) | ||
| 2436 | FD_SET (fdindex[active], rfds); | ||
| 2197 | nr++; | 2437 | nr++; |
| 2198 | } | 2438 | } |
| 2199 | 2439 | ||
| @@ -2205,6 +2445,12 @@ count_children: | |||
| 2205 | break; | 2445 | break; |
| 2206 | } while (active < nh + nc); | 2446 | } while (active < nh + nc); |
| 2207 | 2447 | ||
| 2448 | if (noninteractive) | ||
| 2449 | { | ||
| 2450 | if (handle_file_notifications (NULL)) | ||
| 2451 | nr++; | ||
| 2452 | } | ||
| 2453 | |||
| 2208 | /* If no input has arrived and timeout hasn't expired, wait again. */ | 2454 | /* If no input has arrived and timeout hasn't expired, wait again. */ |
| 2209 | if (nr == 0) | 2455 | if (nr == 0) |
| 2210 | { | 2456 | { |
| @@ -2227,10 +2473,9 @@ static BOOL CALLBACK | |||
| 2227 | find_child_console (HWND hwnd, LPARAM arg) | 2473 | find_child_console (HWND hwnd, LPARAM arg) |
| 2228 | { | 2474 | { |
| 2229 | child_process * cp = (child_process *) arg; | 2475 | child_process * cp = (child_process *) arg; |
| 2230 | DWORD thread_id; | ||
| 2231 | DWORD process_id; | 2476 | DWORD process_id; |
| 2232 | 2477 | ||
| 2233 | thread_id = GetWindowThreadProcessId (hwnd, &process_id); | 2478 | GetWindowThreadProcessId (hwnd, &process_id); |
| 2234 | if (process_id == cp->procinfo.dwProcessId) | 2479 | if (process_id == cp->procinfo.dwProcessId) |
| 2235 | { | 2480 | { |
| 2236 | char window_class[32]; | 2481 | char window_class[32]; |
| @@ -2634,10 +2879,11 @@ All path elements in FILENAME are converted to their short names. */) | |||
| 2634 | filename = Fexpand_file_name (filename, Qnil); | 2879 | filename = Fexpand_file_name (filename, Qnil); |
| 2635 | 2880 | ||
| 2636 | /* luckily, this returns the short version of each element in the path. */ | 2881 | /* luckily, this returns the short version of each element in the path. */ |
| 2637 | if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname, MAX_PATH) == 0) | 2882 | if (w32_get_short_filename (SSDATA (ENCODE_FILE (filename)), |
| 2883 | shortname, MAX_PATH) == 0) | ||
| 2638 | return Qnil; | 2884 | return Qnil; |
| 2639 | 2885 | ||
| 2640 | dostounix_filename (shortname, 0); | 2886 | dostounix_filename (shortname); |
| 2641 | 2887 | ||
| 2642 | /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */ | 2888 | /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */ |
| 2643 | return build_string (shortname); | 2889 | return build_string (shortname); |
| @@ -2651,7 +2897,7 @@ If FILENAME does not exist, return nil. | |||
| 2651 | All path elements in FILENAME are converted to their long names. */) | 2897 | All path elements in FILENAME are converted to their long names. */) |
| 2652 | (Lisp_Object filename) | 2898 | (Lisp_Object filename) |
| 2653 | { | 2899 | { |
| 2654 | char longname[ MAX_PATH ]; | 2900 | char longname[ MAX_UTF8_PATH ]; |
| 2655 | int drive_only = 0; | 2901 | int drive_only = 0; |
| 2656 | 2902 | ||
| 2657 | CHECK_STRING (filename); | 2903 | CHECK_STRING (filename); |
| @@ -2663,10 +2909,11 @@ All path elements in FILENAME are converted to their long names. */) | |||
| 2663 | /* first expand it. */ | 2909 | /* first expand it. */ |
| 2664 | filename = Fexpand_file_name (filename, Qnil); | 2910 | filename = Fexpand_file_name (filename, Qnil); |
| 2665 | 2911 | ||
| 2666 | if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, MAX_PATH)) | 2912 | if (!w32_get_long_filename (SSDATA (ENCODE_FILE (filename)), longname, |
| 2913 | MAX_UTF8_PATH)) | ||
| 2667 | return Qnil; | 2914 | return Qnil; |
| 2668 | 2915 | ||
| 2669 | dostounix_filename (longname, 0); | 2916 | dostounix_filename (longname); |
| 2670 | 2917 | ||
| 2671 | /* If we were passed only a drive, make sure that a slash is not appended | 2918 | /* If we were passed only a drive, make sure that a slash is not appended |
| 2672 | for consistency with directories. Allow for drive mapping via SUBST | 2919 | for consistency with directories. Allow for drive mapping via SUBST |
| @@ -2674,7 +2921,7 @@ All path elements in FILENAME are converted to their long names. */) | |||
| 2674 | if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3]) | 2921 | if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3]) |
| 2675 | longname[2] = '\0'; | 2922 | longname[2] = '\0'; |
| 2676 | 2923 | ||
| 2677 | return DECODE_FILE (build_string (longname)); | 2924 | return DECODE_FILE (build_unibyte_string (longname)); |
| 2678 | } | 2925 | } |
| 2679 | 2926 | ||
| 2680 | DEFUN ("w32-set-process-priority", Fw32_set_process_priority, | 2927 | DEFUN ("w32-set-process-priority", Fw32_set_process_priority, |
| @@ -2729,6 +2976,59 @@ If successful, the return value is t, otherwise nil. */) | |||
| 2729 | return result; | 2976 | return result; |
| 2730 | } | 2977 | } |
| 2731 | 2978 | ||
| 2979 | DEFUN ("w32-application-type", Fw32_application_type, | ||
| 2980 | Sw32_application_type, 1, 1, 0, | ||
| 2981 | doc: /* Return the type of an MS-Windows PROGRAM. | ||
| 2982 | |||
| 2983 | Knowing the type of an executable could be useful for formatting | ||
| 2984 | file names passed to it or for quoting its command-line arguments. | ||
| 2985 | |||
| 2986 | PROGRAM should specify an executable file, including the extension. | ||
| 2987 | |||
| 2988 | The value is one of the following: | ||
| 2989 | |||
| 2990 | `dos' -- a DOS .com program or some other non-PE executable | ||
| 2991 | `cygwin' -- a Cygwin program that depends on Cygwin DLL | ||
| 2992 | `msys' -- an MSYS 1.x or MSYS2 program | ||
| 2993 | `w32-native' -- a native Windows application | ||
| 2994 | `unknown' -- a file that doesn't exist, or cannot be open, or whose | ||
| 2995 | name is not encodable in the current ANSI codepage. | ||
| 2996 | |||
| 2997 | Note that for .bat and .cmd batch files the function returns the type | ||
| 2998 | of their command interpreter, as specified by the \"COMSPEC\" | ||
| 2999 | environment variable. | ||
| 3000 | |||
| 3001 | This function returns `unknown' for programs whose file names | ||
| 3002 | include characters not supported by the current ANSI codepage, as | ||
| 3003 | such programs cannot be invoked by Emacs anyway. */) | ||
| 3004 | (Lisp_Object program) | ||
| 3005 | { | ||
| 3006 | int is_dos_app, is_cygwin_app, is_msys_app, dummy; | ||
| 3007 | Lisp_Object encoded_progname; | ||
| 3008 | char *progname, progname_a[MAX_PATH]; | ||
| 3009 | |||
| 3010 | program = Fexpand_file_name (program, Qnil); | ||
| 3011 | encoded_progname = ENCODE_FILE (program); | ||
| 3012 | progname = SSDATA (encoded_progname); | ||
| 3013 | unixtodos_filename (progname); | ||
| 3014 | filename_to_ansi (progname, progname_a); | ||
| 3015 | /* Reject file names that cannot be encoded in the current ANSI | ||
| 3016 | codepage. */ | ||
| 3017 | if (_mbspbrk ((unsigned char *)progname_a, (const unsigned char *)"?")) | ||
| 3018 | return Qunknown; | ||
| 3019 | |||
| 3020 | if (w32_executable_type (progname_a, &is_dos_app, &is_cygwin_app, | ||
| 3021 | &is_msys_app, &dummy) != 0) | ||
| 3022 | return Qunknown; | ||
| 3023 | if (is_dos_app) | ||
| 3024 | return Qdos; | ||
| 3025 | if (is_cygwin_app) | ||
| 3026 | return Qcygwin; | ||
| 3027 | if (is_msys_app) | ||
| 3028 | return Qmsys; | ||
| 3029 | return Qw32_native; | ||
| 3030 | } | ||
| 3031 | |||
| 2732 | #ifdef HAVE_LANGINFO_CODESET | 3032 | #ifdef HAVE_LANGINFO_CODESET |
| 2733 | /* Emulation of nl_langinfo. Used in fns.c:Flocale_info. */ | 3033 | /* Emulation of nl_langinfo. Used in fns.c:Flocale_info. */ |
| 2734 | char * | 3034 | char * |
| @@ -2885,7 +3185,7 @@ int_from_hex (char * s) | |||
| 2885 | function isn't given a context pointer. */ | 3185 | function isn't given a context pointer. */ |
| 2886 | Lisp_Object Vw32_valid_locale_ids; | 3186 | Lisp_Object Vw32_valid_locale_ids; |
| 2887 | 3187 | ||
| 2888 | static BOOL CALLBACK | 3188 | static BOOL CALLBACK ALIGN_STACK |
| 2889 | enum_locale_fn (LPTSTR localeNum) | 3189 | enum_locale_fn (LPTSTR localeNum) |
| 2890 | { | 3190 | { |
| 2891 | DWORD id = int_from_hex (localeNum); | 3191 | DWORD id = int_from_hex (localeNum); |
| @@ -2949,7 +3249,7 @@ If successful, the new locale id is returned, otherwise nil. */) | |||
| 2949 | function isn't given a context pointer. */ | 3249 | function isn't given a context pointer. */ |
| 2950 | Lisp_Object Vw32_valid_codepages; | 3250 | Lisp_Object Vw32_valid_codepages; |
| 2951 | 3251 | ||
| 2952 | static BOOL CALLBACK | 3252 | static BOOL CALLBACK ALIGN_STACK |
| 2953 | enum_codepage_fn (LPTSTR codepageNum) | 3253 | enum_codepage_fn (LPTSTR codepageNum) |
| 2954 | { | 3254 | { |
| 2955 | DWORD id = atoi (codepageNum); | 3255 | DWORD id = atoi (codepageNum); |
| @@ -3030,17 +3330,27 @@ If successful, the new CP is returned, otherwise nil. */) | |||
| 3030 | DEFUN ("w32-get-codepage-charset", Fw32_get_codepage_charset, | 3330 | DEFUN ("w32-get-codepage-charset", Fw32_get_codepage_charset, |
| 3031 | Sw32_get_codepage_charset, 1, 1, 0, | 3331 | Sw32_get_codepage_charset, 1, 1, 0, |
| 3032 | doc: /* Return charset ID corresponding to codepage CP. | 3332 | doc: /* Return charset ID corresponding to codepage CP. |
| 3033 | Returns nil if the codepage is not valid. */) | 3333 | Returns nil if the codepage is not valid or its charset ID could |
| 3334 | not be determined. | ||
| 3335 | |||
| 3336 | Note that this function is only guaranteed to work with ANSI | ||
| 3337 | codepages; most console codepages are not supported and will | ||
| 3338 | yield nil. */) | ||
| 3034 | (Lisp_Object cp) | 3339 | (Lisp_Object cp) |
| 3035 | { | 3340 | { |
| 3036 | CHARSETINFO info; | 3341 | CHARSETINFO info; |
| 3342 | DWORD_PTR dwcp; | ||
| 3037 | 3343 | ||
| 3038 | CHECK_NUMBER (cp); | 3344 | CHECK_NUMBER (cp); |
| 3039 | 3345 | ||
| 3040 | if (!IsValidCodePage (XINT (cp))) | 3346 | if (!IsValidCodePage (XINT (cp))) |
| 3041 | return Qnil; | 3347 | return Qnil; |
| 3042 | 3348 | ||
| 3043 | if (TranslateCharsetInfo ((DWORD *) XINT (cp), &info, TCI_SRCCODEPAGE)) | 3349 | /* Going through a temporary DWORD_PTR variable avoids compiler warning |
| 3350 | about cast to pointer from integer of different size, when | ||
| 3351 | building --with-wide-int or building for 64bit. */ | ||
| 3352 | dwcp = XINT (cp); | ||
| 3353 | if (TranslateCharsetInfo ((DWORD *) dwcp, &info, TCI_SRCCODEPAGE)) | ||
| 3044 | return make_number (info.ciCharset); | 3354 | return make_number (info.ciCharset); |
| 3045 | 3355 | ||
| 3046 | return Qnil; | 3356 | return Qnil; |
| @@ -3061,10 +3371,10 @@ The return value is a list of pairs of language id and layout id. */) | |||
| 3061 | { | 3371 | { |
| 3062 | while (--num_layouts >= 0) | 3372 | while (--num_layouts >= 0) |
| 3063 | { | 3373 | { |
| 3064 | DWORD kl = (DWORD) layouts[num_layouts]; | 3374 | HKL kl = layouts[num_layouts]; |
| 3065 | 3375 | ||
| 3066 | obj = Fcons (Fcons (make_number (kl & 0xffff), | 3376 | obj = Fcons (Fcons (make_number (LOWORD (kl)), |
| 3067 | make_number ((kl >> 16) & 0xffff)), | 3377 | make_number (HIWORD (kl))), |
| 3068 | obj); | 3378 | obj); |
| 3069 | } | 3379 | } |
| 3070 | } | 3380 | } |
| @@ -3079,10 +3389,10 @@ DEFUN ("w32-get-keyboard-layout", Fw32_get_keyboard_layout, | |||
| 3079 | The return value is the cons of the language id and the layout id. */) | 3389 | The return value is the cons of the language id and the layout id. */) |
| 3080 | (void) | 3390 | (void) |
| 3081 | { | 3391 | { |
| 3082 | DWORD kl = (DWORD) GetKeyboardLayout (dwWindowsThreadId); | 3392 | HKL kl = GetKeyboardLayout (dwWindowsThreadId); |
| 3083 | 3393 | ||
| 3084 | return Fcons (make_number (kl & 0xffff), | 3394 | return Fcons (make_number (LOWORD (kl)), |
| 3085 | make_number ((kl >> 16) & 0xffff)); | 3395 | make_number (HIWORD (kl))); |
| 3086 | } | 3396 | } |
| 3087 | 3397 | ||
| 3088 | 3398 | ||
| @@ -3093,14 +3403,14 @@ The keyboard layout setting affects interpretation of keyboard input. | |||
| 3093 | If successful, the new layout id is returned, otherwise nil. */) | 3403 | If successful, the new layout id is returned, otherwise nil. */) |
| 3094 | (Lisp_Object layout) | 3404 | (Lisp_Object layout) |
| 3095 | { | 3405 | { |
| 3096 | DWORD kl; | 3406 | HKL kl; |
| 3097 | 3407 | ||
| 3098 | CHECK_CONS (layout); | 3408 | CHECK_CONS (layout); |
| 3099 | CHECK_NUMBER_CAR (layout); | 3409 | CHECK_NUMBER_CAR (layout); |
| 3100 | CHECK_NUMBER_CDR (layout); | 3410 | CHECK_NUMBER_CDR (layout); |
| 3101 | 3411 | ||
| 3102 | kl = (XINT (XCAR (layout)) & 0xffff) | 3412 | kl = (HKL) (UINT_PTR) ((XINT (XCAR (layout)) & 0xffff) |
| 3103 | | (XINT (XCDR (layout)) << 16); | 3413 | | (XINT (XCDR (layout)) << 16)); |
| 3104 | 3414 | ||
| 3105 | /* Synchronize layout with input thread. */ | 3415 | /* Synchronize layout with input thread. */ |
| 3106 | if (dwWindowsThreadId) | 3416 | if (dwWindowsThreadId) |
| @@ -3115,18 +3425,211 @@ If successful, the new layout id is returned, otherwise nil. */) | |||
| 3115 | return Qnil; | 3425 | return Qnil; |
| 3116 | } | 3426 | } |
| 3117 | } | 3427 | } |
| 3118 | else if (!ActivateKeyboardLayout ((HKL) kl, 0)) | 3428 | else if (!ActivateKeyboardLayout (kl, 0)) |
| 3119 | return Qnil; | 3429 | return Qnil; |
| 3120 | 3430 | ||
| 3121 | return Fw32_get_keyboard_layout (); | 3431 | return Fw32_get_keyboard_layout (); |
| 3122 | } | 3432 | } |
| 3123 | 3433 | ||
| 3434 | /* Two variables to interface between get_lcid and the EnumLocales | ||
| 3435 | callback function below. */ | ||
| 3436 | #ifndef LOCALE_NAME_MAX_LENGTH | ||
| 3437 | # define LOCALE_NAME_MAX_LENGTH 85 | ||
| 3438 | #endif | ||
| 3439 | static LCID found_lcid; | ||
| 3440 | static char lname[3 * LOCALE_NAME_MAX_LENGTH + 1 + 1]; | ||
| 3441 | |||
| 3442 | /* Callback function for EnumLocales. */ | ||
| 3443 | static BOOL CALLBACK | ||
| 3444 | get_lcid_callback (LPTSTR locale_num_str) | ||
| 3445 | { | ||
| 3446 | char *endp; | ||
| 3447 | char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1]; | ||
| 3448 | LCID try_lcid = strtoul (locale_num_str, &endp, 16); | ||
| 3449 | |||
| 3450 | if (GetLocaleInfo (try_lcid, LOCALE_SABBREVLANGNAME, | ||
| 3451 | locval, LOCALE_NAME_MAX_LENGTH)) | ||
| 3452 | { | ||
| 3453 | size_t locval_len; | ||
| 3454 | |||
| 3455 | /* This is for when they only specify the language, as in "ENU". */ | ||
| 3456 | if (stricmp (locval, lname) == 0) | ||
| 3457 | { | ||
| 3458 | found_lcid = try_lcid; | ||
| 3459 | return FALSE; | ||
| 3460 | } | ||
| 3461 | locval_len = strlen (locval); | ||
| 3462 | strcpy (locval + locval_len, "_"); | ||
| 3463 | if (GetLocaleInfo (try_lcid, LOCALE_SABBREVCTRYNAME, | ||
| 3464 | locval + locval_len + 1, LOCALE_NAME_MAX_LENGTH)) | ||
| 3465 | { | ||
| 3466 | locval_len = strlen (locval); | ||
| 3467 | if (strnicmp (locval, lname, locval_len) == 0 | ||
| 3468 | && (lname[locval_len] == '.' | ||
| 3469 | || lname[locval_len] == '\0')) | ||
| 3470 | { | ||
| 3471 | found_lcid = try_lcid; | ||
| 3472 | return FALSE; | ||
| 3473 | } | ||
| 3474 | } | ||
| 3475 | } | ||
| 3476 | return TRUE; | ||
| 3477 | } | ||
| 3478 | |||
| 3479 | /* Return the Locale ID (LCID) number given the locale's name, a | ||
| 3480 | string, in LOCALE_NAME. This works by enumerating all the locales | ||
| 3481 | supported by the system, until we find one whose name matches | ||
| 3482 | LOCALE_NAME. */ | ||
| 3483 | static LCID | ||
| 3484 | get_lcid (const char *locale_name) | ||
| 3485 | { | ||
| 3486 | /* A simple cache. */ | ||
| 3487 | static LCID last_lcid; | ||
| 3488 | static char last_locale[1000]; | ||
| 3489 | |||
| 3490 | /* The code below is not thread-safe, as it uses static variables. | ||
| 3491 | But this function is called only from the Lisp thread. */ | ||
| 3492 | if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0) | ||
| 3493 | return last_lcid; | ||
| 3494 | |||
| 3495 | strncpy (lname, locale_name, sizeof (lname) - 1); | ||
| 3496 | lname[sizeof (lname) - 1] = '\0'; | ||
| 3497 | found_lcid = 0; | ||
| 3498 | EnumSystemLocales (get_lcid_callback, LCID_SUPPORTED); | ||
| 3499 | if (found_lcid > 0) | ||
| 3500 | { | ||
| 3501 | last_lcid = found_lcid; | ||
| 3502 | strcpy (last_locale, locale_name); | ||
| 3503 | } | ||
| 3504 | return found_lcid; | ||
| 3505 | } | ||
| 3506 | |||
| 3507 | #ifndef _NLSCMPERROR | ||
| 3508 | # define _NLSCMPERROR INT_MAX | ||
| 3509 | #endif | ||
| 3510 | #ifndef LINGUISTIC_IGNORECASE | ||
| 3511 | # define LINGUISTIC_IGNORECASE 0x00000010 | ||
| 3512 | #endif | ||
| 3513 | |||
| 3514 | typedef int (WINAPI *CompareStringW_Proc) | ||
| 3515 | (LCID, DWORD, LPCWSTR, int, LPCWSTR, int); | ||
| 3516 | |||
| 3517 | int | ||
| 3518 | w32_compare_strings (const char *s1, const char *s2, char *locname, | ||
| 3519 | int ignore_case) | ||
| 3520 | { | ||
| 3521 | LCID lcid = GetThreadLocale (); | ||
| 3522 | wchar_t *string1_w, *string2_w; | ||
| 3523 | int val, needed; | ||
| 3524 | extern BOOL g_b_init_compare_string_w; | ||
| 3525 | static CompareStringW_Proc pCompareStringW; | ||
| 3526 | DWORD flags = 0; | ||
| 3527 | |||
| 3528 | USE_SAFE_ALLOCA; | ||
| 3529 | |||
| 3530 | /* The LCID machinery doesn't seem to support the "C" locale, so we | ||
| 3531 | need to do that by hand. */ | ||
| 3532 | if (locname | ||
| 3533 | && ((locname[0] == 'C' && (locname[1] == '\0' || locname[1] == '.')) | ||
| 3534 | || strcmp (locname, "POSIX") == 0)) | ||
| 3535 | return (ignore_case ? stricmp (s1, s2) : strcmp (s1, s2)); | ||
| 3536 | |||
| 3537 | if (!g_b_init_compare_string_w) | ||
| 3538 | { | ||
| 3539 | if (os_subtype == OS_9X) | ||
| 3540 | { | ||
| 3541 | pCompareStringW = | ||
| 3542 | (CompareStringW_Proc) GetProcAddress (LoadLibrary ("Unicows.dll"), | ||
| 3543 | "CompareStringW"); | ||
| 3544 | if (!pCompareStringW) | ||
| 3545 | { | ||
| 3546 | errno = EINVAL; | ||
| 3547 | /* This return value is compatible with wcscoll and | ||
| 3548 | other MS CRT functions. */ | ||
| 3549 | return _NLSCMPERROR; | ||
| 3550 | } | ||
| 3551 | } | ||
| 3552 | else | ||
| 3553 | pCompareStringW = CompareStringW; | ||
| 3554 | |||
| 3555 | g_b_init_compare_string_w = 1; | ||
| 3556 | } | ||
| 3557 | |||
| 3558 | needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s1, -1, NULL, 0); | ||
| 3559 | if (needed > 0) | ||
| 3560 | { | ||
| 3561 | SAFE_NALLOCA (string1_w, 1, needed + 1); | ||
| 3562 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s1, -1, | ||
| 3563 | string1_w, needed); | ||
| 3564 | } | ||
| 3565 | else | ||
| 3566 | { | ||
| 3567 | errno = EINVAL; | ||
| 3568 | return _NLSCMPERROR; | ||
| 3569 | } | ||
| 3570 | |||
| 3571 | needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s2, -1, NULL, 0); | ||
| 3572 | if (needed > 0) | ||
| 3573 | { | ||
| 3574 | SAFE_NALLOCA (string2_w, 1, needed + 1); | ||
| 3575 | pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s2, -1, | ||
| 3576 | string2_w, needed); | ||
| 3577 | } | ||
| 3578 | else | ||
| 3579 | { | ||
| 3580 | SAFE_FREE (); | ||
| 3581 | errno = EINVAL; | ||
| 3582 | return _NLSCMPERROR; | ||
| 3583 | } | ||
| 3584 | |||
| 3585 | if (locname) | ||
| 3586 | { | ||
| 3587 | /* Convert locale name string to LCID. We don't want to use | ||
| 3588 | LocaleNameToLCID because (a) it is only available since | ||
| 3589 | Vista, and (b) it doesn't accept locale names returned by | ||
| 3590 | 'setlocale' and 'GetLocaleInfo'. */ | ||
| 3591 | LCID new_lcid = get_lcid (locname); | ||
| 3592 | |||
| 3593 | if (new_lcid > 0) | ||
| 3594 | lcid = new_lcid; | ||
| 3595 | else | ||
| 3596 | error ("Invalid locale %s: Invalid argument", locname); | ||
| 3597 | } | ||
| 3598 | |||
| 3599 | if (ignore_case) | ||
| 3600 | { | ||
| 3601 | /* NORM_IGNORECASE ignores any tertiary distinction, not just | ||
| 3602 | case variants. LINGUISTIC_IGNORECASE is more selective, and | ||
| 3603 | is sensitive to the locale's language, but it is not | ||
| 3604 | available before Vista. */ | ||
| 3605 | if (w32_major_version >= 6) | ||
| 3606 | flags |= LINGUISTIC_IGNORECASE; | ||
| 3607 | else | ||
| 3608 | flags |= NORM_IGNORECASE; | ||
| 3609 | } | ||
| 3610 | /* This approximates what glibc collation functions do when the | ||
| 3611 | locale's codeset is UTF-8. */ | ||
| 3612 | if (!NILP (Vw32_collate_ignore_punctuation)) | ||
| 3613 | flags |= NORM_IGNORESYMBOLS; | ||
| 3614 | val = pCompareStringW (lcid, flags, string1_w, -1, string2_w, -1); | ||
| 3615 | SAFE_FREE (); | ||
| 3616 | if (!val) | ||
| 3617 | { | ||
| 3618 | errno = EINVAL; | ||
| 3619 | return _NLSCMPERROR; | ||
| 3620 | } | ||
| 3621 | return val - 2; | ||
| 3622 | } | ||
| 3623 | |||
| 3124 | 3624 | ||
| 3125 | void | 3625 | void |
| 3126 | syms_of_ntproc (void) | 3626 | syms_of_ntproc (void) |
| 3127 | { | 3627 | { |
| 3128 | DEFSYM (Qhigh, "high"); | 3628 | DEFSYM (Qhigh, "high"); |
| 3129 | DEFSYM (Qlow, "low"); | 3629 | DEFSYM (Qlow, "low"); |
| 3630 | DEFSYM (Qcygwin, "cygwin"); | ||
| 3631 | DEFSYM (Qmsys, "msys"); | ||
| 3632 | DEFSYM (Qw32_native, "w32-native"); | ||
| 3130 | 3633 | ||
| 3131 | defsubr (&Sw32_has_winsock); | 3634 | defsubr (&Sw32_has_winsock); |
| 3132 | defsubr (&Sw32_unload_winsock); | 3635 | defsubr (&Sw32_unload_winsock); |
| @@ -3134,6 +3637,7 @@ syms_of_ntproc (void) | |||
| 3134 | defsubr (&Sw32_short_file_name); | 3637 | defsubr (&Sw32_short_file_name); |
| 3135 | defsubr (&Sw32_long_file_name); | 3638 | defsubr (&Sw32_long_file_name); |
| 3136 | defsubr (&Sw32_set_process_priority); | 3639 | defsubr (&Sw32_set_process_priority); |
| 3640 | defsubr (&Sw32_application_type); | ||
| 3137 | defsubr (&Sw32_get_locale_info); | 3641 | defsubr (&Sw32_get_locale_info); |
| 3138 | defsubr (&Sw32_get_current_locale_id); | 3642 | defsubr (&Sw32_get_current_locale_id); |
| 3139 | defsubr (&Sw32_get_default_locale_id); | 3643 | defsubr (&Sw32_get_default_locale_id); |
| @@ -3231,6 +3735,20 @@ Any other non-nil value means do this even on remote and removable drives | |||
| 3231 | where the performance impact may be noticeable even on modern hardware. */); | 3735 | where the performance impact may be noticeable even on modern hardware. */); |
| 3232 | Vw32_get_true_file_attributes = Qlocal; | 3736 | Vw32_get_true_file_attributes = Qlocal; |
| 3233 | 3737 | ||
| 3738 | DEFVAR_LISP ("w32-collate-ignore-punctuation", | ||
| 3739 | Vw32_collate_ignore_punctuation, | ||
| 3740 | doc: /* Non-nil causes string collation functions ignore punctuation on MS-Windows. | ||
| 3741 | On Posix platforms, `string-collate-lessp' and `string-collate-equalp' | ||
| 3742 | ignore punctuation characters when they compare strings, if the | ||
| 3743 | locale's codeset is UTF-8, as in \"en_US.UTF-8\". Binding this option | ||
| 3744 | to a non-nil value will achieve a similar effect on MS-Windows, where | ||
| 3745 | locales with UTF-8 codeset are not supported. | ||
| 3746 | |||
| 3747 | Note that setting this to non-nil will also ignore blanks and symbols | ||
| 3748 | in the strings. So do NOT use this option when comparing file names | ||
| 3749 | for equality, only when you need to sort them. */); | ||
| 3750 | Vw32_collate_ignore_punctuation = Qnil; | ||
| 3751 | |||
| 3234 | staticpro (&Vw32_valid_locale_ids); | 3752 | staticpro (&Vw32_valid_locale_ids); |
| 3235 | staticpro (&Vw32_valid_codepages); | 3753 | staticpro (&Vw32_valid_codepages); |
| 3236 | } | 3754 | } |