comparison src/w32proc.c @ 49600:23a1cea22d13

Trailing whitespace deleted.
author Juanma Barranquero <lekktu@gmail.com>
date Tue, 04 Feb 2003 14:56:31 +0000
parents 514398573221
children 695cf19ef79e d7ddb3e565de
comparison
equal deleted inserted replaced
49599:5ade352e8d1c 49600:23a1cea22d13
118 118
119 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */ 119 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
120 static signal_handler sig_handlers[NSIG]; 120 static signal_handler sig_handlers[NSIG];
121 121
122 /* Fake signal implementation to record the SIGCHLD handler. */ 122 /* Fake signal implementation to record the SIGCHLD handler. */
123 signal_handler 123 signal_handler
124 sys_signal (int sig, signal_handler handler) 124 sys_signal (int sig, signal_handler handler)
125 { 125 {
126 signal_handler old; 126 signal_handler old;
127 127
128 if (sig != SIGCHLD) 128 if (sig != SIGCHLD)
129 { 129 {
130 errno = EINVAL; 130 errno = EINVAL;
131 return SIG_ERR; 131 return SIG_ERR;
132 } 132 }
149 child_process * 149 child_process *
150 new_child (void) 150 new_child (void)
151 { 151 {
152 child_process *cp; 152 child_process *cp;
153 DWORD id; 153 DWORD id;
154 154
155 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--) 155 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
156 if (!CHILD_ACTIVE (cp)) 156 if (!CHILD_ACTIVE (cp))
157 goto Initialise; 157 goto Initialise;
158 if (child_proc_count == MAX_CHILDREN) 158 if (child_proc_count == MAX_CHILDREN)
159 return NULL; 159 return NULL;
180 } 180 }
181 delete_child (cp); 181 delete_child (cp);
182 return NULL; 182 return NULL;
183 } 183 }
184 184
185 void 185 void
186 delete_child (child_process *cp) 186 delete_child (child_process *cp)
187 { 187 {
188 int i; 188 int i;
189 189
190 /* Should not be deleting a child that is still needed. */ 190 /* Should not be deleting a child that is still needed. */
255 255
256 /* Thread proc for child process and socket reader threads. Each thread 256 /* Thread proc for child process and socket reader threads. Each thread
257 is normally blocked until woken by select() to check for input by 257 is normally blocked until woken by select() to check for input by
258 reading one char. When the read completes, char_avail is signalled 258 reading one char. When the read completes, char_avail is signalled
259 to wake up the select emulator and the thread blocks itself again. */ 259 to wake up the select emulator and the thread blocks itself again. */
260 DWORD WINAPI 260 DWORD WINAPI
261 reader_thread (void *arg) 261 reader_thread (void *arg)
262 { 262 {
263 child_process *cp; 263 child_process *cp;
264 264
265 /* Our identity */ 265 /* Our identity */
266 cp = (child_process *)arg; 266 cp = (child_process *)arg;
267 267
268 /* We have to wait for the go-ahead before we can start */ 268 /* We have to wait for the go-ahead before we can start */
269 if (cp == NULL 269 if (cp == NULL
270 || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) 270 || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
271 return 1; 271 return 1;
272 272
285 return 1; 285 return 1;
286 } 286 }
287 287
288 if (rc == STATUS_READ_ERROR) 288 if (rc == STATUS_READ_ERROR)
289 return 1; 289 return 1;
290 290
291 /* If the read died, the child has died so let the thread die */ 291 /* If the read died, the child has died so let the thread die */
292 if (rc == STATUS_READ_FAILED) 292 if (rc == STATUS_READ_FAILED)
293 break; 293 break;
294 294
295 /* Wait until our input is acknowledged before reading again */ 295 /* Wait until our input is acknowledged before reading again */
296 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) 296 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
297 { 297 {
298 DebPrint (("reader_thread.WaitForSingleObject failed with " 298 DebPrint (("reader_thread.WaitForSingleObject failed with "
299 "%lu for fd %ld\n", GetLastError (), cp->fd)); 299 "%lu for fd %ld\n", GetLastError (), cp->fd));
306 /* To avoid Emacs changing directory, we just record here the directory 306 /* To avoid Emacs changing directory, we just record here the directory
307 the new process should start in. This is set just before calling 307 the new process should start in. This is set just before calling
308 sys_spawnve, and is not generally valid at any other time. */ 308 sys_spawnve, and is not generally valid at any other time. */
309 static char * process_dir; 309 static char * process_dir;
310 310
311 static BOOL 311 static BOOL
312 create_child (char *exe, char *cmdline, char *env, int is_gui_app, 312 create_child (char *exe, char *cmdline, char *env, int is_gui_app,
313 int * pPid, child_process *cp) 313 int * pPid, child_process *cp)
314 { 314 {
315 STARTUPINFO start; 315 STARTUPINFO start;
316 SECURITY_ATTRIBUTES sec_attrs; 316 SECURITY_ATTRIBUTES sec_attrs;
317 #if 0 317 #if 0
318 SECURITY_DESCRIPTOR sec_desc; 318 SECURITY_DESCRIPTOR sec_desc;
319 #endif 319 #endif
320 DWORD flags; 320 DWORD flags;
321 char dir[ MAXPATHLEN ]; 321 char dir[ MAXPATHLEN ];
322 322
323 if (cp == NULL) abort (); 323 if (cp == NULL) abort ();
324 324
325 memset (&start, 0, sizeof (start)); 325 memset (&start, 0, sizeof (start));
326 start.cb = sizeof (start); 326 start.cb = sizeof (start);
327 327
328 #ifdef HAVE_NTGUI 328 #ifdef HAVE_NTGUI
329 if (NILP (Vw32_start_process_show_window) && !is_gui_app) 329 if (NILP (Vw32_start_process_show_window) && !is_gui_app)
330 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 330 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
331 else 331 else
332 start.dwFlags = STARTF_USESTDHANDLES; 332 start.dwFlags = STARTF_USESTDHANDLES;
345 goto EH_Fail; 345 goto EH_Fail;
346 #endif 346 #endif
347 sec_attrs.nLength = sizeof (sec_attrs); 347 sec_attrs.nLength = sizeof (sec_attrs);
348 sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */; 348 sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */;
349 sec_attrs.bInheritHandle = FALSE; 349 sec_attrs.bInheritHandle = FALSE;
350 350
351 strcpy (dir, process_dir); 351 strcpy (dir, process_dir);
352 unixtodos_filename (dir); 352 unixtodos_filename (dir);
353 353
354 flags = (!NILP (Vw32_start_process_share_console) 354 flags = (!NILP (Vw32_start_process_share_console)
355 ? CREATE_NEW_PROCESS_GROUP 355 ? CREATE_NEW_PROCESS_GROUP
381 /* create_child doesn't know what emacs' file handle will be for waiting 381 /* create_child doesn't know what emacs' file handle will be for waiting
382 on output from the child, so we need to make this additional call 382 on output from the child, so we need to make this additional call
383 to register the handle with the process 383 to register the handle with the process
384 This way the select emulator knows how to match file handles with 384 This way the select emulator knows how to match file handles with
385 entries in child_procs. */ 385 entries in child_procs. */
386 void 386 void
387 register_child (int pid, int fd) 387 register_child (int pid, int fd)
388 { 388 {
389 child_process *cp; 389 child_process *cp;
390 390
391 cp = find_child_pid (pid); 391 cp = find_child_pid (pid);
392 if (cp == NULL) 392 if (cp == NULL)
393 { 393 {
394 DebPrint (("register_child unable to find pid %lu\n", pid)); 394 DebPrint (("register_child unable to find pid %lu\n", pid));
395 return; 395 return;
396 } 396 }
397 397
398 #ifdef FULL_DEBUG 398 #ifdef FULL_DEBUG
399 DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid)); 399 DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid));
400 #endif 400 #endif
401 401
402 cp->fd = fd; 402 cp->fd = fd;
403 403
404 /* thread is initially blocked until select is called; set status so 404 /* thread is initially blocked until select is called; set status so
405 that select will release thread */ 405 that select will release thread */
406 cp->status = STATUS_READ_ACKNOWLEDGED; 406 cp->status = STATUS_READ_ACKNOWLEDGED;
417 417
418 /* When a process dies its pipe will break so the reader thread will 418 /* When a process dies its pipe will break so the reader thread will
419 signal failure to the select emulator. 419 signal failure to the select emulator.
420 The select emulator then calls this routine to clean up. 420 The select emulator then calls this routine to clean up.
421 Since the thread signaled failure we can assume it is exiting. */ 421 Since the thread signaled failure we can assume it is exiting. */
422 static void 422 static void
423 reap_subprocess (child_process *cp) 423 reap_subprocess (child_process *cp)
424 { 424 {
425 if (cp->procinfo.hProcess) 425 if (cp->procinfo.hProcess)
426 { 426 {
427 /* Reap the process */ 427 /* Reap the process */
446 446
447 /* Wait for any of our existing child processes to die 447 /* Wait for any of our existing child processes to die
448 When it does, close its handle 448 When it does, close its handle
449 Return the pid and fill in the status if non-NULL. */ 449 Return the pid and fill in the status if non-NULL. */
450 450
451 int 451 int
452 sys_wait (int *status) 452 sys_wait (int *status)
453 { 453 {
454 DWORD active, retval; 454 DWORD active, retval;
455 int nh; 455 int nh;
456 int pid; 456 int pid;
457 child_process *cp, *cps[MAX_CHILDREN]; 457 child_process *cp, *cps[MAX_CHILDREN];
458 HANDLE wait_hnd[MAX_CHILDREN]; 458 HANDLE wait_hnd[MAX_CHILDREN];
459 459
460 nh = 0; 460 nh = 0;
461 if (dead_child != NULL) 461 if (dead_child != NULL)
462 { 462 {
463 /* We want to wait for a specific child */ 463 /* We want to wait for a specific child */
464 wait_hnd[nh] = dead_child->procinfo.hProcess; 464 wait_hnd[nh] = dead_child->procinfo.hProcess;
477 wait_hnd[nh] = cp->procinfo.hProcess; 477 wait_hnd[nh] = cp->procinfo.hProcess;
478 cps[nh] = cp; 478 cps[nh] = cp;
479 nh++; 479 nh++;
480 } 480 }
481 } 481 }
482 482
483 if (nh == 0) 483 if (nh == 0)
484 { 484 {
485 /* Nothing to wait on, so fail */ 485 /* Nothing to wait on, so fail */
486 errno = ECHILD; 486 errno = ECHILD;
487 return -1; 487 return -1;
533 533
534 if (retval == STATUS_CONTROL_C_EXIT) 534 if (retval == STATUS_CONTROL_C_EXIT)
535 retval = SIGINT; 535 retval = SIGINT;
536 else 536 else
537 retval <<= 8; 537 retval <<= 8;
538 538
539 cp = cps[active]; 539 cp = cps[active];
540 pid = cp->pid; 540 pid = cp->pid;
541 #ifdef FULL_DEBUG 541 #ifdef FULL_DEBUG
542 DebPrint (("Wait signaled with process pid %d\n", cp->pid)); 542 DebPrint (("Wait signaled with process pid %d\n", cp->pid));
543 #endif 543 #endif
569 569
570 reap_subprocess (cp); 570 reap_subprocess (cp);
571 } 571 }
572 572
573 reap_subprocess (cp); 573 reap_subprocess (cp);
574 574
575 return pid; 575 return pid;
576 } 576 }
577 577
578 void 578 void
579 w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app, int * is_gui_app) 579 w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app, int * is_gui_app)
580 { 580 {
581 file_data executable; 581 file_data executable;
582 char * p; 582 char * p;
583 583
584 /* Default values in case we can't tell for sure. */ 584 /* Default values in case we can't tell for sure. */
585 *is_dos_app = FALSE; 585 *is_dos_app = FALSE;
586 *is_cygnus_app = FALSE; 586 *is_cygnus_app = FALSE;
587 *is_gui_app = FALSE; 587 *is_gui_app = FALSE;
588 588
589 if (!open_input_file (&executable, filename)) 589 if (!open_input_file (&executable, filename))
590 return; 590 return;
591 591
592 p = strrchr (filename, '.'); 592 p = strrchr (filename, '.');
593 593
594 /* We can only identify DOS .com programs from the extension. */ 594 /* We can only identify DOS .com programs from the extension. */
595 if (p && stricmp (p, ".com") == 0) 595 if (p && stricmp (p, ".com") == 0)
596 *is_dos_app = TRUE; 596 *is_dos_app = TRUE;
597 else if (p && (stricmp (p, ".bat") == 0 597 else if (p && (stricmp (p, ".bat") == 0
598 || stricmp (p, ".cmd") == 0)) 598 || stricmp (p, ".cmd") == 0))
621 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) 621 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
622 goto unwind; 622 goto unwind;
623 623
624 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew); 624 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
625 625
626 if ((char *) nt_header > (char *) dos_header + executable.size) 626 if ((char *) nt_header > (char *) dos_header + executable.size)
627 { 627 {
628 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */ 628 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
629 *is_dos_app = TRUE; 629 *is_dos_app = TRUE;
630 } 630 }
631 else if (nt_header->Signature != IMAGE_NT_SIGNATURE 631 else if (nt_header->Signature != IMAGE_NT_SIGNATURE
632 && LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE) 632 && LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
633 { 633 {
634 *is_dos_app = TRUE; 634 *is_dos_app = TRUE;
635 } 635 }
662 GUI) app. Accept Posix and OS2 subsytem apps as console 662 GUI) app. Accept Posix and OS2 subsytem apps as console
663 apps. */ 663 apps. */
664 *is_gui_app = (nt_header->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI); 664 *is_gui_app = (nt_header->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
665 } 665 }
666 } 666 }
667 667
668 unwind: 668 unwind:
669 close_file_data (&executable); 669 close_file_data (&executable);
670 } 670 }
671 671
672 int 672 int
715 *nptr = NULL; 715 *nptr = NULL;
716 } 716 }
717 717
718 /* When a new child process is created we need to register it in our list, 718 /* When a new child process is created we need to register it in our list,
719 so intercept spawn requests. */ 719 so intercept spawn requests. */
720 int 720 int
721 sys_spawnve (int mode, char *cmdname, char **argv, char **envp) 721 sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
722 { 722 {
723 Lisp_Object program, full; 723 Lisp_Object program, full;
724 char *cmdline, *env, *parg, **targ; 724 char *cmdline, *env, *parg, **targ;
725 int arglen, numenv; 725 int arglen, numenv;
744 /* Handle executable names without an executable suffix. */ 744 /* Handle executable names without an executable suffix. */
745 program = make_string (cmdname, strlen (cmdname)); 745 program = make_string (cmdname, strlen (cmdname));
746 if (NILP (Ffile_executable_p (program))) 746 if (NILP (Ffile_executable_p (program)))
747 { 747 {
748 struct gcpro gcpro1; 748 struct gcpro gcpro1;
749 749
750 full = Qnil; 750 full = Qnil;
751 GCPRO1 (program); 751 GCPRO1 (program);
752 openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK)); 752 openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
753 UNGCPRO; 753 UNGCPRO;
754 if (NILP (full)) 754 if (NILP (full))
787 strcpy (cmdname, SDATA (Vinvocation_directory)); 787 strcpy (cmdname, SDATA (Vinvocation_directory));
788 strcat (cmdname, "cmdproxy.exe"); 788 strcat (cmdname, "cmdproxy.exe");
789 } 789 }
790 unixtodos_filename (cmdname); 790 unixtodos_filename (cmdname);
791 } 791 }
792 792
793 /* we have to do some conjuring here to put argv and envp into the 793 /* we have to do some conjuring here to put argv and envp into the
794 form CreateProcess wants... argv needs to be a space separated/null 794 form CreateProcess wants... argv needs to be a space separated/null
795 terminated list of parameters, and envp is a null 795 terminated list of parameters, and envp is a null
796 separated/double-null terminated list of parameters. 796 separated/double-null terminated list of parameters.
797 797
828 if (INTEGERP (Vw32_quote_process_args)) 828 if (INTEGERP (Vw32_quote_process_args))
829 escape_char = XINT (Vw32_quote_process_args); 829 escape_char = XINT (Vw32_quote_process_args);
830 else 830 else
831 escape_char = is_cygnus_app ? '"' : '\\'; 831 escape_char = is_cygnus_app ? '"' : '\\';
832 } 832 }
833 833
834 /* Cygwin apps needs quoting a bit more often */ 834 /* Cygwin apps needs quoting a bit more often */
835 if (escape_char == '"') 835 if (escape_char == '"')
836 sepchars = "\r\n\t\f '"; 836 sepchars = "\r\n\t\f '";
837 837
838 /* do argv... */ 838 /* do argv... */
839 arglen = 0; 839 arglen = 0;
964 } 964 }
965 *parg++ = ' '; 965 *parg++ = ' ';
966 targ++; 966 targ++;
967 } 967 }
968 *--parg = '\0'; 968 *--parg = '\0';
969 969
970 /* and envp... */ 970 /* and envp... */
971 arglen = 1; 971 arglen = 1;
972 targ = envp; 972 targ = envp;
973 numenv = 1; /* for end null */ 973 numenv = 1; /* for end null */
974 while (*targ) 974 while (*targ)
975 { 975 {
976 arglen += strlen (*targ++) + 1; 976 arglen += strlen (*targ++) + 1;
977 numenv++; 977 numenv++;
978 } 978 }
979 /* extra env vars... */ 979 /* extra env vars... */
980 sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d", 980 sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d",
981 GetCurrentProcessId ()); 981 GetCurrentProcessId ());
982 arglen += strlen (ppid_env_var_buffer) + 1; 982 arglen += strlen (ppid_env_var_buffer) + 1;
983 numenv++; 983 numenv++;
984 984
985 /* merge env passed in and extra env into one, and sort it. */ 985 /* merge env passed in and extra env into one, and sort it. */
1002 if (cp == NULL) 1002 if (cp == NULL)
1003 { 1003 {
1004 errno = EAGAIN; 1004 errno = EAGAIN;
1005 return -1; 1005 return -1;
1006 } 1006 }
1007 1007
1008 /* Now create the process. */ 1008 /* Now create the process. */
1009 if (!create_child (cmdname, cmdline, env, is_gui_app, &pid, cp)) 1009 if (!create_child (cmdname, cmdline, env, is_gui_app, &pid, cp))
1010 { 1010 {
1011 delete_child (cp); 1011 delete_child (cp);
1012 errno = ENOEXEC; 1012 errno = ENOEXEC;
1013 return -1; 1013 return -1;
1014 } 1014 }
1015 1015
1016 return pid; 1016 return pid;
1017 } 1017 }
1018 1018
1019 /* Emulate the select call 1019 /* Emulate the select call
1020 Wait for available input on any of the given rfds, or timeout if 1020 Wait for available input on any of the given rfds, or timeout if
1041 extern HANDLE interrupt_handle; 1041 extern HANDLE interrupt_handle;
1042 1042
1043 /* From process.c */ 1043 /* From process.c */
1044 extern int proc_buffered_char[]; 1044 extern int proc_buffered_char[];
1045 1045
1046 int 1046 int
1047 sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, 1047 sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1048 EMACS_TIME *timeout) 1048 EMACS_TIME *timeout)
1049 { 1049 {
1050 SELECT_TYPE orfds; 1050 SELECT_TYPE orfds;
1051 DWORD timeout_ms, start_time; 1051 DWORD timeout_ms, start_time;
1052 int i, nh, nc, nr; 1052 int i, nh, nc, nr;
1053 DWORD active; 1053 DWORD active;
1054 child_process *cp, *cps[MAX_CHILDREN]; 1054 child_process *cp, *cps[MAX_CHILDREN];
1055 HANDLE wait_hnd[MAXDESC + MAX_CHILDREN]; 1055 HANDLE wait_hnd[MAXDESC + MAX_CHILDREN];
1056 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */ 1056 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */
1057 1057
1058 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE; 1058 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
1059 1059
1060 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */ 1060 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
1061 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL) 1061 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
1062 { 1062 {
1063 Sleep (timeout_ms); 1063 Sleep (timeout_ms);
1064 return 0; 1064 return 0;
1065 } 1065 }
1066 1066
1068 if (rfds == NULL || wfds != NULL || efds != NULL) 1068 if (rfds == NULL || wfds != NULL || efds != NULL)
1069 { 1069 {
1070 errno = EINVAL; 1070 errno = EINVAL;
1071 return -1; 1071 return -1;
1072 } 1072 }
1073 1073
1074 orfds = *rfds; 1074 orfds = *rfds;
1075 FD_ZERO (rfds); 1075 FD_ZERO (rfds);
1076 nr = 0; 1076 nr = 0;
1077 1077
1078 /* Always wait on interrupt_handle, to detect C-g (quit). */ 1078 /* Always wait on interrupt_handle, to detect C-g (quit). */
1079 wait_hnd[0] = interrupt_handle; 1079 wait_hnd[0] = interrupt_handle;
1080 fdindex[0] = -1; 1080 fdindex[0] = -1;
1081 1081
1082 /* Build a list of pipe handles to wait on. */ 1082 /* Build a list of pipe handles to wait on. */
1083 nh = 1; 1083 nh = 1;
1084 for (i = 0; i < nfds; i++) 1084 for (i = 0; i < nfds; i++)
1085 if (FD_ISSET (i, &orfds)) 1085 if (FD_ISSET (i, &orfds))
1086 { 1086 {
1193 { 1193 {
1194 wait_hnd[nh + nc] = cp->procinfo.hProcess; 1194 wait_hnd[nh + nc] = cp->procinfo.hProcess;
1195 cps[nc] = cp; 1195 cps[nc] = cp;
1196 nc++; 1196 nc++;
1197 } 1197 }
1198 1198
1199 /* Nothing to look for, so we didn't find anything */ 1199 /* Nothing to look for, so we didn't find anything */
1200 if (nh + nc == 0) 1200 if (nh + nc == 0)
1201 { 1201 {
1202 if (timeout) 1202 if (timeout)
1203 Sleep (timeout_ms); 1203 Sleep (timeout_ms);
1204 return 0; 1204 return 0;
1205 } 1205 }
1206 1206
1207 start_time = GetTickCount (); 1207 start_time = GetTickCount ();
1208 1208
1209 /* Wait for input or child death to be signalled. If user input is 1209 /* Wait for input or child death to be signalled. If user input is
1210 allowed, then also accept window messages. */ 1210 allowed, then also accept window messages. */
1211 if (FD_ISSET (0, &orfds)) 1211 if (FD_ISSET (0, &orfds))
1360 } 1360 }
1361 /* keep looking */ 1361 /* keep looking */
1362 return TRUE; 1362 return TRUE;
1363 } 1363 }
1364 1364
1365 int 1365 int
1366 sys_kill (int pid, int sig) 1366 sys_kill (int pid, int sig)
1367 { 1367 {
1368 child_process *cp; 1368 child_process *cp;
1369 HANDLE proc_hand; 1369 HANDLE proc_hand;
1370 int need_to_free = 0; 1370 int need_to_free = 0;
1371 int rc = 0; 1371 int rc = 0;
1372 1372
1373 /* Only handle signals that will result in the process dying */ 1373 /* Only handle signals that will result in the process dying */
1374 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) 1374 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
1375 { 1375 {
1376 errno = EINVAL; 1376 errno = EINVAL;
1377 return -1; 1377 return -1;
1394 pid = cp->procinfo.dwProcessId; 1394 pid = cp->procinfo.dwProcessId;
1395 1395
1396 /* Try to locate console window for process. */ 1396 /* Try to locate console window for process. */
1397 EnumWindows (find_child_console, (LPARAM) cp); 1397 EnumWindows (find_child_console, (LPARAM) cp);
1398 } 1398 }
1399 1399
1400 if (sig == SIGINT || sig == SIGQUIT) 1400 if (sig == SIGINT || sig == SIGQUIT)
1401 { 1401 {
1402 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) 1402 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
1403 { 1403 {
1404 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0); 1404 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
1570 handles[0] = GetStdHandle (STD_INPUT_HANDLE); 1570 handles[0] = GetStdHandle (STD_INPUT_HANDLE);
1571 handles[1] = GetStdHandle (STD_OUTPUT_HANDLE); 1571 handles[1] = GetStdHandle (STD_OUTPUT_HANDLE);
1572 handles[2] = GetStdHandle (STD_ERROR_HANDLE); 1572 handles[2] = GetStdHandle (STD_ERROR_HANDLE);
1573 1573
1574 /* make inheritable copies of the new handles */ 1574 /* make inheritable copies of the new handles */
1575 if (!DuplicateHandle (parent, 1575 if (!DuplicateHandle (parent,
1576 (HANDLE) _get_osfhandle (in), 1576 (HANDLE) _get_osfhandle (in),
1577 parent, 1577 parent,
1578 &newstdin, 1578 &newstdin,
1579 0, 1579 0,
1580 TRUE, 1580 TRUE,
1581 DUPLICATE_SAME_ACCESS)) 1581 DUPLICATE_SAME_ACCESS))
1582 report_file_error ("Duplicating input handle for child", Qnil); 1582 report_file_error ("Duplicating input handle for child", Qnil);
1583 1583
1584 if (!DuplicateHandle (parent, 1584 if (!DuplicateHandle (parent,
1585 (HANDLE) _get_osfhandle (out), 1585 (HANDLE) _get_osfhandle (out),
1586 parent, 1586 parent,
1587 &newstdout, 1587 &newstdout,
1588 0, 1588 0,
1589 TRUE, 1589 TRUE,
1590 DUPLICATE_SAME_ACCESS)) 1590 DUPLICATE_SAME_ACCESS))
1591 report_file_error ("Duplicating output handle for child", Qnil); 1591 report_file_error ("Duplicating output handle for child", Qnil);
1592 1592
1593 if (!DuplicateHandle (parent, 1593 if (!DuplicateHandle (parent,
1594 (HANDLE) _get_osfhandle (err), 1594 (HANDLE) _get_osfhandle (err),
1595 parent, 1595 parent,
1596 &newstderr, 1596 &newstderr,
1597 0, 1597 0,
1600 report_file_error ("Duplicating error handle for child", Qnil); 1600 report_file_error ("Duplicating error handle for child", Qnil);
1601 1601
1602 /* and store them as our std handles */ 1602 /* and store them as our std handles */
1603 if (!SetStdHandle (STD_INPUT_HANDLE, newstdin)) 1603 if (!SetStdHandle (STD_INPUT_HANDLE, newstdin))
1604 report_file_error ("Changing stdin handle", Qnil); 1604 report_file_error ("Changing stdin handle", Qnil);
1605 1605
1606 if (!SetStdHandle (STD_OUTPUT_HANDLE, newstdout)) 1606 if (!SetStdHandle (STD_OUTPUT_HANDLE, newstdout))
1607 report_file_error ("Changing stdout handle", Qnil); 1607 report_file_error ("Changing stdout handle", Qnil);
1608 1608
1609 if (!SetStdHandle (STD_ERROR_HANDLE, newstderr)) 1609 if (!SetStdHandle (STD_ERROR_HANDLE, newstderr))
1610 report_file_error ("Changing stderr handle", Qnil); 1610 report_file_error ("Changing stderr handle", Qnil);
1931 if (NILP (userp)) 1931 if (NILP (userp))
1932 return make_number (GetSystemDefaultLCID ()); 1932 return make_number (GetSystemDefaultLCID ());
1933 return make_number (GetUserDefaultLCID ()); 1933 return make_number (GetUserDefaultLCID ());
1934 } 1934 }
1935 1935
1936 1936
1937 DEFUN ("w32-set-current-locale", Fw32_set_current_locale, Sw32_set_current_locale, 1, 1, 0, 1937 DEFUN ("w32-set-current-locale", Fw32_set_current_locale, Sw32_set_current_locale, 1, 1, 0,
1938 doc: /* Make Windows locale LCID be the current locale setting for Emacs. 1938 doc: /* Make Windows locale LCID be the current locale setting for Emacs.
1939 If successful, the new locale id is returned, otherwise nil. */) 1939 If successful, the new locale id is returned, otherwise nil. */)
1940 (lcid) 1940 (lcid)
1941 Lisp_Object lcid; 1941 Lisp_Object lcid;
1988 () 1988 ()
1989 { 1989 {
1990 return make_number (GetConsoleCP ()); 1990 return make_number (GetConsoleCP ());
1991 } 1991 }
1992 1992
1993 1993
1994 DEFUN ("w32-set-console-codepage", Fw32_set_console_codepage, 1994 DEFUN ("w32-set-console-codepage", Fw32_set_console_codepage,
1995 Sw32_set_console_codepage, 1, 1, 0, 1995 Sw32_set_console_codepage, 1, 1, 0,
1996 doc: /* Make Windows codepage CP be the current codepage setting for Emacs. 1996 doc: /* Make Windows codepage CP be the current codepage setting for Emacs.
1997 The codepage setting affects keyboard input and display in tty mode. 1997 The codepage setting affects keyboard input and display in tty mode.
1998 If successful, the new CP is returned, otherwise nil. */) 1998 If successful, the new CP is returned, otherwise nil. */)
2017 () 2017 ()
2018 { 2018 {
2019 return make_number (GetConsoleOutputCP ()); 2019 return make_number (GetConsoleOutputCP ());
2020 } 2020 }
2021 2021
2022 2022
2023 DEFUN ("w32-set-console-output-codepage", Fw32_set_console_output_codepage, 2023 DEFUN ("w32-set-console-output-codepage", Fw32_set_console_output_codepage,
2024 Sw32_set_console_output_codepage, 1, 1, 0, 2024 Sw32_set_console_output_codepage, 1, 1, 0,
2025 doc: /* Make Windows codepage CP be the current codepage setting for Emacs. 2025 doc: /* Make Windows codepage CP be the current codepage setting for Emacs.
2026 The codepage setting affects keyboard input and display in tty mode. 2026 The codepage setting affects keyboard input and display in tty mode.
2027 If successful, the new CP is returned, otherwise nil. */) 2027 If successful, the new CP is returned, otherwise nil. */)
2097 2097
2098 return Fcons (make_number (kl & 0xffff), 2098 return Fcons (make_number (kl & 0xffff),
2099 make_number ((kl >> 16) & 0xffff)); 2099 make_number ((kl >> 16) & 0xffff));
2100 } 2100 }
2101 2101
2102 2102
2103 DEFUN ("w32-set-keyboard-layout", Fw32_set_keyboard_layout, 2103 DEFUN ("w32-set-keyboard-layout", Fw32_set_keyboard_layout,
2104 Sw32_set_keyboard_layout, 1, 1, 0, 2104 Sw32_set_keyboard_layout, 1, 1, 0,
2105 doc: /* Make LAYOUT be the current keyboard layout for Emacs. 2105 doc: /* Make LAYOUT be the current keyboard layout for Emacs.
2106 The keyboard layout setting affects interpretation of keyboard input. 2106 The keyboard layout setting affects interpretation of keyboard input.
2107 If successful, the new layout id is returned, otherwise nil. */) 2107 If successful, the new layout id is returned, otherwise nil. */)
2216 DEFVAR_LISP ("w32-downcase-file-names", &Vw32_downcase_file_names, 2216 DEFVAR_LISP ("w32-downcase-file-names", &Vw32_downcase_file_names,
2217 doc: /* Non-nil means convert all-upper case file names to lower case. 2217 doc: /* Non-nil means convert all-upper case file names to lower case.
2218 This applies when performing completions and file name expansion. 2218 This applies when performing completions and file name expansion.
2219 Note that the value of this setting also affects remote file names, 2219 Note that the value of this setting also affects remote file names,
2220 so you probably don't want to set to non-nil if you use case-sensitive 2220 so you probably don't want to set to non-nil if you use case-sensitive
2221 filesystems via ange-ftp. */); 2221 filesystems via ange-ftp. */);
2222 Vw32_downcase_file_names = Qnil; 2222 Vw32_downcase_file_names = Qnil;
2223 2223
2224 #if 0 2224 #if 0
2225 DEFVAR_LISP ("w32-generate-fake-inodes", &Vw32_generate_fake_inodes, 2225 DEFVAR_LISP ("w32-generate-fake-inodes", &Vw32_generate_fake_inodes,
2226 doc: /* Non-nil means attempt to fake realistic inode values. 2226 doc: /* Non-nil means attempt to fake realistic inode values.