comparison src/ntproc.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents 8626e4521993
children a86b2b5e0111
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
30 #include <io.h> 30 #include <io.h>
31 #include <fcntl.h> 31 #include <fcntl.h>
32 #include <signal.h> 32 #include <signal.h>
33 33
34 /* must include CRT headers *before* config.h */ 34 /* must include CRT headers *before* config.h */
35 /* ### I don't believe it - martin */ 35 /* #### I don't believe it - martin */
36 #include <config.h> 36 #include <config.h>
37 #undef signal 37 #undef signal
38 #undef wait 38 #undef wait
39 #undef spawnve 39 #undef spawnve
40 #undef select 40 #undef select
41 #undef kill 41 #undef kill
42 42
43 #include <windows.h> 43 #include <windows.h>
44 #include <sys/socket.h> 44 #include <sys/socket.h>
45 45 #ifdef HAVE_A_OUT_H
46 #include <a.out.h>
47 #endif
46 #include "lisp.h" 48 #include "lisp.h"
47 #include "sysproc.h" 49 #include "sysproc.h"
48 #include "nt.h" 50 #include "nt.h"
49 #include "ntheap.h" /* From 19.34.6 */ 51 #include "ntheap.h" /* From 19.34.6 */
50 #include "systime.h" 52 #include "systime.h"
51 #include "syssignal.h" 53 #include "syssignal.h"
54 #include "sysfile.h"
52 #include "syswait.h" 55 #include "syswait.h"
56 #include "buffer.h"
53 #include "process.h" 57 #include "process.h"
54 /*#include "w32term.h"*/ /* From 19.34.6: sync in ? --marcpa */ 58 /*#include "w32term.h"*/ /* From 19.34.6: sync in ? --marcpa */
55 59
56 /* #### I'm not going to play with shit. */ 60 /* #### I'm not going to play with shit. */
57 #pragma warning (disable:4013 4024 4090) 61 #pragma warning (disable:4013 4024 4090)
84 allows the possibility of hash collisions. */ 88 allows the possibility of hash collisions. */
85 Lisp_Object Vwin32_generate_fake_inodes; 89 Lisp_Object Vwin32_generate_fake_inodes;
86 90
87 Lisp_Object Qhigh, Qlow; 91 Lisp_Object Qhigh, Qlow;
88 92
93 extern Lisp_Object Vlisp_EXEC_SUFFIXES;
94
89 #ifndef DEBUG_XEMACS 95 #ifndef DEBUG_XEMACS
90 __inline 96 __inline
91 #endif 97 #endif
92 void _DebPrint (const char *fmt, ...) 98 void _DebPrint (const char *fmt, ...)
93 { 99 {
111 int child_proc_count = 0; 117 int child_proc_count = 0;
112 child_process child_procs[ MAX_CHILDREN ]; 118 child_process child_procs[ MAX_CHILDREN ];
113 child_process *dead_child = NULL; 119 child_process *dead_child = NULL;
114 120
115 DWORD WINAPI reader_thread (void *arg); 121 DWORD WINAPI reader_thread (void *arg);
122
123 /* Determine if running on Windows 9x and not NT */
124 static int
125 windows9x_p (void)
126 {
127 return GetVersion () & 0x80000000;
128 }
116 129
117 /* Find an unused process slot. */ 130 /* Find an unused process slot. */
118 child_process * 131 child_process *
119 new_child (void) 132 new_child (void)
120 { 133 {
221 if (CHILD_ACTIVE (cp) && pid == cp->pid) 234 if (CHILD_ACTIVE (cp) && pid == cp->pid)
222 return cp; 235 return cp;
223 return NULL; 236 return NULL;
224 } 237 }
225 238
239 /* Function to do blocking read of one byte, needed to implement
240 select. It is only allowed on sockets and pipes. */
241 static int
242 _sys_read_ahead (int fd)
243 {
244 child_process * cp;
245 int rc = 0;
246
247 if (fd < 0 || fd >= MAXDESC)
248 return STATUS_READ_ERROR;
249
250 cp = fd_info[fd].cp;
251
252 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
253 return STATUS_READ_ERROR;
254
255 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
256 || (fd_info[fd].flags & FILE_READ) == 0)
257 {
258 /* fd is not a pipe or socket */
259 abort ();
260 }
261
262 cp->status = STATUS_READ_IN_PROGRESS;
263
264 if (fd_info[fd].flags & FILE_PIPE)
265 {
266 rc = _read (fd, &cp->chr, sizeof (char));
267
268 /* Give subprocess time to buffer some more output for us before
269 reporting that input is available; we need this because Win95
270 connects DOS programs to pipes by making the pipe appear to be
271 the normal console stdout - as a result most DOS programs will
272 write to stdout without buffering, ie. one character at a
273 time. Even some Win32 programs do this - "dir" in a command
274 shell on NT is very slow if we don't do this. */
275 if (rc > 0)
276 {
277 int wait = XINT (Vwin32_pipe_read_delay);
278
279 if (wait > 0)
280 Sleep (wait);
281 else if (wait < 0)
282 while (++wait <= 0)
283 /* Yield remainder of our time slice, effectively giving a
284 temporary priority boost to the child process. */
285 Sleep (0);
286 }
287 }
288
289 if (rc == sizeof (char))
290 cp->status = STATUS_READ_SUCCEEDED;
291 else
292 cp->status = STATUS_READ_FAILED;
293
294 return cp->status;
295 }
226 296
227 /* Thread proc for child process and socket reader threads. Each thread 297 /* Thread proc for child process and socket reader threads. Each thread
228 is normally blocked until woken by select() to check for input by 298 is normally blocked until woken by select() to check for input by
229 reading one char. When the read completes, char_avail is signalled 299 reading one char. When the read completes, char_avail is signalled
230 to wake up the select emulator and the thread blocks itself again. */ 300 to wake up the select emulator and the thread blocks itself again. */
328 the new process should start in. This is set just before calling 398 the new process should start in. This is set just before calling
329 sys_spawnve, and is not generally valid at any other time. */ 399 sys_spawnve, and is not generally valid at any other time. */
330 static const char * process_dir; 400 static const char * process_dir;
331 401
332 static BOOL 402 static BOOL
333 create_child (char *exe, char *cmdline, char *env, 403 create_child (const char *exe, char *cmdline, char *env,
334 int * pPid, child_process *cp) 404 int * pPid, child_process *cp)
335 { 405 {
336 STARTUPINFO start; 406 STARTUPINFO start;
337 SECURITY_ATTRIBUTES sec_attrs; 407 SECURITY_ATTRIBUTES sec_attrs;
338 SECURITY_DESCRIPTOR sec_desc; 408 SECURITY_DESCRIPTOR sec_desc;
380 CloseHandle (cp->procinfo.hThread); 450 CloseHandle (cp->procinfo.hThread);
381 CloseHandle (cp->procinfo.hProcess); 451 CloseHandle (cp->procinfo.hProcess);
382 cp->procinfo.hThread=NULL; 452 cp->procinfo.hThread=NULL;
383 cp->procinfo.hProcess=NULL; 453 cp->procinfo.hProcess=NULL;
384 454
385 /* Hack for Windows 95, which assigns large (ie negative) pids */
386 if (cp->pid < 0)
387 cp->pid = -cp->pid;
388
389 /* pid must fit in a Lisp_Int */ 455 /* pid must fit in a Lisp_Int */
390 #ifdef USE_UNION_TYPE 456
391 cp->pid = (cp->pid & ((1U << VALBITS) - 1));
392 #else
393 cp->pid = (cp->pid & VALMASK);
394 #endif
395 457
396 *pPid = cp->pid; 458 *pPid = cp->pid;
397 459
398 return TRUE; 460 return TRUE;
399 461
400 EH_Fail: 462 EH_Fail:
401 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError());); 463 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError()););
402 return FALSE; 464 return FALSE;
403 } 465 }
404 466
467 #ifndef __MINGW32__
468 /* Return pointer to section header for section containing the given
469 relative virtual address. */
470 static IMAGE_SECTION_HEADER *
471 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header)
472 {
473 PIMAGE_SECTION_HEADER section;
474 int i;
475
476 section = IMAGE_FIRST_SECTION (nt_header);
477
478 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
479 {
480 if (rva >= section->VirtualAddress
481 && rva < section->VirtualAddress + section->SizeOfRawData)
482 return section;
483 section++;
484 }
485 return NULL;
486 }
487 #endif
488
405 void 489 void
406 win32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app) 490 win32_executable_type (const char * filename, int * is_dos_app, int * is_cygnus_app)
407 { 491 {
408 file_data executable; 492 file_data executable;
409 char * p; 493 char * p;
410 494
411 /* Default values in case we can't tell for sure. */ 495 /* Default values in case we can't tell for sure. */
428 COMSPEC to determine what executable to actually invoke. 512 COMSPEC to determine what executable to actually invoke.
429 Therefore, we have to do the same here as well. */ 513 Therefore, we have to do the same here as well. */
430 /* Actually, I think it uses the program association for that 514 /* Actually, I think it uses the program association for that
431 extension, which is defined in the registry. */ 515 extension, which is defined in the registry. */
432 p = egetenv ("COMSPEC"); 516 p = egetenv ("COMSPEC");
433 if (p) 517 if (p)
434 win32_executable_type (p, is_dos_app, is_cygnus_app); 518 win32_executable_type (p, is_dos_app, is_cygnus_app);
435 } 519 }
436 else 520 else
437 { 521 {
438 /* Look for DOS .exe signature - if found, we must also check that 522 /* Look for DOS .exe signature - if found, we must also check that
439 it isn't really a 16- or 32-bit Windows exe, since both formats 523 it isn't really a 16- or 32-bit Windows exe, since both formats
440 start with a DOS program stub. Note that 16-bit Windows 524 start with a DOS program stub. Note that 16-bit Windows
441 executables use the OS/2 1.x format. */ 525 executables use the OS/2 1.x format. */
442 526
443 IMAGE_DOS_HEADER * dos_header; 527 #ifdef __MINGW32__
444 IMAGE_NT_HEADERS * nt_header; 528 /* mingw32 doesn't have enough headers to detect cygwin
445 529 apps, just do what we can. */
446 dos_header = (PIMAGE_DOS_HEADER) executable.file_base; 530 FILHDR * exe_header;
447 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) 531
448 goto unwind; 532 exe_header = (FILHDR*) executable.file_base;
449 533 if (exe_header->e_magic != DOSMAGIC)
450 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew); 534 goto unwind;
451 535
452 if ((char *) nt_header > (char *) dos_header + executable.size) 536 if ((char *) exe_header->e_lfanew > (char *) executable.size)
453 {
454 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
455 *is_dos_app = TRUE;
456 }
457 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
458 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
459 {
460 *is_dos_app = TRUE;
461 }
462 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
463 {
464 /* Look for cygwin.dll in DLL import list. */
465 IMAGE_DATA_DIRECTORY import_dir =
466 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
467 IMAGE_IMPORT_DESCRIPTOR * imports;
468 IMAGE_SECTION_HEADER * section;
469
470 section = rva_to_section (import_dir.VirtualAddress, nt_header);
471 imports = RVA_TO_PTR (import_dir.VirtualAddress, section, executable);
472
473 for ( ; imports->Name; imports++)
474 { 537 {
475 char * dllname = RVA_TO_PTR (imports->Name, section, executable); 538 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
476 539 *is_dos_app = TRUE;
477 if (strcmp (dllname, "cygwin.dll") == 0) 540 }
541 else if (exe_header->nt_signature != NT_SIGNATURE)
478 { 542 {
479 *is_cygnus_app = TRUE; 543 *is_dos_app = TRUE;
480 break; 544 }
545 #else
546 IMAGE_DOS_HEADER * dos_header;
547 IMAGE_NT_HEADERS * nt_header;
548
549 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
550 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
551 goto unwind;
552
553 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
554
555 if ((char *) nt_header > (char *) dos_header + executable.size)
556 {
557 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
558 *is_dos_app = TRUE;
559 }
560 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
561 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
562 {
563 *is_dos_app = TRUE;
564 }
565 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
566 {
567 /* Look for cygwin.dll in DLL import list. */
568 IMAGE_DATA_DIRECTORY import_dir =
569 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
570 IMAGE_IMPORT_DESCRIPTOR * imports;
571 IMAGE_SECTION_HEADER * section;
572
573 section = rva_to_section (import_dir.VirtualAddress, nt_header);
574 imports = RVA_TO_PTR (import_dir.VirtualAddress, section, executable);
575
576 for ( ; imports->Name; imports++)
577 {
578 char * dllname = RVA_TO_PTR (imports->Name, section, executable);
579
580 if (strcmp (dllname, "cygwin.dll") == 0)
581 {
582 *is_cygnus_app = TRUE;
583 break;
584 }
481 } 585 }
482 } 586 }
587 #endif
483 } 588 }
484 } 589
485 590 unwind:
486 unwind: 591 close_file_data (&executable);
487 close_file_data (&executable);
488 } 592 }
489 593
490 int 594 int
491 compare_env (const char **strp1, const char **strp2) 595 compare_env (const void *strp1, const void *strp2)
492 { 596 {
493 const char *str1 = *strp1, *str2 = *strp2; 597 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2;
494 598
495 while (*str1 && *str2 && *str1 != '=' && *str2 != '=') 599 while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
496 { 600 {
497 if ((*str1) > (*str2)) 601 if ((*str1) > (*str2))
498 return 1; 602 return 1;
532 } 636 }
533 637
534 /* When a new child process is created we need to register it in our list, 638 /* When a new child process is created we need to register it in our list,
535 so intercept spawn requests. */ 639 so intercept spawn requests. */
536 int 640 int
537 sys_spawnve (int mode, CONST char *cmdname, 641 sys_spawnve (int mode, const char *cmdname,
538 CONST char * CONST *argv, CONST char *CONST *envp) 642 const char * const *argv, const char *const *envp)
539 { 643 {
540 Lisp_Object program, full; 644 Lisp_Object program, full;
541 char *cmdline, *env, *parg, **targ; 645 char *cmdline, *env, *parg, **targ;
542 int arglen, numenv; 646 int arglen, numenv;
543 int pid; 647 int pid;
544 child_process *cp; 648 child_process *cp;
545 int is_dos_app, is_cygnus_app; 649 int is_dos_app, is_cygnus_app;
546 int do_quoting = 0; 650 int do_quoting = 0;
547 char escape_char; 651 char escape_char = 0;
548 /* We pass our process ID to our children by setting up an environment 652 /* We pass our process ID to our children by setting up an environment
549 variable in their environment. */ 653 variable in their environment. */
550 char ppid_env_var_buffer[64]; 654 char ppid_env_var_buffer[64];
551 char *extra_env[] = {ppid_env_var_buffer, NULL}; 655 char *extra_env[] = {ppid_env_var_buffer, NULL};
552 struct gcpro gcpro1; 656 struct gcpro gcpro1;
562 program = make_string (cmdname, strlen (cmdname)); 666 program = make_string (cmdname, strlen (cmdname));
563 GCPRO1 (program); 667 GCPRO1 (program);
564 if (NILP (Ffile_executable_p (program))) 668 if (NILP (Ffile_executable_p (program)))
565 { 669 {
566 full = Qnil; 670 full = Qnil;
567 locate_file (Vexec_path, program, EXEC_SUFFIXES, &full, 1); 671 locate_file (Vexec_path, program, Vlisp_EXEC_SUFFIXES, &full, 1);
568 if (NILP (full)) 672 if (NILP (full))
569 { 673 {
570 UNGCPRO; 674 UNGCPRO;
571 errno = EINVAL; 675 errno = EINVAL;
572 return -1; 676 return -1;
573 } 677 }
574 cmdname = XSTRING_DATA (full); 678 TO_EXTERNAL_FORMAT (LISP_STRING, full,
575 /* #### KLUDGE */ 679 C_STRING_ALLOCA, cmdname,
576 *(char**)(argv[0]) = cmdname; 680 Qfile_name);
681 }
682 else
683 {
684 (char*)cmdname = alloca (strlen (argv[0]) + 1);
685 strcpy ((char*)cmdname, argv[0]);
577 } 686 }
578 UNGCPRO; 687 UNGCPRO;
579 688
580 /* make sure argv[0] and cmdname are both in DOS format */ 689 /* make sure argv[0] and cmdname are both in DOS format */
581 strcpy (cmdname = alloca (strlen (cmdname) + 1), argv[0]); 690 unixtodos_filename ((char*)cmdname);
582 unixtodos_filename (cmdname);
583 /* #### KLUDGE */ 691 /* #### KLUDGE */
584 *(char**)(argv[0]) = cmdname; 692 ((const char**)argv)[0] = cmdname;
585 693
586 /* Determine whether program is a 16-bit DOS executable, or a Win32 694 /* Determine whether program is a 16-bit DOS executable, or a Win32
587 executable that is implicitly linked to the Cygnus dll (implying it 695 executable that is implicitly linked to the Cygnus dll (implying it
588 was compiled with the Cygnus GNU toolchain and hence relies on 696 was compiled with the Cygnus GNU toolchain and hence relies on
589 cygwin.dll to parse the command line - we use this to decide how to 697 cygwin.dll to parse the command line - we use this to decide how to
595 while leaving the real app name as argv[0]. */ 703 while leaving the real app name as argv[0]. */
596 if (is_dos_app) 704 if (is_dos_app)
597 { 705 {
598 cmdname = alloca (MAXPATHLEN); 706 cmdname = alloca (MAXPATHLEN);
599 if (egetenv ("CMDPROXY")) 707 if (egetenv ("CMDPROXY"))
600 strcpy (cmdname, egetenv ("CMDPROXY")); 708 strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
601 else 709 else
602 { 710 {
603 strcpy (cmdname, XSTRING_DATA (Vinvocation_directory)); 711 strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
604 strcat (cmdname, "cmdproxy.exe"); 712 strcat ((char*)cmdname, "cmdproxy.exe");
605 } 713 }
606 unixtodos_filename (cmdname); 714 unixtodos_filename ((char*)cmdname);
607 } 715 }
608 716
609 /* we have to do some conjuring here to put argv and envp into the 717 /* we have to do some conjuring here to put argv and envp into the
610 form CreateProcess wants... argv needs to be a space separated/null 718 form CreateProcess wants... argv needs to be a space separated/null
611 terminated list of parameters, and envp is a null 719 terminated list of parameters, and envp is a null
647 escape_char = is_cygnus_app ? '"' : '\\'; 755 escape_char = is_cygnus_app ? '"' : '\\';
648 } 756 }
649 757
650 /* do argv... */ 758 /* do argv... */
651 arglen = 0; 759 arglen = 0;
652 targ = argv; 760 targ = (char**)argv;
653 while (*targ) 761 while (*targ)
654 { 762 {
655 char * p = *targ; 763 char * p = *targ;
656 int need_quotes = 0; 764 int need_quotes = 0;
657 int escape_char_run = 0; 765 int escape_char_run = 0;
693 arglen += escape_char_run; 801 arglen += escape_char_run;
694 } 802 }
695 arglen += strlen (*targ++) + 1; 803 arglen += strlen (*targ++) + 1;
696 } 804 }
697 cmdline = alloca (arglen); 805 cmdline = alloca (arglen);
698 targ = argv; 806 targ = (char**)argv;
699 parg = cmdline; 807 parg = cmdline;
700 while (*targ) 808 while (*targ)
701 { 809 {
702 char * p = *targ; 810 char * p = *targ;
703 int need_quotes = 0; 811 int need_quotes = 0;
774 } 882 }
775 *--parg = '\0'; 883 *--parg = '\0';
776 884
777 /* and envp... */ 885 /* and envp... */
778 arglen = 1; 886 arglen = 1;
779 targ = envp; 887 targ = (char**)envp;
780 numenv = 1; /* for end null */ 888 numenv = 1; /* for end null */
781 while (*targ) 889 while (*targ)
782 { 890 {
783 arglen += strlen (*targ++) + 1; 891 arglen += strlen (*targ++) + 1;
784 numenv++; 892 numenv++;
789 arglen += strlen (ppid_env_var_buffer) + 1; 897 arglen += strlen (ppid_env_var_buffer) + 1;
790 numenv++; 898 numenv++;
791 899
792 /* merge env passed in and extra env into one, and sort it. */ 900 /* merge env passed in and extra env into one, and sort it. */
793 targ = (char **) alloca (numenv * sizeof (char *)); 901 targ = (char **) alloca (numenv * sizeof (char *));
794 merge_and_sort_env (envp, extra_env, targ); 902 merge_and_sort_env ((char**)envp, extra_env, targ);
795 903
796 /* concatenate env entries. */ 904 /* concatenate env entries. */
797 env = alloca (arglen); 905 env = alloca (arglen);
798 parg = env; 906 parg = env;
799 while (*targ) 907 while (*targ)
836 { 944 {
837 char window_class[32]; 945 char window_class[32];
838 946
839 GetClassName (hwnd, window_class, sizeof (window_class)); 947 GetClassName (hwnd, window_class, sizeof (window_class));
840 if (strcmp (window_class, 948 if (strcmp (window_class,
841 (os_subtype == OS_WIN95) 949 windows9x_p()
842 ? "tty" 950 ? "tty"
843 : "ConsoleWindowClass") == 0) 951 : "ConsoleWindowClass") == 0)
844 { 952 {
845 cp->hwnd = hwnd; 953 cp->hwnd = hwnd;
846 return FALSE; 954 return FALSE;
880 { 988 {
881 proc_hand = cp->procinfo.hProcess; 989 proc_hand = cp->procinfo.hProcess;
882 pid = cp->procinfo.dwProcessId; 990 pid = cp->procinfo.dwProcessId;
883 991
884 /* Try to locate console window for process. */ 992 /* Try to locate console window for process. */
885 EnumWindows (find_child_console, (LPARAM) cp); 993 EnumWindows ((WNDENUMPROC)find_child_console, (LPARAM) cp);
886 } 994 }
887 995
888 if (sig == SIGINT) 996 if (sig == SIGINT)
889 { 997 {
890 if (NILP (Vwin32_start_process_share_console) && cp && cp->hwnd) 998 if (NILP (Vwin32_start_process_share_console) && cp && cp->hwnd)
929 else 1037 else
930 { 1038 {
931 if (NILP (Vwin32_start_process_share_console) && cp && cp->hwnd) 1039 if (NILP (Vwin32_start_process_share_console) && cp && cp->hwnd)
932 { 1040 {
933 #if 1 1041 #if 1
934 if (os_subtype == OS_WIN95) 1042 if (windows9x_p())
935 { 1043 {
936 /* 1044 /*
937 Another possibility is to try terminating the VDM out-right by 1045 Another possibility is to try terminating the VDM out-right by
938 calling the Shell VxD (id 0x17) V86 interface, function #4 1046 calling the Shell VxD (id 0x17) V86 interface, function #4
939 "SHELL_Destroy_VM", ie. 1047 "SHELL_Destroy_VM", ie.
990 return rc; 1098 return rc;
991 } 1099 }
992 1100
993 #if 0 1101 #if 0
994 /* Sync with FSF Emacs 19.34.6 note: ifdef'ed out in XEmacs */ 1102 /* Sync with FSF Emacs 19.34.6 note: ifdef'ed out in XEmacs */
995 extern int report_file_error (CONST char *, Lisp_Object); 1103 extern int report_file_error (const char *, Lisp_Object);
996 #endif 1104 #endif
997 /* The following two routines are used to manipulate stdin, stdout, and 1105 /* The following two routines are used to manipulate stdin, stdout, and
998 stderr of our child processes. 1106 stderr of our child processes.
999 1107
1000 Assuming that in, out, and err are *not* inheritable, we make them 1108 Assuming that in, out, and err are *not* inheritable, we make them
1318 if (!SetThreadLocale (XINT (lcid))) 1426 if (!SetThreadLocale (XINT (lcid)))
1319 return Qnil; 1427 return Qnil;
1320 1428
1321 /* Sync with FSF Emacs 19.34.6 note: dwWinThreadId declared in 1429 /* Sync with FSF Emacs 19.34.6 note: dwWinThreadId declared in
1322 w32term.h and defined in w32fns.c, both of which are not in current 1430 w32term.h and defined in w32fns.c, both of which are not in current
1323 XEmacs. ### Check what we lose by ifdef'ing out these. --marcpa */ 1431 XEmacs. #### Check what we lose by ifdef'ing out these. --marcpa */
1324 #if 0 1432 #if 0
1325 /* Need to set input thread locale if present. */ 1433 /* Need to set input thread locale if present. */
1326 if (dwWinThreadId) 1434 if (dwWinThreadId)
1327 /* Reply is not needed. */ 1435 /* Reply is not needed. */
1328 PostThreadMessage (dwWinThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0); 1436 PostThreadMessage (dwWinThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
1333 1441
1334 1442
1335 void 1443 void
1336 syms_of_ntproc () 1444 syms_of_ntproc ()
1337 { 1445 {
1338 Qhigh = intern ("high");
1339 Qlow = intern ("low");
1340
1341 DEFSUBR (Fwin32_short_file_name); 1446 DEFSUBR (Fwin32_short_file_name);
1342 DEFSUBR (Fwin32_long_file_name); 1447 DEFSUBR (Fwin32_long_file_name);
1343 DEFSUBR (Fwin32_set_process_priority); 1448 DEFSUBR (Fwin32_set_process_priority);
1344 DEFSUBR (Fwin32_get_locale_info); 1449 DEFSUBR (Fwin32_get_locale_info);
1345 DEFSUBR (Fwin32_get_current_locale_id); 1450 DEFSUBR (Fwin32_get_current_locale_id);
1346 DEFSUBR (Fwin32_get_default_locale_id); 1451 DEFSUBR (Fwin32_get_default_locale_id);
1347 DEFSUBR (Fwin32_get_valid_locale_ids); 1452 DEFSUBR (Fwin32_get_valid_locale_ids);
1348 DEFSUBR (Fwin32_set_current_locale); 1453 DEFSUBR (Fwin32_set_current_locale);
1454 }
1455
1456
1457 void
1458 vars_of_ntproc (void)
1459 {
1460 defsymbol (&Qhigh, "high");
1461 defsymbol (&Qlow, "low");
1349 1462
1350 DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /* 1463 DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /*
1351 Non-nil enables quoting of process arguments to ensure correct parsing. 1464 Non-nil enables quoting of process arguments to ensure correct parsing.
1352 Because Windows does not directly pass argv arrays to child processes, 1465 Because Windows does not directly pass argv arrays to child processes,
1353 programs have to reconstruct the argv array by parsing the command 1466 programs have to reconstruct the argv array by parsing the command
1374 allowing only only DOS subprocess to run at a time (whether started directly 1487 allowing only only DOS subprocess to run at a time (whether started directly
1375 or indirectly by Emacs), and preventing Emacs from cleanly terminating the 1488 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1376 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't 1489 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1377 otherwise respond to interrupts from Emacs. 1490 otherwise respond to interrupts from Emacs.
1378 */ ); 1491 */ );
1379 Vwin32_start_process_share_console = Qnil; 1492 Vwin32_start_process_share_console = Qt;
1380 1493
1381 DEFVAR_LISP ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /* 1494 DEFVAR_LISP ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /*
1382 Forced delay before reading subprocess output. 1495 Forced delay before reading subprocess output.
1383 This is done to improve the buffering of subprocess output, by 1496 This is done to improve the buffering of subprocess output, by
1384 avoiding the inefficiency of frequently reading small amounts of data. 1497 avoiding the inefficiency of frequently reading small amounts of data.
1399 the truename of a file can be slow. 1512 the truename of a file can be slow.
1400 */ ); 1513 */ );
1401 Vwin32_generate_fake_inodes = Qnil; 1514 Vwin32_generate_fake_inodes = Qnil;
1402 #endif 1515 #endif
1403 } 1516 }
1517
1404 /* end of ntproc.c */ 1518 /* end of ntproc.c */