aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32proc.c
diff options
context:
space:
mode:
authorGeoff Voelker1997-09-03 01:05:33 +0000
committerGeoff Voelker1997-09-03 01:05:33 +0000
commitb2fc9f3d6b10a339618ce7adfa1ea3557e7a820d (patch)
tree7c078f35889a6b084d05c4db559e1247a9619510 /src/w32proc.c
parent014510b01f9351d93187b339a156133614cd49a0 (diff)
downloademacs-b2fc9f3d6b10a339618ce7adfa1ea3557e7a820d.tar.gz
emacs-b2fc9f3d6b10a339618ce7adfa1ea3557e7a820d.zip
Include w32heap.h.
(Vw32_start_process_share_console, Vw32_generate_fake_inodes, Vw32_get_true_file_attributes, Qhigh, Qlow, process_dir): New variables. (find_child_console, set_process_dir, Fw32_short_file_name, Fw32_long_file_name, Fw32_set_process_priority, Fw32_get_locale_info, Fw32_get_current_locale_id, Fw32_get_default_local_id, Fw32_set_current_locale): New functions. (CORRECT_DIR_SEPS): New macro. (create_child): Create a new console if subprocs don't share parent's. (reap_subprocess): Don't check for dos subprocesses. Add debug support. (sys_wait): Ignore socket child_procs. Check for quit while waiting. (w32_executable_type): Renamed from w32_is_dos_binary. Check for dos and Cygnus executables. (sys_spawnve): Always use cmdproxy if spawning a dos app. Use quotes to quote arguments for Cygnus apps, backslashes otherwise. Handle escape characters. Escape quotes at start and end, too. (sys_select): Treat null timeout as infinite. Add handles of child processes. Loop over handles round robin to ensure fairness. (sys_kill): Send ctrl-break and ctrl-c keystrokes to subprocesses on SIGINT if not sharing consoles, otherwise generate ctrl-break event. On other termination signals, send WM_QUIT message to Win95 apps and WM_CLOSE to NT apps. (syms_of_ntproc): Intern new symbols. defsubr new functions. DEFVAR new variables.
Diffstat (limited to 'src/w32proc.c')
-rw-r--r--src/w32proc.c899
1 files changed, 692 insertions, 207 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index fec9a9ddeee..35f0ff1d17d 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA.
41 41
42#include "lisp.h" 42#include "lisp.h"
43#include "w32.h" 43#include "w32.h"
44#include "w32heap.h"
44#include "systime.h" 45#include "systime.h"
45#include "syswait.h" 46#include "syswait.h"
46#include "process.h" 47#include "process.h"
@@ -55,6 +56,12 @@ Lisp_Object Vw32_quote_process_args;
55 hidden. The default is nil. */ 56 hidden. The default is nil. */
56Lisp_Object Vw32_start_process_show_window; 57Lisp_Object Vw32_start_process_show_window;
57 58
59/* Control whether create_child causes the process to inherit Emacs'
60 console window, or be given a new one of its own. The default is
61 nil, to allow multiple DOS programs to run on Win95. Having separate
62 consoles also allows Emacs to cleanly terminate process groups. */
63Lisp_Object Vw32_start_process_share_console;
64
58/* Time to sleep before reading from a subprocess output pipe - this 65/* Time to sleep before reading from a subprocess output pipe - this
59 avoids the inefficiency of frequently reading small amounts of data. 66 avoids the inefficiency of frequently reading small amounts of data.
60 This is primarily necessary for handling DOS processes on Windows 95, 67 This is primarily necessary for handling DOS processes on Windows 95,
@@ -65,8 +72,18 @@ Lisp_Object Vw32_pipe_read_delay;
65 nil means no, t means yes. */ 72 nil means no, t means yes. */
66Lisp_Object Vw32_downcase_file_names; 73Lisp_Object Vw32_downcase_file_names;
67 74
68/* Keep track of whether we have already started a DOS program. */ 75/* Control whether stat() attempts to generate fake but hopefully
69BOOL dos_process_running; 76 "accurate" inode values, by hashing the absolute truenames of files.
77 This should detect aliasing between long and short names, but still
78 allows the possibility of hash collisions. */
79Lisp_Object Vw32_generate_fake_inodes;
80
81/* Control whether stat() attempts to determine file type and link count
82 exactly, at the expense of slower operation. Since true hard links
83 are supported on NTFS volumes, this is only relevant on NT. */
84Lisp_Object Vw32_get_true_file_attributes;
85
86Lisp_Object Qhigh, Qlow;
70 87
71#ifndef SYS_SIGLIST_DECLARED 88#ifndef SYS_SIGLIST_DECLARED
72extern char *sys_siglist[]; 89extern char *sys_siglist[];
@@ -237,8 +254,8 @@ reader_thread (void *arg)
237 cp = (child_process *)arg; 254 cp = (child_process *)arg;
238 255
239 /* We have to wait for the go-ahead before we can start */ 256 /* We have to wait for the go-ahead before we can start */
240 if (cp == NULL || 257 if (cp == NULL
241 WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) 258 || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
242 return 1; 259 return 1;
243 260
244 for (;;) 261 for (;;)
@@ -274,6 +291,11 @@ reader_thread (void *arg)
274 return 0; 291 return 0;
275} 292}
276 293
294/* To avoid Emacs changing directory, we just record here the directory
295 the new process should start in. This is set just before calling
296 sys_spawnve, and is not generally valid at any other time. */
297static char * process_dir;
298
277static BOOL 299static BOOL
278create_child (char *exe, char *cmdline, char *env, 300create_child (char *exe, char *cmdline, char *env,
279 int * pPid, child_process *cp) 301 int * pPid, child_process *cp)
@@ -281,6 +303,7 @@ create_child (char *exe, char *cmdline, char *env,
281 STARTUPINFO start; 303 STARTUPINFO start;
282 SECURITY_ATTRIBUTES sec_attrs; 304 SECURITY_ATTRIBUTES sec_attrs;
283 SECURITY_DESCRIPTOR sec_desc; 305 SECURITY_DESCRIPTOR sec_desc;
306 char dir[ MAXPATHLEN ];
284 307
285 if (cp == NULL) abort (); 308 if (cp == NULL) abort ();
286 309
@@ -308,9 +331,14 @@ create_child (char *exe, char *cmdline, char *env,
308 sec_attrs.lpSecurityDescriptor = &sec_desc; 331 sec_attrs.lpSecurityDescriptor = &sec_desc;
309 sec_attrs.bInheritHandle = FALSE; 332 sec_attrs.bInheritHandle = FALSE;
310 333
334 strcpy (dir, process_dir);
335 unixtodos_filename (dir);
336
311 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, 337 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
312 CREATE_NEW_PROCESS_GROUP, 338 (!NILP (Vw32_start_process_share_console)
313 env, NULL, 339 ? CREATE_NEW_PROCESS_GROUP
340 : CREATE_NEW_CONSOLE),
341 env, dir,
314 &start, &cp->procinfo)) 342 &start, &cp->procinfo))
315 goto EH_Fail; 343 goto EH_Fail;
316 344
@@ -323,11 +351,10 @@ create_child (char *exe, char *cmdline, char *env,
323 /* pid must fit in a Lisp_Int */ 351 /* pid must fit in a Lisp_Int */
324 cp->pid = (cp->pid & VALMASK); 352 cp->pid = (cp->pid & VALMASK);
325 353
326
327 *pPid = cp->pid; 354 *pPid = cp->pid;
328 355
329 return TRUE; 356 return TRUE;
330 357
331 EH_Fail: 358 EH_Fail:
332 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError());); 359 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError()););
333 return FALSE; 360 return FALSE;
@@ -380,18 +407,15 @@ reap_subprocess (child_process *cp)
380 if (cp->procinfo.hProcess) 407 if (cp->procinfo.hProcess)
381 { 408 {
382 /* Reap the process */ 409 /* Reap the process */
383 if (WaitForSingleObject (cp->procinfo.hProcess, INFINITE) != WAIT_OBJECT_0) 410#ifdef FULL_DEBUG
384 DebPrint (("reap_subprocess.WaitForSingleObject (process) failed " 411 /* Process should have already died before we are called. */
385 "with %lu for fd %ld\n", GetLastError (), cp->fd)); 412 if (WaitForSingleObject (cp->procinfo.hProcess, 0) != WAIT_OBJECT_0)
413 DebPrint (("reap_subprocess: child fpr fd %d has not died yet!", cp->fd));
414#endif
386 CloseHandle (cp->procinfo.hProcess); 415 CloseHandle (cp->procinfo.hProcess);
387 cp->procinfo.hProcess = NULL; 416 cp->procinfo.hProcess = NULL;
388 CloseHandle (cp->procinfo.hThread); 417 CloseHandle (cp->procinfo.hThread);
389 cp->procinfo.hThread = NULL; 418 cp->procinfo.hThread = NULL;
390
391 /* If this was a DOS process, indicate that it is now safe to
392 start a new one. */
393 if (cp->is_dos_process)
394 dos_process_running = FALSE;
395 } 419 }
396 420
397 /* For asynchronous children, the child_proc resources will be freed 421 /* For asynchronous children, the child_proc resources will be freed
@@ -423,6 +447,8 @@ sys_wait (int *status)
423 cps[nh] = dead_child; 447 cps[nh] = dead_child;
424 if (!wait_hnd[nh]) abort (); 448 if (!wait_hnd[nh]) abort ();
425 nh++; 449 nh++;
450 active = 0;
451 goto get_result;
426 } 452 }
427 else 453 else
428 { 454 {
@@ -432,7 +458,6 @@ sys_wait (int *status)
432 { 458 {
433 wait_hnd[nh] = cp->procinfo.hProcess; 459 wait_hnd[nh] = cp->procinfo.hProcess;
434 cps[nh] = cp; 460 cps[nh] = cp;
435 if (!wait_hnd[nh]) abort ();
436 nh++; 461 nh++;
437 } 462 }
438 } 463 }
@@ -443,30 +468,33 @@ sys_wait (int *status)
443 errno = ECHILD; 468 errno = ECHILD;
444 return -1; 469 return -1;
445 } 470 }
446 471
447 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, INFINITE); 472 do
473 {
474 /* Check for quit about once a second. */
475 QUIT;
476 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000);
477 } while (active == WAIT_TIMEOUT);
478
448 if (active == WAIT_FAILED) 479 if (active == WAIT_FAILED)
449 { 480 {
450 errno = EBADF; 481 errno = EBADF;
451 return -1; 482 return -1;
452 } 483 }
453 else if (active == WAIT_TIMEOUT) 484 else if (active >= WAIT_OBJECT_0
454 { 485 && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
455 /* Should never happen */
456 errno = EINVAL;
457 return -1;
458 }
459 else if (active >= WAIT_OBJECT_0 &&
460 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
461 { 486 {
462 active -= WAIT_OBJECT_0; 487 active -= WAIT_OBJECT_0;
463 } 488 }
464 else if (active >= WAIT_ABANDONED_0 && 489 else if (active >= WAIT_ABANDONED_0
465 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS) 490 && active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
466 { 491 {
467 active -= WAIT_ABANDONED_0; 492 active -= WAIT_ABANDONED_0;
468 } 493 }
469 494 else
495 abort ();
496
497get_result:
470 if (!GetExitCodeProcess (wait_hnd[active], &retval)) 498 if (!GetExitCodeProcess (wait_hnd[active], &retval))
471 { 499 {
472 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n", 500 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
@@ -525,56 +553,95 @@ sys_wait (int *status)
525 553
526 reap_subprocess (cp); 554 reap_subprocess (cp);
527 } 555 }
556
557 reap_subprocess (cp);
528 558
529 return pid; 559 return pid;
530} 560}
531 561
532int 562void
533w32_is_dos_binary (char * filename) 563w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app)
534{ 564{
535 IMAGE_DOS_HEADER dos_header; 565 file_data executable;
536 DWORD signature; 566 char * p;
537 int fd; 567
538 int is_dos_binary = FALSE; 568 /* Default values in case we can't tell for sure. */
569 *is_dos_app = FALSE;
570 *is_cygnus_app = FALSE;
571
572 if (!open_input_file (&executable, filename))
573 return;
539 574
540 fd = open (filename, O_RDONLY | O_BINARY, 0); 575 p = strrchr (filename, '.');
541 if (fd >= 0) 576
577 /* We can only identify DOS .com programs from the extension. */
578 if (p && stricmp (p, ".com") == 0)
579 *is_dos_app = TRUE;
580 else if (p && (stricmp (p, ".bat") == 0
581 || stricmp (p, ".cmd") == 0))
582 {
583 /* A DOS shell script - it appears that CreateProcess is happy to
584 accept this (somewhat surprisingly); presumably it looks at
585 COMSPEC to determine what executable to actually invoke.
586 Therefore, we have to do the same here as well. */
587 /* Actually, I think it uses the program association for that
588 extension, which is defined in the registry. */
589 p = egetenv ("COMSPEC");
590 if (p)
591 w32_executable_type (p, is_dos_app, is_cygnus_app);
592 }
593 else
542 { 594 {
543 char * p = strrchr (filename, '.'); 595 /* Look for DOS .exe signature - if found, we must also check that
596 it isn't really a 16- or 32-bit Windows exe, since both formats
597 start with a DOS program stub. Note that 16-bit Windows
598 executables use the OS/2 1.x format. */
544 599
545 /* We can only identify DOS .com programs from the extension. */ 600 IMAGE_DOS_HEADER * dos_header;
546 if (p && stricmp (p, ".com") == 0) 601 IMAGE_NT_HEADERS * nt_header;
547 is_dos_binary = TRUE; 602
548 else if (p && stricmp (p, ".bat") == 0) 603 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
549 { 604 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
550 /* A DOS shell script - it appears that CreateProcess is happy 605 goto unwind;
551 to accept this (somewhat surprisingly); presumably it looks 606
552 at COMSPEC to determine what executable to actually invoke. 607 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
553 Therefore, we have to do the same here as well. */ 608
554 p = getenv ("COMSPEC"); 609 if (nt_header > dos_header + executable.size)
555 if (p)
556 is_dos_binary = w32_is_dos_binary (p);
557 }
558 else
559 { 610 {
560 /* Look for DOS .exe signature - if found, we must also check 611 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
561 that it isn't really a 16- or 32-bit Windows exe, since 612 *is_dos_app = TRUE;
562 both formats start with a DOS program stub. Note that 613 }
563 16-bit Windows executables use the OS/2 1.x format. */ 614 else if (nt_header->Signature != IMAGE_NT_SIGNATURE
564 if (read (fd, &dos_header, sizeof (dos_header)) == sizeof (dos_header) 615 && LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
565 && dos_header.e_magic == IMAGE_DOS_SIGNATURE 616 {
566 && lseek (fd, dos_header.e_lfanew, SEEK_SET) != -1) 617 *is_dos_app = TRUE;
567 { 618 }
568 if (read (fd, &signature, sizeof (signature)) != sizeof (signature) 619 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
569 || (signature != IMAGE_NT_SIGNATURE && 620 {
570 LOWORD (signature) != IMAGE_OS2_SIGNATURE)) 621 /* Look for cygwin.dll in DLL import list. */
571 is_dos_binary = TRUE; 622 IMAGE_DATA_DIRECTORY import_dir =
572 } 623 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
573 } 624 IMAGE_IMPORT_DESCRIPTOR * imports;
574 close (fd); 625 IMAGE_SECTION_HEADER * section;
626
627 section = rva_to_section (import_dir.VirtualAddress, nt_header);
628 imports = RVA_TO_PTR (import_dir.VirtualAddress, section, executable);
629
630 for ( ; imports->Name; imports++)
631 {
632 char * dllname = RVA_TO_PTR (imports->Name, section, executable);
633
634 if (strcmp (dllname, "cygwin.dll") == 0)
635 {
636 *is_cygnus_app = TRUE;
637 break;
638 }
639 }
640 }
575 } 641 }
576 642
577 return is_dos_binary; 643unwind:
644 close_file_data (&executable);
578} 645}
579 646
580int 647int
@@ -631,7 +698,9 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
631 int arglen, numenv; 698 int arglen, numenv;
632 int pid; 699 int pid;
633 child_process *cp; 700 child_process *cp;
634 int is_dos_binary; 701 int is_dos_app, is_cygnus_app;
702 int do_quoting = 0;
703 char escape_char;
635 /* We pass our process ID to our children by setting up an environment 704 /* We pass our process ID to our children by setting up an environment
636 variable in their environment. */ 705 variable in their environment. */
637 char ppid_env_var_buffer[64]; 706 char ppid_env_var_buffer[64];
@@ -659,22 +728,35 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
659 errno = EINVAL; 728 errno = EINVAL;
660 return -1; 729 return -1;
661 } 730 }
662 cmdname = XSTRING (full)->data; 731 program = full;
663 argv[0] = cmdname;
664 } 732 }
665 733
666 /* make sure cmdname is in DOS format */ 734 /* make sure argv[0] and cmdname are both in DOS format */
667 strcpy (cmdname = alloca (strlen (cmdname) + 1), argv[0]); 735 cmdname = XSTRING (program)->data;
668 unixtodos_filename (cmdname); 736 unixtodos_filename (cmdname);
669 argv[0] = cmdname; 737 argv[0] = cmdname;
670 738
671 /* Check if program is a DOS executable, and if so whether we are 739 /* Determine whether program is a 16-bit DOS executable, or a Win32
672 allowed to start it. */ 740 executable that is implicitly linked to the Cygnus dll (implying it
673 is_dos_binary = w32_is_dos_binary (cmdname); 741 was compiled with the Cygnus GNU toolchain and hence relies on
674 if (is_dos_binary && dos_process_running) 742 cygwin.dll to parse the command line - we use this to decide how to
743 escape quote chars in command line args that must be quoted). */
744 w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app);
745
746 /* On Windows 95, if cmdname is a DOS app, we invoke a helper
747 application to start it by specifying the helper app as cmdname,
748 while leaving the real app name as argv[0]. */
749 if (is_dos_app)
675 { 750 {
676 errno = EAGAIN; 751 cmdname = alloca (MAXPATHLEN);
677 return -1; 752 if (egetenv ("CMDPROXY"))
753 strcpy (cmdname, egetenv ("CMDPROXY"));
754 else
755 {
756 strcpy (cmdname, XSTRING (Vinvocation_directory)->data);
757 strcat (cmdname, "cmdproxy.exe");
758 }
759 unixtodos_filename (cmdname);
678 } 760 }
679 761
680 /* we have to do some conjuring here to put argv and envp into the 762 /* we have to do some conjuring here to put argv and envp into the
@@ -682,17 +764,41 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
682 terminated list of parameters, and envp is a null 764 terminated list of parameters, and envp is a null
683 separated/double-null terminated list of parameters. 765 separated/double-null terminated list of parameters.
684 766
685 Additionally, zero-length args and args containing whitespace need 767 Additionally, zero-length args and args containing whitespace or
686 to be wrapped in double quotes. Args containing embedded double 768 quote chars need to be wrapped in double quotes - for this to work,
687 quotes (as opposed to enclosing quotes, which we leave alone) are 769 embedded quotes need to be escaped as well. The aim is to ensure
688 usually illegal (most W32 programs do not implement escaping of 770 the child process reconstructs the argv array we start with
689 double quotes - sad but true, at least for programs compiled with 771 exactly, so we treat quotes at the beginning and end of arguments
690 MSVC), but we will escape quotes anyway for those programs that can 772 as embedded quotes.
691 handle it. The W32 gcc library from Cygnus doubles quotes to 773
692 escape them, so we will use that convention. 774 The Win32 GNU-based library from Cygnus doubles quotes to escape
693 775 them, while MSVC uses backslash for escaping. (Actually the MSVC
694 Since I have no idea how large argv and envp are likely to be 776 startup code does attempt to recognise doubled quotes and accept
695 we figure out list lengths on the fly and allocate them. */ 777 them, but gets it wrong and ends up requiring three quotes to get a
778 single embedded quote!) So by default we decide whether to use
779 quote or backslash as the escape character based on whether the
780 binary is apparently a Cygnus compiled app.
781
782 Note that using backslash to escape embedded quotes requires
783 additional special handling if an embedded quote is already
784 preceeded by backslash, or if an arg requiring quoting ends with
785 backslash. In such cases, the run of escape characters needs to be
786 doubled. For consistency, we apply this special handling as long
787 as the escape character is not quote.
788
789 Since we have no idea how large argv and envp are likely to be we
790 figure out list lengths on the fly and allocate them. */
791
792 if (!NILP (Vw32_quote_process_args))
793 {
794 do_quoting = 1;
795 /* Override escape char by binding w32-quote-process-args to
796 desired character, or use t for auto-selection. */
797 if (INTEGERP (Vw32_quote_process_args))
798 escape_char = XINT (Vw32_quote_process_args);
799 else
800 escape_char = is_cygnus_app ? '"' : '\\';
801 }
696 802
697 /* do argv... */ 803 /* do argv... */
698 arglen = 0; 804 arglen = 0;
@@ -700,22 +806,45 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
700 while (*targ) 806 while (*targ)
701 { 807 {
702 char * p = *targ; 808 char * p = *targ;
703 int add_quotes = 0; 809 int need_quotes = 0;
810 int escape_char_run = 0;
704 811
705 if (*p == 0) 812 if (*p == 0)
706 add_quotes = 1; 813 need_quotes = 1;
707 while (*p) 814 for ( ; *p; p++)
708 if (*p++ == '"') 815 {
709 { 816 if (*p == '"')
710 /* allow for embedded quotes to be doubled - we won't 817 {
711 actually double quotes that aren't embedded though */ 818 /* allow for embedded quotes to be escaped */
712 arglen++; 819 arglen++;
713 add_quotes = 1; 820 need_quotes = 1;
714 } 821 /* handle the case where the embedded quote is already escaped */
715 else if (*p == ' ' || *p == '\t') 822 if (escape_char_run > 0)
716 add_quotes = 1; 823 {
717 if (add_quotes) 824 /* To preserve the arg exactly, we need to double the
718 arglen += 2; 825 preceding escape characters (plus adding one to
826 escape the quote character itself). */
827 arglen += escape_char_run;
828 }
829 }
830 else if (*p == ' ' || *p == '\t')
831 {
832 need_quotes = 1;
833 }
834
835 if (*p == escape_char && escape_char != '"')
836 escape_char_run++;
837 else
838 escape_char_run = 0;
839 }
840 if (need_quotes)
841 {
842 arglen += 2;
843 /* handle the case where the arg ends with an escape char - we
844 must not let the enclosing quote be escaped. */
845 if (escape_char_run > 0)
846 arglen += escape_char_run;
847 }
719 arglen += strlen (*targ++) + 1; 848 arglen += strlen (*targ++) + 1;
720 } 849 }
721 cmdline = alloca (arglen); 850 cmdline = alloca (arglen);
@@ -724,24 +853,20 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
724 while (*targ) 853 while (*targ)
725 { 854 {
726 char * p = *targ; 855 char * p = *targ;
727 int add_quotes = 0; 856 int need_quotes = 0;
728 857
729 if (*p == 0) 858 if (*p == 0)
730 add_quotes = 1; 859 need_quotes = 1;
731 860
732 if (!NILP (Vw32_quote_process_args)) 861 if (do_quoting)
733 { 862 {
734 /* This is conditional because it sometimes causes more
735 problems than it solves, since argv arrays are not always
736 carefully constructed. M-x grep, for instance, passes the
737 whole command line as one argument, so it becomes
738 impossible to pass a regexp which contains spaces. */
739 for ( ; *p; p++) 863 for ( ; *p; p++)
740 if (*p == ' ' || *p == '\t' || *p == '"') 864 if (*p == ' ' || *p == '\t' || *p == '"')
741 add_quotes = 1; 865 need_quotes = 1;
742 } 866 }
743 if (add_quotes) 867 if (need_quotes)
744 { 868 {
869 int escape_char_run = 0;
745 char * first; 870 char * first;
746 char * last; 871 char * last;
747 872
@@ -749,12 +874,47 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
749 first = p; 874 first = p;
750 last = p + strlen (p) - 1; 875 last = p + strlen (p) - 1;
751 *parg++ = '"'; 876 *parg++ = '"';
877#if 0
878 /* This version does not escape quotes if they occur at the
879 beginning or end of the arg - this could lead to incorrect
880 behaviour when the arg itself represents a command line
881 containing quoted args. I believe this was originally done
882 as a hack to make some things work, before
883 `w32-quote-process-args' was added. */
752 while (*p) 884 while (*p)
753 { 885 {
754 if (*p == '"' && p > first && p < last) 886 if (*p == '"' && p > first && p < last)
755 *parg++ = '"'; /* double up embedded quotes only */ 887 *parg++ = escape_char; /* escape embedded quotes */
756 *parg++ = *p++; 888 *parg++ = *p++;
757 } 889 }
890#else
891 for ( ; *p; p++)
892 {
893 if (*p == '"')
894 {
895 /* double preceding escape chars if any */
896 while (escape_char_run > 0)
897 {
898 *parg++ = escape_char;
899 escape_char_run--;
900 }
901 /* escape all quote chars, even at beginning or end */
902 *parg++ = escape_char;
903 }
904 *parg++ = *p;
905
906 if (*p == escape_char && escape_char != '"')
907 escape_char_run++;
908 else
909 escape_char_run = 0;
910 }
911 /* double escape chars before enclosing quote */
912 while (escape_char_run > 0)
913 {
914 *parg++ = escape_char;
915 escape_char_run--;
916 }
917#endif
758 *parg++ = '"'; 918 *parg++ = '"';
759 } 919 }
760 else 920 else
@@ -812,12 +972,6 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
812 errno = ENOEXEC; 972 errno = ENOEXEC;
813 return -1; 973 return -1;
814 } 974 }
815
816 if (is_dos_binary)
817 {
818 cp->is_dos_process = TRUE;
819 dos_process_running = TRUE;
820 }
821 975
822 return pid; 976 return pid;
823} 977}
@@ -825,7 +979,14 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
825/* Emulate the select call 979/* Emulate the select call
826 Wait for available input on any of the given rfds, or timeout if 980 Wait for available input on any of the given rfds, or timeout if
827 a timeout is given and no input is detected 981 a timeout is given and no input is detected
828 wfds and efds are not supported and must be NULL. */ 982 wfds and efds are not supported and must be NULL.
983
984 For simplicity, we detect the death of child processes here and
985 synchronously call the SIGCHLD handler. Since it is possible for
986 children to be created without a corresponding pipe handle from which
987 to read output, we wait separately on the process handles as well as
988 the char_avail events for each process pipe. We only call
989 wait/reap_process when the process actually terminates. */
829 990
830/* From ntterm.c */ 991/* From ntterm.c */
831extern HANDLE keyboard_handle; 992extern HANDLE keyboard_handle;
@@ -837,17 +998,19 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
837 EMACS_TIME *timeout) 998 EMACS_TIME *timeout)
838{ 999{
839 SELECT_TYPE orfds; 1000 SELECT_TYPE orfds;
840 DWORD timeout_ms; 1001 DWORD timeout_ms, start_time;
841 int i, nh, nr; 1002 int i, nh, nc, nr;
842 DWORD active; 1003 DWORD active;
843 child_process *cp; 1004 child_process *cp, *cps[MAX_CHILDREN];
844 HANDLE wait_hnd[MAXDESC]; 1005 HANDLE wait_hnd[MAXDESC + MAX_CHILDREN];
845 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */ 1006 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */
846 1007
1008 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
1009
847 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */ 1010 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
848 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL) 1011 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
849 { 1012 {
850 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000); 1013 Sleep (timeout_ms);
851 return 0; 1014 return 0;
852 } 1015 }
853 1016
@@ -862,7 +1025,7 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
862 FD_ZERO (rfds); 1025 FD_ZERO (rfds);
863 nr = 0; 1026 nr = 0;
864 1027
865 /* Build a list of handles to wait on. */ 1028 /* Build a list of pipe handles to wait on. */
866 nh = 0; 1029 nh = 0;
867 for (i = 0; i < nfds; i++) 1030 for (i = 0; i < nfds; i++)
868 if (FD_ISSET (i, &orfds)) 1031 if (FD_ISSET (i, &orfds))
@@ -914,8 +1077,8 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
914 have changed) should indicate read has completed 1077 have changed) should indicate read has completed
915 but has not been acknowledged. */ 1078 but has not been acknowledged. */
916 current_status = cp->status; 1079 current_status = cp->status;
917 if (current_status != STATUS_READ_SUCCEEDED && 1080 if (current_status != STATUS_READ_SUCCEEDED
918 current_status != STATUS_READ_FAILED) 1081 && current_status != STATUS_READ_FAILED)
919 DebPrint (("char_avail set, but read not completed: status %d\n", 1082 DebPrint (("char_avail set, but read not completed: status %d\n",
920 current_status)); 1083 current_status));
921 } 1084 }
@@ -926,10 +1089,10 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
926 that read has completed but event wasn't yet signalled 1089 that read has completed but event wasn't yet signalled
927 when we tested it (because a context switch occurred 1090 when we tested it (because a context switch occurred
928 or if running on separate CPUs). */ 1091 or if running on separate CPUs). */
929 if (current_status != STATUS_READ_READY && 1092 if (current_status != STATUS_READ_READY
930 current_status != STATUS_READ_IN_PROGRESS && 1093 && current_status != STATUS_READ_IN_PROGRESS
931 current_status != STATUS_READ_SUCCEEDED && 1094 && current_status != STATUS_READ_SUCCEEDED
932 current_status != STATUS_READ_FAILED) 1095 && current_status != STATUS_READ_FAILED)
933 DebPrint (("char_avail reset, but read status is bad: %d\n", 1096 DebPrint (("char_avail reset, but read status is bad: %d\n",
934 current_status)); 1097 current_status));
935 } 1098 }
@@ -951,29 +1114,35 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
951 } 1114 }
952 } 1115 }
953 } 1116 }
1117
1118count_children:
1119 /* Add handles of child processes. */
1120 nc = 0;
1121 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
1122 /* some child_procs might be sockets; ignore them */
1123 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
1124 {
1125 wait_hnd[nh + nc] = cp->procinfo.hProcess;
1126 cps[nc] = cp;
1127 nc++;
1128 }
954 1129
955 /* Nothing to look for, so we didn't find anything */ 1130 /* Nothing to look for, so we didn't find anything */
956 if (nh == 0) 1131 if (nh + nc == 0)
957 { 1132 {
958 if (timeout) 1133 if (timeout)
959 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000); 1134 Sleep (timeout_ms);
960 return 0; 1135 return 0;
961 } 1136 }
962 1137
963 /* 1138 /* Wait for input or child death to be signalled. */
964 Wait for input 1139 start_time = GetTickCount ();
965 If a child process dies while this is waiting, its pipe will break 1140 active = WaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms);
966 so the reader thread will signal an error condition, thus, the wait
967 will wake up
968 */
969 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
970
971 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms);
972 1141
973 if (active == WAIT_FAILED) 1142 if (active == WAIT_FAILED)
974 { 1143 {
975 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n", 1144 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
976 nh, timeout_ms, GetLastError ())); 1145 nh + nc, timeout_ms, GetLastError ()));
977 /* don't return EBADF - this causes wait_reading_process_input to 1146 /* don't return EBADF - this causes wait_reading_process_input to
978 abort; WAIT_FAILED is returned when single-stepping under 1147 abort; WAIT_FAILED is returned when single-stepping under
979 Windows 95 after switching thread focus in debugger, and 1148 Windows 95 after switching thread focus in debugger, and
@@ -985,16 +1154,18 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
985 { 1154 {
986 return 0; 1155 return 0;
987 } 1156 }
988 else if (active >= WAIT_OBJECT_0 && 1157 else if (active >= WAIT_OBJECT_0
989 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS) 1158 && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
990 { 1159 {
991 active -= WAIT_OBJECT_0; 1160 active -= WAIT_OBJECT_0;
992 } 1161 }
993 else if (active >= WAIT_ABANDONED_0 && 1162 else if (active >= WAIT_ABANDONED_0
994 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS) 1163 && active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
995 { 1164 {
996 active -= WAIT_ABANDONED_0; 1165 active -= WAIT_ABANDONED_0;
997 } 1166 }
1167 else
1168 abort ();
998 1169
999 /* Loop over all handles after active (now officially documented as 1170 /* Loop over all handles after active (now officially documented as
1000 being the first signalled handle in the array). We do this to 1171 being the first signalled handle in the array). We do this to
@@ -1002,7 +1173,23 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1002 processed - otherwise higher numbered channels could be starved. */ 1173 processed - otherwise higher numbered channels could be starved. */
1003 do 1174 do
1004 { 1175 {
1005 if (fdindex[active] == 0) 1176 if (active >= nh)
1177 {
1178 cp = cps[active - nh];
1179 /* SIG_DFL for SIGCHLD is ignore */
1180 if (sig_handlers[SIGCHLD] != SIG_DFL
1181 && sig_handlers[SIGCHLD] != SIG_IGN)
1182 {
1183#ifdef FULL_DEBUG
1184 DebPrint (("select calling SIGCHLD handler for pid %d\n",
1185 cp->pid));
1186#endif
1187 dead_child = cp;
1188 sig_handlers[SIGCHLD] (SIGCHLD);
1189 dead_child = NULL;
1190 }
1191 }
1192 else if (fdindex[active] == 0)
1006 { 1193 {
1007 /* Keyboard input available */ 1194 /* Keyboard input available */
1008 FD_SET (0, rfds); 1195 FD_SET (0, rfds);
@@ -1010,60 +1197,63 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1010 } 1197 }
1011 else 1198 else
1012 { 1199 {
1013 /* must be a socket or pipe */ 1200 /* must be a socket or pipe - read ahead should have
1014 int current_status; 1201 completed, either succeeding or failing. */
1015
1016 cp = fd_info[ fdindex[active] ].cp;
1017
1018 /* Read ahead should have completed, either succeeding or failing. */
1019 FD_SET (fdindex[active], rfds); 1202 FD_SET (fdindex[active], rfds);
1020 nr++; 1203 nr++;
1021 current_status = cp->status;
1022 if (current_status != STATUS_READ_SUCCEEDED)
1023 {
1024 if (current_status != STATUS_READ_FAILED)
1025 DebPrint (("internal error: subprocess pipe signalled "
1026 "at the wrong time (status %d)\n!", current_status));
1027
1028 /* The child_process entry for a socket or pipe will be
1029 freed when the last descriptor using it is closed; for
1030 pipes, we call the SIGCHLD handler. */
1031 if (fd_info[ fdindex[active] ].flags & FILE_PIPE)
1032 {
1033 /* The SIGCHLD handler will do a Wait so we know it won't
1034 return until the process is dead
1035 We force Wait to only wait for this process to avoid it
1036 picking up other children that happen to be dead but that
1037 we haven't noticed yet
1038 SIG_DFL for SIGCHLD is ignore? */
1039 if (sig_handlers[SIGCHLD] != SIG_DFL &&
1040 sig_handlers[SIGCHLD] != SIG_IGN)
1041 {
1042#ifdef FULL_DEBUG
1043 DebPrint (("select calling SIGCHLD handler for pid %d\n",
1044 cp->pid));
1045#endif
1046 dead_child = cp;
1047 sig_handlers[SIGCHLD] (SIGCHLD);
1048 dead_child = NULL;
1049 }
1050
1051 /* Clean up the child process entry in the table */
1052 reap_subprocess (cp);
1053 }
1054 }
1055 } 1204 }
1056 1205
1057 /* Test for input on remaining channels. */ 1206 /* Even though wait_reading_process_output only reads from at most
1058 while (++active < nh) 1207 one channel, we must process all channels here so that we reap
1208 all children that have died. */
1209 while (++active < nh + nc)
1059 if (WaitForSingleObject (wait_hnd[active], 0) == WAIT_OBJECT_0) 1210 if (WaitForSingleObject (wait_hnd[active], 0) == WAIT_OBJECT_0)
1060 break; 1211 break;
1061 } while (active < nh); 1212 } while (active < nh + nc);
1213
1214 /* If no input has arrived and timeout hasn't expired, wait again. */
1215 if (nr == 0)
1216 {
1217 DWORD elapsed = GetTickCount () - start_time;
1218
1219 if (timeout_ms > elapsed) /* INFINITE is MAX_UINT */
1220 {
1221 if (timeout_ms != INFINITE)
1222 timeout_ms -= elapsed;
1223 goto count_children;
1224 }
1225 }
1062 1226
1063 return nr; 1227 return nr;
1064} 1228}
1065 1229
1066/* Substitute for certain kill () operations */ 1230/* Substitute for certain kill () operations */
1231
1232static BOOL CALLBACK
1233find_child_console (HWND hwnd, child_process * cp)
1234{
1235 DWORD thread_id;
1236 DWORD process_id;
1237
1238 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
1239 if (process_id == cp->procinfo.dwProcessId)
1240 {
1241 char window_class[32];
1242
1243 GetClassName (hwnd, window_class, sizeof (window_class));
1244 if (strcmp (window_class,
1245 (os_subtype == OS_WIN95)
1246 ? "tty"
1247 : "ConsoleWindowClass") == 0)
1248 {
1249 cp->hwnd = hwnd;
1250 return FALSE;
1251 }
1252 }
1253 /* keep looking */
1254 return TRUE;
1255}
1256
1067int 1257int
1068sys_kill (int pid, int sig) 1258sys_kill (int pid, int sig)
1069{ 1259{
@@ -1094,27 +1284,81 @@ sys_kill (int pid, int sig)
1094 { 1284 {
1095 proc_hand = cp->procinfo.hProcess; 1285 proc_hand = cp->procinfo.hProcess;
1096 pid = cp->procinfo.dwProcessId; 1286 pid = cp->procinfo.dwProcessId;
1287
1288 /* Try to locate console window for process. */
1289 EnumWindows (find_child_console, (LPARAM) cp);
1097 } 1290 }
1098 1291
1099 if (sig == SIGINT) 1292 if (sig == SIGINT)
1100 { 1293 {
1294 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
1295 {
1296 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
1297 BYTE vk_break_code = VK_CANCEL;
1298 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
1299 HWND foreground_window;
1300
1301 if (break_scan_code == 0)
1302 {
1303 /* Fake Ctrl-C if we can't manage Ctrl-Break. */
1304 vk_break_code = 'C';
1305 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
1306 }
1307
1308 foreground_window = GetForegroundWindow ();
1309 if (foreground_window && SetForegroundWindow (cp->hwnd))
1310 {
1311 /* Generate keystrokes as if user had typed Ctrl-Break or Ctrl-C. */
1312 keybd_event (VK_CONTROL, control_scan_code, 0, 0);
1313 keybd_event (vk_break_code, break_scan_code, 0, 0);
1314 keybd_event (vk_break_code, break_scan_code, KEYEVENTF_KEYUP, 0);
1315 keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
1316
1317 SetForegroundWindow (foreground_window);
1318 }
1319 }
1101 /* Ctrl-Break is NT equivalent of SIGINT. */ 1320 /* Ctrl-Break is NT equivalent of SIGINT. */
1102 if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid)) 1321 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
1103 { 1322 {
1104 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d " 1323 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
1105 "for pid %lu\n", GetLastError (), pid)); 1324 "for pid %lu\n", GetLastError (), pid));
1106 errno = EINVAL; 1325 errno = EINVAL;
1107 rc = -1; 1326 rc = -1;
1108 } 1327 }
1109 } 1328 }
1110 else 1329 else
1111 { 1330 {
1331 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
1332 {
1333#if 1
1334 if (os_subtype == OS_WIN95)
1335 {
1336/*
1337 Another possibility is to try terminating the VDM out-right by
1338 calling the Shell VxD (id 0x17) V86 interface, function #4
1339 "SHELL_Destroy_VM", ie.
1340
1341 mov edx,4
1342 mov ebx,vm_handle
1343 call shellapi
1344
1345 First need to determine the current VM handle, and then arrange for
1346 the shellapi call to be made from the system vm (by using
1347 Switch_VM_and_callback).
1348
1349 Could try to invoke DestroyVM through CallVxD.
1350
1351*/
1352 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
1353 }
1354 else
1355#endif
1356 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
1357 }
1112 /* Kill the process. On W32 this doesn't kill child processes 1358 /* Kill the process. On W32 this doesn't kill child processes
1113 so it doesn't work very well for shells which is why it's not 1359 so it doesn't work very well for shells which is why it's not
1114 used in every case. Also, don't try to terminate DOS processes 1360 used in every case. */
1115 (on Windows 95), because this will hang Emacs. */ 1361 else if (!TerminateProcess (proc_hand, 0xff))
1116 if (!(cp && cp->is_dos_process)
1117 && !TerminateProcess (proc_hand, 0xff))
1118 { 1362 {
1119 DebPrint (("sys_kill.TerminateProcess returned %d " 1363 DebPrint (("sys_kill.TerminateProcess returned %d "
1120 "for pid %lu\n", GetLastError (), pid)); 1364 "for pid %lu\n", GetLastError (), pid));
@@ -1213,6 +1457,12 @@ reset_standard_handles (int in, int out, int err, HANDLE handles[3])
1213 SetStdHandle (STD_ERROR_HANDLE, handles[2]); 1457 SetStdHandle (STD_ERROR_HANDLE, handles[2]);
1214} 1458}
1215 1459
1460void
1461set_process_dir (char * dir)
1462{
1463 process_dir = dir;
1464}
1465
1216#ifdef HAVE_SOCKETS 1466#ifdef HAVE_SOCKETS
1217 1467
1218/* To avoid problems with winsock implementations that work over dial-up 1468/* To avoid problems with winsock implementations that work over dial-up
@@ -1282,12 +1532,220 @@ socket connections still exist.")
1282#endif /* HAVE_SOCKETS */ 1532#endif /* HAVE_SOCKETS */
1283 1533
1284 1534
1535/* Some miscellaneous functions that are Windows specific, but not GUI
1536 specific (ie. are applicable in terminal or batch mode as well). */
1537
1538/* lifted from fileio.c */
1539#define CORRECT_DIR_SEPS(s) \
1540 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
1541 else unixtodos_filename (s); \
1542 } while (0)
1543
1544DEFUN ("w32-short-file-name", Fw32_short_file_name, Sw32_short_file_name, 1, 1, 0,
1545 "Return the short file name version (8.3) of the full path of FILENAME.\n\
1546If FILENAME does not exist, return nil.\n\
1547All path elements in FILENAME are converted to their short names.")
1548 (filename)
1549 Lisp_Object filename;
1550{
1551 char shortname[MAX_PATH];
1552
1553 CHECK_STRING (filename, 0);
1554
1555 /* first expand it. */
1556 filename = Fexpand_file_name (filename, Qnil);
1557
1558 /* luckily, this returns the short version of each element in the path. */
1559 if (GetShortPathName (XSTRING (filename)->data, shortname, MAX_PATH) == 0)
1560 return Qnil;
1561
1562 CORRECT_DIR_SEPS (shortname);
1563
1564 return build_string (shortname);
1565}
1566
1567
1568DEFUN ("w32-long-file-name", Fw32_long_file_name, Sw32_long_file_name,
1569 1, 1, 0,
1570 "Return the long file name version of the full path of FILENAME.\n\
1571If FILENAME does not exist, return nil.\n\
1572All path elements in FILENAME are converted to their long names.")
1573 (filename)
1574 Lisp_Object filename;
1575{
1576 char longname[ MAX_PATH ];
1577
1578 CHECK_STRING (filename, 0);
1579
1580 /* first expand it. */
1581 filename = Fexpand_file_name (filename, Qnil);
1582
1583 if (!w32_get_long_filename (XSTRING (filename)->data, longname, MAX_PATH))
1584 return Qnil;
1585
1586 CORRECT_DIR_SEPS (longname);
1587
1588 return build_string (longname);
1589}
1590
1591DEFUN ("w32-set-process-priority", Fw32_set_process_priority, Sw32_set_process_priority,
1592 2, 2, 0,
1593 "Set the priority of PROCESS to PRIORITY.\n\
1594If PROCESS is nil, the priority of Emacs is changed, otherwise the\n\
1595priority of the process whose pid is PROCESS is changed.\n\
1596PRIORITY should be one of the symbols high, normal, or low;\n\
1597any other symbol will be interpreted as normal.\n\
1598\n\
1599If successful, the return value is t, otherwise nil.")
1600 (process, priority)
1601 Lisp_Object process, priority;
1602{
1603 HANDLE proc_handle = GetCurrentProcess ();
1604 DWORD priority_class = NORMAL_PRIORITY_CLASS;
1605 Lisp_Object result = Qnil;
1606
1607 CHECK_SYMBOL (priority, 0);
1608
1609 if (!NILP (process))
1610 {
1611 DWORD pid;
1612 child_process *cp;
1613
1614 CHECK_NUMBER (process, 0);
1615
1616 /* Allow pid to be an internally generated one, or one obtained
1617 externally. This is necessary because real pids on Win95 are
1618 negative. */
1619
1620 pid = XINT (process);
1621 cp = find_child_pid (pid);
1622 if (cp != NULL)
1623 pid = cp->procinfo.dwProcessId;
1624
1625 proc_handle = OpenProcess (PROCESS_SET_INFORMATION, FALSE, pid);
1626 }
1627
1628 if (EQ (priority, Qhigh))
1629 priority_class = HIGH_PRIORITY_CLASS;
1630 else if (EQ (priority, Qlow))
1631 priority_class = IDLE_PRIORITY_CLASS;
1632
1633 if (proc_handle != NULL)
1634 {
1635 if (SetPriorityClass (proc_handle, priority_class))
1636 result = Qt;
1637 if (!NILP (process))
1638 CloseHandle (proc_handle);
1639 }
1640
1641 return result;
1642}
1643
1644
1645DEFUN ("w32-get-locale-info", Fw32_get_locale_info, Sw32_get_locale_info, 1, 2, 0,
1646 "Return information about the Windows locale LCID.\n\
1647By default, return a three letter locale code which encodes the default\n\
1648language as the first two characters, and the country or regionial variant\n\
1649as the third letter. For example, ENU refers to `English (United States)',\n\
1650while ENC means `English (Canadian)'.\n\
1651\n\
1652If the optional argument LONGFORM is non-nil, the long form of the locale\n\
1653name is returned, e.g. `English (United States)' instead.\n\
1654\n\
1655If LCID (a 16-bit number) is not a valid locale, the result is nil.")
1656 (lcid, longform)
1657 Lisp_Object lcid, longform;
1658{
1659 int got_abbrev;
1660 int got_full;
1661 char abbrev_name[32] = { 0 };
1662 char full_name[256] = { 0 };
1663
1664 CHECK_NUMBER (lcid, 0);
1665
1666 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
1667 return Qnil;
1668
1669 if (NILP (longform))
1670 {
1671 got_abbrev = GetLocaleInfo (XINT (lcid),
1672 LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
1673 abbrev_name, sizeof (abbrev_name));
1674 if (got_abbrev)
1675 return build_string (abbrev_name);
1676 }
1677 else
1678 {
1679 got_full = GetLocaleInfo (XINT (lcid),
1680 LOCALE_SLANGUAGE | LOCALE_USE_CP_ACP,
1681 full_name, sizeof (full_name));
1682 if (got_full)
1683 return build_string (full_name);
1684 }
1685
1686 return Qnil;
1687}
1688
1689
1690DEFUN ("w32-get-current-locale-id", Fw32_get_current_locale_id, Sw32_get_current_locale_id, 0, 0, 0,
1691 "Return Windows locale id for current locale setting.\n\
1692This is a numerical value; use `w32-get-locale-info' to convert to a\n\
1693human-readable form.")
1694 ()
1695{
1696 return make_number (GetThreadLocale ());
1697}
1698
1699
1700DEFUN ("w32-get-default-locale-id", Fw32_get_default_locale_id, Sw32_get_default_locale_id, 0, 1, 0,
1701 "Return Windows locale id for default locale setting.\n\
1702By default, the system default locale setting is returned; if the optional\n\
1703parameter USERP is non-nil, the user default locale setting is returned.\n\
1704This is a numerical value; use `w32-get-locale-info' to convert to a\n\
1705human-readable form.")
1706 (userp)
1707 Lisp_Object userp;
1708{
1709 if (NILP (userp))
1710 return make_number (GetSystemDefaultLCID ());
1711 return make_number (GetUserDefaultLCID ());
1712}
1713
1714
1715DEFUN ("w32-set-current-locale", Fw32_set_current_locale, Sw32_set_current_locale, 1, 1, 0,
1716 "Make Windows locale LCID be the current locale setting for Emacs.\n\
1717If successful, the new locale id is returned, otherwise nil.")
1718 (lcid)
1719 Lisp_Object lcid;
1720{
1721 CHECK_NUMBER (lcid, 0);
1722
1723 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
1724 return Qnil;
1725
1726 if (!SetThreadLocale (XINT (lcid)))
1727 return Qnil;
1728
1729 return make_number (GetThreadLocale ());
1730}
1731
1732
1285syms_of_ntproc () 1733syms_of_ntproc ()
1286{ 1734{
1735 Qhigh = intern ("high");
1736 Qlow = intern ("low");
1737
1287#ifdef HAVE_SOCKETS 1738#ifdef HAVE_SOCKETS
1288 defsubr (&Sw32_has_winsock); 1739 defsubr (&Sw32_has_winsock);
1289 defsubr (&Sw32_unload_winsock); 1740 defsubr (&Sw32_unload_winsock);
1290#endif 1741#endif
1742 defsubr (&Sw32_short_file_name);
1743 defsubr (&Sw32_long_file_name);
1744 defsubr (&Sw32_set_process_priority);
1745 defsubr (&Sw32_get_locale_info);
1746 defsubr (&Sw32_get_current_locale_id);
1747 defsubr (&Sw32_get_default_locale_id);
1748 defsubr (&Sw32_set_current_locale);
1291 1749
1292 DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args, 1750 DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args,
1293 "Non-nil enables quoting of process arguments to ensure correct parsing.\n\ 1751 "Non-nil enables quoting of process arguments to ensure correct parsing.\n\
@@ -1296,10 +1754,10 @@ programs have to reconstruct the argv array by parsing the command\n\
1296line string. For an argument to contain a space, it must be enclosed\n\ 1754line string. For an argument to contain a space, it must be enclosed\n\
1297in double quotes or it will be parsed as multiple arguments.\n\ 1755in double quotes or it will be parsed as multiple arguments.\n\
1298\n\ 1756\n\
1299However, the argument list to call-process is not always correctly\n\ 1757If the value is a character, that character will be used to escape any\n\
1300constructed (or arguments have already been quoted), so enabling this\n\ 1758quote characters that appear, otherwise a suitable escape character\n\
1301option may cause unexpected behavior."); 1759will be chosen based on the type of the program.");
1302 Vw32_quote_process_args = Qnil; 1760 Vw32_quote_process_args = Qt;
1303 1761
1304 DEFVAR_LISP ("w32-start-process-show-window", 1762 DEFVAR_LISP ("w32-start-process-show-window",
1305 &Vw32_start_process_show_window, 1763 &Vw32_start_process_show_window,
@@ -1307,6 +1765,16 @@ option may cause unexpected behavior.");
1307When non-nil, they show their window in the method of their choice."); 1765When non-nil, they show their window in the method of their choice.");
1308 Vw32_start_process_show_window = Qnil; 1766 Vw32_start_process_show_window = Qnil;
1309 1767
1768 DEFVAR_LISP ("w32-start-process-share-console",
1769 &Vw32_start_process_share_console,
1770 "When nil, processes started via start-process are given a new console.\n\
1771When non-nil, they share the Emacs console; this has the limitation of\n\
1772allowing only only DOS subprocess to run at a time (whether started directly\n\
1773or indirectly by Emacs), and preventing Emacs from cleanly terminating the\n\
1774subprocess group, but may allow Emacs to interrupt a subprocess that doesn't\n\
1775otherwise respond to interrupts from Emacs.");
1776 Vw32_start_process_share_console = Qnil;
1777
1310 DEFVAR_INT ("w32-pipe-read-delay", &Vw32_pipe_read_delay, 1778 DEFVAR_INT ("w32-pipe-read-delay", &Vw32_pipe_read_delay,
1311 "Forced delay before reading subprocess output.\n\ 1779 "Forced delay before reading subprocess output.\n\
1312This is done to improve the buffering of subprocess output, by\n\ 1780This is done to improve the buffering of subprocess output, by\n\
@@ -1322,5 +1790,22 @@ process temporarily). A value of zero disables waiting entirely.");
1322 "Non-nil means convert all-upper case file names to lower case.\n\ 1790 "Non-nil means convert all-upper case file names to lower case.\n\
1323This applies when performing completions and file name expansion."); 1791This applies when performing completions and file name expansion.");
1324 Vw32_downcase_file_names = Qnil; 1792 Vw32_downcase_file_names = Qnil;
1793
1794#if 0
1795 DEFVAR_LISP ("w32-generate-fake-inodes", &Vw32_generate_fake_inodes,
1796 "Non-nil means attempt to fake realistic inode values.\n\
1797This works by hashing the truename of files, and should detect \n\
1798aliasing between long and short (8.3 DOS) names, but can have\n\
1799false positives because of hash collisions. Note that determing\n\
1800the truename of a file can be slow.");
1801 Vw32_generate_fake_inodes = Qnil;
1802#endif
1803
1804 DEFVAR_LISP ("w32-get-true-file-attributes", &Vw32_get_true_file_attributes,
1805 "Non-nil means determine accurate link count in file-attributes.\n\
1806This option slows down file-attributes noticeably, so is disabled by\n\
1807default. Note that it is only useful for files on NTFS volumes,\n\
1808where hard links are supported.");
1809 Vw32_get_true_file_attributes = Qnil;
1325} 1810}
1326/* end of ntproc.c */ 1811/* end of ntproc.c */