Mercurial > hg > xemacs-beta
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 */ |