Mercurial > hg > xemacs-beta
comparison src/ntproc.c @ 282:c42ec1d1cded r21-0b39
Import from CVS: tag r21-0b39
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:33:18 +0200 |
parents | ca9a9ec9c1c1 |
children | e11d67e05968 |
comparison
equal
deleted
inserted
replaced
281:090b52736db2 | 282:c42ec1d1cded |
---|---|
325 /* Hack for Windows 95, which assigns large (ie negative) pids */ | 325 /* Hack for Windows 95, which assigns large (ie negative) pids */ |
326 if (cp->pid < 0) | 326 if (cp->pid < 0) |
327 cp->pid = -cp->pid; | 327 cp->pid = -cp->pid; |
328 | 328 |
329 /* pid must fit in a Lisp_Int */ | 329 /* pid must fit in a Lisp_Int */ |
330 #ifdef USE_UNION_TYPE | |
331 cp->pid = (cp->pid & ((1U << VALBITS) - 1)); | |
332 #else | |
330 cp->pid = (cp->pid & VALMASK); | 333 cp->pid = (cp->pid & VALMASK); |
334 #endif | |
331 | 335 |
332 *pPid = cp->pid; | 336 *pPid = cp->pid; |
333 | 337 |
334 return TRUE; | 338 return TRUE; |
335 | 339 |
955 } | 959 } |
956 | 960 |
957 return pid; | 961 return pid; |
958 } | 962 } |
959 | 963 |
960 /* Emulate the select call | |
961 Wait for available input on any of the given rfds, or timeout if | |
962 a timeout is given and no input is detected | |
963 wfds and efds are not supported and must be NULL. | |
964 | |
965 For simplicity, we detect the death of child processes here and | |
966 synchronously call the SIGCHLD handler. Since it is possible for | |
967 children to be created without a corresponding pipe handle from which | |
968 to read output, we wait separately on the process handles as well as | |
969 the char_avail events for each process pipe. We only call | |
970 wait/reap_process when the process actually terminates. */ | |
971 | |
972 /* From ntterm.c */ | |
973 extern HANDLE keyboard_handle; | |
974 /* From process.c */ | |
975 extern int proc_buffered_char[]; | |
976 | |
977 int | |
978 sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |
979 EMACS_TIME *timeout) | |
980 { | |
981 SELECT_TYPE orfds; | |
982 DWORD timeout_ms, start_time; | |
983 int i, nh, nc, nr; | |
984 DWORD active; | |
985 child_process *cp, *cps[MAX_CHILDREN]; | |
986 HANDLE wait_hnd[MAXDESC + MAX_CHILDREN]; | |
987 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */ | |
988 | |
989 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE; | |
990 | |
991 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */ | |
992 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL) | |
993 { | |
994 Sleep (timeout_ms); | |
995 return 0; | |
996 } | |
997 | |
998 /* Otherwise, we only handle rfds, so fail otherwise. */ | |
999 if (rfds == NULL || wfds != NULL || efds != NULL) | |
1000 { | |
1001 errno = EINVAL; | |
1002 return -1; | |
1003 } | |
1004 | |
1005 orfds = *rfds; | |
1006 FD_ZERO (rfds); | |
1007 nr = 0; | |
1008 | |
1009 /* Build a list of pipe handles to wait on. */ | |
1010 nh = 0; | |
1011 for (i = 0; i < nfds; i++) | |
1012 if (FD_ISSET (i, &orfds)) | |
1013 { | |
1014 if (i == 0) | |
1015 { | |
1016 #if 0 | |
1017 /* Sync with FSF Emacs 19.34.6 note: ifdef'ed out in XEmacs */ | |
1018 if (keyboard_handle) | |
1019 { | |
1020 /* Handle stdin specially */ | |
1021 wait_hnd[nh] = keyboard_handle; | |
1022 fdindex[nh] = i; | |
1023 nh++; | |
1024 } | |
1025 #endif | |
1026 | |
1027 /* Check for any emacs-generated input in the queue since | |
1028 it won't be detected in the wait */ | |
1029 if (detect_input_pending ()) | |
1030 { | |
1031 FD_SET (i, rfds); | |
1032 return 1; | |
1033 } | |
1034 } | |
1035 else | |
1036 { | |
1037 /* Child process and socket input */ | |
1038 cp = fd_info[i].cp; | |
1039 if (cp) | |
1040 { | |
1041 int current_status = cp->status; | |
1042 | |
1043 if (current_status == STATUS_READ_ACKNOWLEDGED) | |
1044 { | |
1045 /* Tell reader thread which file handle to use. */ | |
1046 cp->fd = i; | |
1047 /* Wake up the reader thread for this process */ | |
1048 cp->status = STATUS_READ_READY; | |
1049 if (!SetEvent (cp->char_consumed)) | |
1050 DebPrint (("nt_select.SetEvent failed with " | |
1051 "%lu for fd %ld\n", GetLastError (), i)); | |
1052 } | |
1053 | |
1054 #ifdef CHECK_INTERLOCK | |
1055 /* slightly crude cross-checking of interlock between threads */ | |
1056 | |
1057 current_status = cp->status; | |
1058 if (WaitForSingleObject (cp->char_avail, 0) == WAIT_OBJECT_0) | |
1059 { | |
1060 /* char_avail has been signalled, so status (which may | |
1061 have changed) should indicate read has completed | |
1062 but has not been acknowledged. */ | |
1063 current_status = cp->status; | |
1064 if (current_status != STATUS_READ_SUCCEEDED && | |
1065 current_status != STATUS_READ_FAILED) | |
1066 DebPrint (("char_avail set, but read not completed: status %d\n", | |
1067 current_status)); | |
1068 } | |
1069 else | |
1070 { | |
1071 /* char_avail has not been signalled, so status should | |
1072 indicate that read is in progress; small possibility | |
1073 that read has completed but event wasn't yet signalled | |
1074 when we tested it (because a context switch occurred | |
1075 or if running on separate CPUs). */ | |
1076 if (current_status != STATUS_READ_READY && | |
1077 current_status != STATUS_READ_IN_PROGRESS && | |
1078 current_status != STATUS_READ_SUCCEEDED && | |
1079 current_status != STATUS_READ_FAILED) | |
1080 DebPrint (("char_avail reset, but read status is bad: %d\n", | |
1081 current_status)); | |
1082 } | |
1083 #endif | |
1084 wait_hnd[nh] = cp->char_avail; | |
1085 fdindex[nh] = i; | |
1086 if (!wait_hnd[nh]) abort (); | |
1087 nh++; | |
1088 #ifdef FULL_DEBUG | |
1089 DebPrint (("select waiting on child %d fd %d\n", | |
1090 cp-child_procs, i)); | |
1091 #endif | |
1092 } | |
1093 else | |
1094 { | |
1095 /* Unable to find something to wait on for this fd, skip */ | |
1096 | |
1097 /* Note that this is not a fatal error, and can in fact | |
1098 happen in unusual circumstances. Specifically, if | |
1099 sys_spawnve fails, eg. because the program doesn't | |
1100 exist, and debug-on-error is t so Fsignal invokes a | |
1101 nested input loop, then the process output pipe is | |
1102 still included in input_wait_mask with no child_proc | |
1103 associated with it. (It is removed when the debugger | |
1104 exits the nested input loop and the error is thrown.) */ | |
1105 | |
1106 DebPrint (("sys_select: fd %ld is invalid! ignoring\n", i)); | |
1107 } | |
1108 } | |
1109 } | |
1110 | |
1111 count_children: | |
1112 /* Add handles of child processes. */ | |
1113 nc = 0; | |
1114 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--) | |
1115 /* Some child_procs might be sockets; ignore them. Also some | |
1116 children may have died already, but we haven't finished reading | |
1117 the process output; ignore them too. */ | |
1118 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess | |
1119 && (cp->fd < 0 | |
1120 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 | |
1121 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) | |
1122 ) | |
1123 { | |
1124 wait_hnd[nh + nc] = cp->procinfo.hProcess; | |
1125 cps[nc] = cp; | |
1126 nc++; | |
1127 } | |
1128 | |
1129 /* Nothing to look for, so we didn't find anything */ | |
1130 if (nh + nc == 0) | |
1131 { | |
1132 if (timeout) | |
1133 Sleep (timeout_ms); | |
1134 return 0; | |
1135 } | |
1136 | |
1137 /* Wait for input or child death to be signalled. */ | |
1138 start_time = GetTickCount (); | |
1139 active = WaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms); | |
1140 | |
1141 if (active == WAIT_FAILED) | |
1142 { | |
1143 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n", | |
1144 nh + nc, timeout_ms, GetLastError ())); | |
1145 /* don't return EBADF - this causes wait_reading_process_input to | |
1146 abort; WAIT_FAILED is returned when single-stepping under | |
1147 Windows 95 after switching thread focus in debugger, and | |
1148 possibly at other times. */ | |
1149 errno = EINTR; | |
1150 return -1; | |
1151 } | |
1152 else if (active == WAIT_TIMEOUT) | |
1153 { | |
1154 return 0; | |
1155 } | |
1156 else if (active >= WAIT_OBJECT_0 && | |
1157 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS) | |
1158 { | |
1159 active -= WAIT_OBJECT_0; | |
1160 } | |
1161 else if (active >= WAIT_ABANDONED_0 && | |
1162 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS) | |
1163 { | |
1164 active -= WAIT_ABANDONED_0; | |
1165 } | |
1166 else | |
1167 abort (); | |
1168 | |
1169 /* Loop over all handles after active (now officially documented as | |
1170 being the first signalled handle in the array). We do this to | |
1171 ensure fairness, so that all channels with data available will be | |
1172 processed - otherwise higher numbered channels could be starved. */ | |
1173 do | |
1174 { | |
1175 if (active >= nh) | |
1176 { | |
1177 cp = cps[active - nh]; | |
1178 | |
1179 /* We cannot always signal SIGCHLD immediately; if we have not | |
1180 finished reading the process output, we must delay sending | |
1181 SIGCHLD until we do. */ | |
1182 | |
1183 if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_AT_EOF) == 0) | |
1184 fd_info[cp->fd].flags |= FILE_SEND_SIGCHLD; | |
1185 /* SIG_DFL for SIGCHLD is ignore */ | |
1186 else | |
1187 { | |
1188 #ifdef FULL_DEBUG | |
1189 DebPrint (("select is raising SIGCHLD handler for pid %d\n", | |
1190 cp->pid)); | |
1191 #endif | |
1192 dead_child = cp; | |
1193 /* msw_raise (SIGCHLD); -kkm: I will erase this file | |
1194 slowly, line by line, character by character, | |
1195 I will press undo often, to prolong this. | |
1196 Even such a revenge will not be enough for it!!! */ | |
1197 dead_child = NULL; | |
1198 } | |
1199 } | |
1200 else if (fdindex[active] == 0) | |
1201 { | |
1202 /* Keyboard input available */ | |
1203 FD_SET (0, rfds); | |
1204 nr++; | |
1205 } | |
1206 else | |
1207 { | |
1208 /* must be a socket or pipe - read ahead should have | |
1209 completed, either succeeding or failing. */ | |
1210 FD_SET (fdindex[active], rfds); | |
1211 nr++; | |
1212 } | |
1213 | |
1214 /* Even though wait_reading_process_output only reads from at most | |
1215 one channel, we must process all channels here so that we reap | |
1216 all children that have died. */ | |
1217 while (++active < nh + nc) | |
1218 if (WaitForSingleObject (wait_hnd[active], 0) == WAIT_OBJECT_0) | |
1219 break; | |
1220 } while (active < nh + nc); | |
1221 | |
1222 /* If no input has arrived and timeout hasn't expired, wait again. */ | |
1223 if (nr == 0) | |
1224 { | |
1225 DWORD elapsed = GetTickCount () - start_time; | |
1226 | |
1227 if (timeout_ms > elapsed) /* INFINITE is MAX_UINT */ | |
1228 { | |
1229 if (timeout_ms != INFINITE) | |
1230 timeout_ms -= elapsed; | |
1231 goto count_children; | |
1232 } | |
1233 } | |
1234 | |
1235 return nr; | |
1236 } | |
1237 | |
1238 /* Substitute for certain kill () operations */ | 964 /* Substitute for certain kill () operations */ |
1239 | 965 |
1240 static BOOL CALLBACK | 966 static BOOL CALLBACK |
1241 find_child_console (HWND hwnd, child_process * cp) | 967 find_child_console (HWND hwnd, child_process * cp) |
1242 { | 968 { |
1491 void | 1217 void |
1492 set_process_dir (char * dir) | 1218 set_process_dir (char * dir) |
1493 { | 1219 { |
1494 process_dir = dir; | 1220 process_dir = dir; |
1495 } | 1221 } |
1496 | |
1497 #ifdef HAVE_SOCKETS | |
1498 | |
1499 /* To avoid problems with winsock implementations that work over dial-up | |
1500 connections causing or requiring a connection to exist while Emacs is | |
1501 running, Emacs no longer automatically loads winsock on startup if it | |
1502 is present. Instead, it will be loaded when open-network-stream is | |
1503 first called. | |
1504 | |
1505 To allow full control over when winsock is loaded, we provide these | |
1506 two functions to dynamically load and unload winsock. This allows | |
1507 dial-up users to only be connected when they actually need to use | |
1508 socket services. */ | |
1509 | |
1510 /* From nt.c */ | |
1511 extern HANDLE winsock_lib; | |
1512 extern BOOL term_winsock (void); | |
1513 extern BOOL init_winsock (int load_now); | |
1514 | |
1515 extern Lisp_Object Vsystem_name; | |
1516 | |
1517 DEFUN ("win32-has-winsock", Fwin32_has_winsock, 0, 1, "", /* | |
1518 Test for presence of the Windows socket library `winsock'. | |
1519 Returns non-nil if winsock support is present, nil otherwise. | |
1520 | |
1521 If the optional argument LOAD-NOW is non-nil, the winsock library is | |
1522 also loaded immediately if not already loaded. If winsock is loaded, | |
1523 the winsock local hostname is returned (since this may be different from | |
1524 the value of `system-name' and should supplant it), otherwise t is | |
1525 returned to indicate winsock support is present. | |
1526 */ | |
1527 (load_now)) | |
1528 { | |
1529 int have_winsock; | |
1530 | |
1531 have_winsock = init_winsock (!NILP (load_now)); | |
1532 if (have_winsock) | |
1533 { | |
1534 if (winsock_lib != NULL) | |
1535 { | |
1536 /* Return new value for system-name. The best way to do this | |
1537 is to call init_system_name, saving and restoring the | |
1538 original value to avoid side-effects. */ | |
1539 Lisp_Object orig_hostname = Vsystem_name; | |
1540 Lisp_Object hostname; | |
1541 | |
1542 init_system_name (); | |
1543 hostname = Vsystem_name; | |
1544 Vsystem_name = orig_hostname; | |
1545 return hostname; | |
1546 } | |
1547 return Qt; | |
1548 } | |
1549 return Qnil; | |
1550 } | |
1551 | |
1552 DEFUN ("win32-unload-winsock", Fwin32_unload_winsock, 0, 0, "", /* | |
1553 Unload the Windows socket library `winsock' if loaded. | |
1554 This is provided to allow dial-up socket connections to be disconnected | |
1555 when no longer needed. Returns nil without unloading winsock if any | |
1556 socket connections still exist. | |
1557 */ | |
1558 ()) | |
1559 { | |
1560 return term_winsock () ? Qt : Qnil; | |
1561 } | |
1562 | |
1563 #endif /* HAVE_SOCKETS */ | |
1564 | |
1565 | 1222 |
1566 /* Some miscellaneous functions that are Windows specific, but not GUI | 1223 /* Some miscellaneous functions that are Windows specific, but not GUI |
1567 specific (ie. are applicable in terminal or batch mode as well). */ | 1224 specific (ie. are applicable in terminal or batch mode as well). */ |
1568 | 1225 |
1569 /* lifted from fileio.c */ | 1226 /* lifted from fileio.c */ |
1816 syms_of_ntproc () | 1473 syms_of_ntproc () |
1817 { | 1474 { |
1818 Qhigh = intern ("high"); | 1475 Qhigh = intern ("high"); |
1819 Qlow = intern ("low"); | 1476 Qlow = intern ("low"); |
1820 | 1477 |
1821 #ifdef HAVE_SOCKETS | |
1822 DEFSUBR (Fwin32_has_winsock); | |
1823 DEFSUBR (Fwin32_unload_winsock); | |
1824 #endif | |
1825 DEFSUBR (Fwin32_short_file_name); | 1478 DEFSUBR (Fwin32_short_file_name); |
1826 DEFSUBR (Fwin32_long_file_name); | 1479 DEFSUBR (Fwin32_long_file_name); |
1827 DEFSUBR (Fwin32_set_process_priority); | 1480 DEFSUBR (Fwin32_set_process_priority); |
1828 DEFSUBR (Fwin32_get_locale_info); | 1481 DEFSUBR (Fwin32_get_locale_info); |
1829 DEFSUBR (Fwin32_get_current_locale_id); | 1482 DEFSUBR (Fwin32_get_current_locale_id); |
1860 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't | 1513 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't |
1861 otherwise respond to interrupts from Emacs. | 1514 otherwise respond to interrupts from Emacs. |
1862 */ ); | 1515 */ ); |
1863 Vwin32_start_process_share_console = Qnil; | 1516 Vwin32_start_process_share_console = Qnil; |
1864 | 1517 |
1865 DEFVAR_INT ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /* | 1518 DEFVAR_LISP ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /* |
1866 Forced delay before reading subprocess output. | 1519 Forced delay before reading subprocess output. |
1867 This is done to improve the buffering of subprocess output, by | 1520 This is done to improve the buffering of subprocess output, by |
1868 avoiding the inefficiency of frequently reading small amounts of data. | 1521 avoiding the inefficiency of frequently reading small amounts of data. |
1869 | 1522 |
1870 If positive, the value is the number of milliseconds to sleep before | 1523 If positive, the value is the number of milliseconds to sleep before |
1871 reading the subprocess output. If negative, the magnitude is the number | 1524 reading the subprocess output. If negative, the magnitude is the number |
1872 of time slices to wait (effectively boosting the priority of the child | 1525 of time slices to wait (effectively boosting the priority of the child |
1873 process temporarily). A value of zero disables waiting entirely. | 1526 process temporarily). A value of zero disables waiting entirely. |
1874 */ ); | 1527 */ ); |
1875 Vwin32_pipe_read_delay = 50; | 1528 Vwin32_pipe_read_delay = make_int (50); |
1876 | 1529 |
1877 #if 0 | 1530 #if 0 |
1878 DEFVAR_LISP ("win32-generate-fake-inodes", &Vwin32_generate_fake_inodes /* | 1531 DEFVAR_LISP ("win32-generate-fake-inodes", &Vwin32_generate_fake_inodes /* |
1879 "Non-nil means attempt to fake realistic inode values. | 1532 "Non-nil means attempt to fake realistic inode values. |
1880 This works by hashing the truename of files, and should detect | 1533 This works by hashing the truename of files, and should detect |