aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1996-05-17 21:39:36 +0000
committerKarl Heuer1996-05-17 21:39:36 +0000
commit817abdf65c757246c49a90bc58e065acd0b7196c (patch)
treec8d0e930f0facd268ab0be896659ab4ebec5bfe7 /src
parent1f96acec5ef797ba92a93671b97a1760b3c56967 (diff)
downloademacs-817abdf65c757246c49a90bc58e065acd0b7196c.tar.gz
emacs-817abdf65c757246c49a90bc58e065acd0b7196c.zip
(Vwin32_pipe_read_delay): New var.
(can_run_dos_process, dos_process_running): New vars. (win32_is_dos_binary): New function. (reap_subprocess, sys_spawnve): Use them. (syms_of_ntproc): Defvar and initialize Vwin32_pipe_read_delay.
Diffstat (limited to 'src')
-rw-r--r--src/w32proc.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index 42b5b6729f8..d537bd5d3a2 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -51,6 +51,17 @@ Boston, MA 02111-1307, USA.
51 conditional (off by default). */ 51 conditional (off by default). */
52Lisp_Object Vwin32_quote_process_args; 52Lisp_Object Vwin32_quote_process_args;
53 53
54/* Time to sleep before reading from a subprocess output pipe - this
55 avoids the inefficiency of frequently reading small amounts of data.
56 This is primarily necessary for handling DOS processes on Windows 95,
57 but is useful for Win32 processes on both Win95 and NT as well. */
58Lisp_Object Vwin32_pipe_read_delay;
59
60/* Keep track of whether we have already started a DOS program, and
61 whether we can run them in the first place. */
62BOOL can_run_dos_process;
63BOOL dos_process_running;
64
54#ifndef SYS_SIGLIST_DECLARED 65#ifndef SYS_SIGLIST_DECLARED
55extern char *sys_siglist[]; 66extern char *sys_siglist[];
56#endif 67#endif
@@ -367,6 +378,11 @@ reap_subprocess (child_process *cp)
367 cp->procinfo.hProcess = NULL; 378 cp->procinfo.hProcess = NULL;
368 CloseHandle (cp->procinfo.hThread); 379 CloseHandle (cp->procinfo.hThread);
369 cp->procinfo.hThread = NULL; 380 cp->procinfo.hThread = NULL;
381
382 /* If this was a DOS process, indicate that it is now safe to
383 start a new one. */
384 if (cp->is_dos_process)
385 dos_process_running = FALSE;
370 } 386 }
371 387
372 /* For asynchronous children, the child_proc resources will be freed 388 /* For asynchronous children, the child_proc resources will be freed
@@ -504,6 +520,54 @@ sys_wait (int *status)
504 return pid; 520 return pid;
505} 521}
506 522
523int
524win32_is_dos_binary (char * filename)
525{
526 IMAGE_DOS_HEADER dos_header;
527 DWORD signature;
528 int fd;
529 int is_dos_binary = FALSE;
530
531 fd = open (filename, O_RDONLY | O_BINARY, 0);
532 if (fd >= 0)
533 {
534 char * p = strrchr (filename, '.');
535
536 /* We can only identify DOS .com programs from the extension. */
537 if (p && stricmp (p, ".com") == 0)
538 is_dos_binary = TRUE;
539 else if (p && stricmp (p, ".bat") == 0)
540 {
541 /* A DOS shell script - it appears that CreateProcess is happy
542 to accept this (somewhat surprisingly); presumably it looks
543 at COMSPEC to determine what executable to actually invoke.
544 Therefore, we have to do the same here as well. */
545 p = getenv ("COMSPEC");
546 if (p)
547 is_dos_binary = win32_is_dos_binary (p);
548 }
549 else
550 {
551 /* Look for DOS .exe signature - if found, we must also check
552 that it isn't really a 16- or 32-bit Windows exe, since
553 both formats start with a DOS program stub. Note that
554 16-bit Windows executables use the OS/2 1.x format. */
555 if (read (fd, &dos_header, sizeof (dos_header)) == sizeof (dos_header)
556 && dos_header.e_magic == IMAGE_DOS_SIGNATURE
557 && lseek (fd, dos_header.e_lfanew, SEEK_SET) != -1)
558 {
559 if (read (fd, &signature, sizeof (signature)) != sizeof (signature)
560 || (signature != IMAGE_NT_SIGNATURE &&
561 LOWORD (signature) != IMAGE_OS2_SIGNATURE))
562 is_dos_binary = TRUE;
563 }
564 }
565 close (fd);
566 }
567
568 return is_dos_binary;
569}
570
507/* We pass our process ID to our children by setting up an environment 571/* We pass our process ID to our children by setting up an environment
508 variable in their environment. */ 572 variable in their environment. */
509char ppid_env_var_buffer[64]; 573char ppid_env_var_buffer[64];
@@ -518,6 +582,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
518 int arglen; 582 int arglen;
519 int pid; 583 int pid;
520 child_process *cp; 584 child_process *cp;
585 int is_dos_binary;
521 586
522 /* We don't care about the other modes */ 587 /* We don't care about the other modes */
523 if (mode != _P_NOWAIT) 588 if (mode != _P_NOWAIT)
@@ -549,6 +614,15 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
549 strcpy (cmdname = alloca (strlen (cmdname) + 1), argv[0]); 614 strcpy (cmdname = alloca (strlen (cmdname) + 1), argv[0]);
550 unixtodos_filename (cmdname); 615 unixtodos_filename (cmdname);
551 argv[0] = cmdname; 616 argv[0] = cmdname;
617
618 /* Check if program is a DOS executable, and if so whether we are
619 allowed to start it. */
620 is_dos_binary = win32_is_dos_binary (cmdname);
621 if (is_dos_binary && (!can_run_dos_process || dos_process_running))
622 {
623 errno = (can_run_dos_process) ? EAGAIN : EINVAL;
624 return -1;
625 }
552 626
553 /* we have to do some conjuring here to put argv and envp into the 627 /* we have to do some conjuring here to put argv and envp into the
554 form CreateProcess wants... argv needs to be a space separated/null 628 form CreateProcess wants... argv needs to be a space separated/null
@@ -679,6 +753,12 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
679 errno = ENOEXEC; 753 errno = ENOEXEC;
680 return -1; 754 return -1;
681 } 755 }
756
757 if (is_dos_binary)
758 {
759 cp->is_dos_process = TRUE;
760 dos_process_running = TRUE;
761 }
682 762
683 return pid; 763 return pid;
684} 764}
@@ -1086,5 +1166,16 @@ However, the argument list to call-process is not always correctly\n\
1086constructed (or arguments have already been quoted), so enabling this\n\ 1166constructed (or arguments have already been quoted), so enabling this\n\
1087option may cause unexpected behavior."); 1167option may cause unexpected behavior.");
1088 Vwin32_quote_process_args = Qnil; 1168 Vwin32_quote_process_args = Qnil;
1169
1170 DEFVAR_INT ("win32-pipe-read-delay", &Vwin32_pipe_read_delay,
1171 "Forced delay before reading subprocess output.\n\
1172This is done to improve the buffering of subprocess output, by\n\
1173avoiding the inefficiency of frequently reading small amounts of data.\n\
1174\n\
1175If positive, the value is the number of milliseconds to sleep before\n\
1176reading the subprocess output. If negative, the magnitude is the number\n\
1177of time slices to wait (effectively boosting the priority of the child\n\
1178process temporarily). A value of zero disables waiting entirely.");
1179 Vwin32_pipe_read_delay = 50;
1089} 1180}
1090/* end of ntproc.c */ 1181/* end of ntproc.c */