comparison src/ntproc.c @ 100:4be1180a9e89 r20-1b2

Import from CVS: tag r20-1b2
author cvs
date Mon, 13 Aug 2007 09:15:11 +0200
parents
children 9b50b4588a93
comparison
equal deleted inserted replaced
99:2d83cbd90d8d 100:4be1180a9e89
1 /* Process support for Windows NT port of XEMACS.
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 Drew Bliss Oct 14, 1993
22 Adapted from alarm.c by Tim Fleehart */
23
24 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <io.h>
30 #include <fcntl.h>
31 #include <signal.h>
32
33 /* must include CRT headers *before* config.h */
34 #include "config.h"
35 #undef signal
36 #undef wait
37 #undef spawnve
38 #undef select
39 #undef kill
40
41 #include <windows.h>
42
43 #include "lisp.h"
44 #include "nt.h"
45 #include "systime.h"
46 #include "syswait.h"
47 #include "process.h"
48
49 /* Control whether spawnve quotes arguments as necessary to ensure
50 correct parsing by child process. Because not all uses of spawnve
51 are careful about constructing argv arrays, we make this behaviour
52 conditional (off by default). */
53 Lisp_Object Vwin32_quote_process_args;
54
55 /* Time to sleep before reading from a subprocess output pipe - this
56 avoids the inefficiency of frequently reading small amounts of data.
57 This is primarily necessary for handling DOS processes on Windows 95,
58 but is useful for Win32 processes on both Win95 and NT as well. */
59 Lisp_Object Vwin32_pipe_read_delay;
60
61 /* Control conversion of upper case file names to lower case.
62 nil means no, t means yes. */
63 Lisp_Object Vwin32_downcase_file_names;
64
65 /* Keep track of whether we have already started a DOS program. */
66 BOOL dos_process_running;
67
68 #ifndef SYS_SIGLIST_DECLARED
69 extern char *sys_siglist[];
70 #endif
71
72 #ifdef EMACSDEBUG
73 void _DebPrint (const char *fmt, ...)
74 {
75 char buf[1024];
76 va_list args;
77
78 va_start (args, fmt);
79 vsprintf (buf, fmt, args);
80 va_end (args);
81 OutputDebugString (buf);
82 }
83 #endif
84
85 typedef void (_CALLBACK_ *signal_handler)(int);
86
87 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
88 static signal_handler sig_handlers[NSIG];
89
90 /* Fake signal implementation to record the SIGCHLD handler. */
91 signal_handler
92 sys_signal (int sig, signal_handler handler)
93 {
94 signal_handler old;
95
96 if (sig != SIGCHLD)
97 {
98 errno = EINVAL;
99 return SIG_ERR;
100 }
101 old = sig_handlers[sig];
102 sig_handlers[sig] = handler;
103 return old;
104 }
105
106 /* Defined in <process.h> which conflicts with the local copy */
107 #define _P_NOWAIT 1
108
109 /* Child process management list. */
110 int child_proc_count = 0;
111 child_process child_procs[ MAX_CHILDREN ];
112 child_process *dead_child = NULL;
113
114 DWORD WINAPI reader_thread (void *arg);
115
116 /* Find an unused process slot. */
117 child_process *
118 new_child (void)
119 {
120 child_process *cp;
121 DWORD id;
122
123 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
124 if (!CHILD_ACTIVE (cp))
125 goto Initialise;
126 if (child_proc_count == MAX_CHILDREN)
127 return NULL;
128 cp = &child_procs[child_proc_count++];
129
130 Initialise:
131 memset (cp, 0, sizeof(*cp));
132 cp->fd = -1;
133 cp->pid = -1;
134 cp->procinfo.hProcess = NULL;
135 cp->status = STATUS_READ_ERROR;
136
137 /* use manual reset event so that select() will function properly */
138 cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL);
139 if (cp->char_avail)
140 {
141 cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
142 if (cp->char_consumed)
143 {
144 cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
145 if (cp->thrd)
146 return cp;
147 }
148 }
149 delete_child (cp);
150 return NULL;
151 }
152
153 void
154 delete_child (child_process *cp)
155 {
156 int i;
157
158 /* Should not be deleting a child that is still needed. */
159 for (i = 0; i < MAXDESC; i++)
160 if (fd_info[i].cp == cp)
161 abort ();
162
163 if (!CHILD_ACTIVE (cp))
164 return;
165
166 /* reap thread if necessary */
167 if (cp->thrd)
168 {
169 DWORD rc;
170
171 if (GetExitCodeThread (cp->thrd, &rc) && rc == STILL_ACTIVE)
172 {
173 /* let the thread exit cleanly if possible */
174 cp->status = STATUS_READ_ERROR;
175 SetEvent (cp->char_consumed);
176 if (WaitForSingleObject (cp->thrd, 1000) != WAIT_OBJECT_0)
177 {
178 DebPrint (("delete_child.WaitForSingleObject (thread) failed "
179 "with %lu for fd %ld\n", GetLastError (), cp->fd));
180 TerminateThread (cp->thrd, 0);
181 }
182 }
183 CloseHandle (cp->thrd);
184 cp->thrd = NULL;
185 }
186 if (cp->char_avail)
187 {
188 CloseHandle (cp->char_avail);
189 cp->char_avail = NULL;
190 }
191 if (cp->char_consumed)
192 {
193 CloseHandle (cp->char_consumed);
194 cp->char_consumed = NULL;
195 }
196
197 /* update child_proc_count (highest numbered slot in use plus one) */
198 if (cp == child_procs + child_proc_count - 1)
199 {
200 for (i = child_proc_count-1; i >= 0; i--)
201 if (CHILD_ACTIVE (&child_procs[i]))
202 {
203 child_proc_count = i + 1;
204 break;
205 }
206 }
207 if (i < 0)
208 child_proc_count = 0;
209 }
210
211 /* Find a child by pid. */
212 static child_process *
213 find_child_pid (DWORD pid)
214 {
215 child_process *cp;
216
217 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
218 if (CHILD_ACTIVE (cp) && pid == cp->pid)
219 return cp;
220 return NULL;
221 }
222
223
224 /* Thread proc for child process and socket reader threads. Each thread
225 is normally blocked until woken by select() to check for input by
226 reading one char. When the read completes, char_avail is signalled
227 to wake up the select emulator and the thread blocks itself again. */
228 DWORD WINAPI
229 reader_thread (void *arg)
230 {
231 child_process *cp;
232
233 /* Our identity */
234 cp = (child_process *)arg;
235
236 /* We have to wait for the go-ahead before we can start */
237 if (cp == NULL ||
238 WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
239 return 1;
240
241 for (;;)
242 {
243 int rc;
244
245 rc = _sys_read_ahead (cp->fd);
246
247 /* The name char_avail is a misnomer - it really just means the
248 read-ahead has completed, whether successfully or not. */
249 if (!SetEvent (cp->char_avail))
250 {
251 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
252 GetLastError (), cp->fd));
253 return 1;
254 }
255
256 if (rc == STATUS_READ_ERROR)
257 return 1;
258
259 /* If the read died, the child has died so let the thread die */
260 if (rc == STATUS_READ_FAILED)
261 break;
262
263 /* Wait until our input is acknowledged before reading again */
264 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
265 {
266 DebPrint (("reader_thread.WaitForSingleObject failed with "
267 "%lu for fd %ld\n", GetLastError (), cp->fd));
268 break;
269 }
270 }
271 return 0;
272 }
273
274 static BOOL
275 create_child (char *exe, char *cmdline, char *env,
276 int * pPid, child_process *cp)
277 {
278 STARTUPINFO start;
279 SECURITY_ATTRIBUTES sec_attrs;
280 SECURITY_DESCRIPTOR sec_desc;
281
282 if (cp == NULL) abort ();
283
284 memset (&start, 0, sizeof (start));
285 start.cb = sizeof (start);
286
287 #ifdef HAVE_NTGUI
288 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
289 start.wShowWindow = SW_HIDE;
290
291 start.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
292 start.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
293 start.hStdError = GetStdHandle (STD_ERROR_HANDLE);
294 #endif /* HAVE_NTGUI */
295
296 /* Explicitly specify no security */
297 if (!InitializeSecurityDescriptor (&sec_desc, SECURITY_DESCRIPTOR_REVISION))
298 goto EH_Fail;
299 if (!SetSecurityDescriptorDacl (&sec_desc, TRUE, NULL, FALSE))
300 goto EH_Fail;
301 sec_attrs.nLength = sizeof (sec_attrs);
302 sec_attrs.lpSecurityDescriptor = &sec_desc;
303 sec_attrs.bInheritHandle = FALSE;
304
305 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
306 CREATE_NEW_PROCESS_GROUP,
307 env, NULL,
308 &start, &cp->procinfo))
309 goto EH_Fail;
310
311 cp->pid = (int) cp->procinfo.dwProcessId;
312
313 /* Hack for Windows 95, which assigns large (ie negative) pids */
314 if (cp->pid < 0)
315 cp->pid = -cp->pid;
316
317 /* pid must fit in a Lisp_Int */
318 cp->pid = (cp->pid & VALMASK);
319
320
321 *pPid = cp->pid;
322
323 return TRUE;
324
325 EH_Fail:
326 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError()););
327 return FALSE;
328 }
329
330 /* create_child doesn't know what emacs' file handle will be for waiting
331 on output from the child, so we need to make this additional call
332 to register the handle with the process
333 This way the select emulator knows how to match file handles with
334 entries in child_procs. */
335 void
336 register_child (int pid, int fd)
337 {
338 child_process *cp;
339
340 cp = find_child_pid (pid);
341 if (cp == NULL)
342 {
343 DebPrint (("register_child unable to find pid %lu\n", pid));
344 return;
345 }
346
347 #ifdef FULL_DEBUG
348 DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid));
349 #endif
350
351 cp->fd = fd;
352
353 /* thread is initially blocked until select is called; set status so
354 that select will release thread */
355 cp->status = STATUS_READ_ACKNOWLEDGED;
356
357 /* attach child_process to fd_info */
358 if (fd_info[fd].cp != NULL)
359 {
360 DebPrint (("register_child: fd_info[%d] apparently in use!\n", fd));
361 abort ();
362 }
363
364 fd_info[fd].cp = cp;
365 }
366
367 /* When a process dies its pipe will break so the reader thread will
368 signal failure to the select emulator.
369 The select emulator then calls this routine to clean up.
370 Since the thread signaled failure we can assume it is exiting. */
371 static void
372 reap_subprocess (child_process *cp)
373 {
374 if (cp->procinfo.hProcess)
375 {
376 /* Reap the process */
377 if (WaitForSingleObject (cp->procinfo.hProcess, INFINITE) != WAIT_OBJECT_0)
378 DebPrint (("reap_subprocess.WaitForSingleObject (process) failed "
379 "with %lu for fd %ld\n", GetLastError (), cp->fd));
380 CloseHandle (cp->procinfo.hProcess);
381 cp->procinfo.hProcess = NULL;
382 CloseHandle (cp->procinfo.hThread);
383 cp->procinfo.hThread = NULL;
384
385 /* If this was a DOS process, indicate that it is now safe to
386 start a new one. */
387 if (cp->is_dos_process)
388 dos_process_running = FALSE;
389 }
390
391 /* For asynchronous children, the child_proc resources will be freed
392 when the last pipe read descriptor is closed; for synchronous
393 children, we must explicitly free the resources now because
394 register_child has not been called. */
395 if (cp->fd == -1)
396 delete_child (cp);
397 }
398
399 /* Wait for any of our existing child processes to die
400 When it does, close its handle
401 Return the pid and fill in the status if non-NULL. */
402
403 int
404 sys_wait (int *status)
405 {
406 DWORD active, retval;
407 int nh;
408 int pid;
409 child_process *cp, *cps[MAX_CHILDREN];
410 HANDLE wait_hnd[MAX_CHILDREN];
411
412 nh = 0;
413 if (dead_child != NULL)
414 {
415 /* We want to wait for a specific child */
416 wait_hnd[nh] = dead_child->procinfo.hProcess;
417 cps[nh] = dead_child;
418 if (!wait_hnd[nh]) abort ();
419 nh++;
420 }
421 else
422 {
423 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
424 /* some child_procs might be sockets; ignore them */
425 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
426 {
427 wait_hnd[nh] = cp->procinfo.hProcess;
428 cps[nh] = cp;
429 if (!wait_hnd[nh]) abort ();
430 nh++;
431 }
432 }
433
434 if (nh == 0)
435 {
436 /* Nothing to wait on, so fail */
437 errno = ECHILD;
438 return -1;
439 }
440
441 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, INFINITE);
442 if (active == WAIT_FAILED)
443 {
444 errno = EBADF;
445 return -1;
446 }
447 else if (active == WAIT_TIMEOUT)
448 {
449 /* Should never happen */
450 errno = EINVAL;
451 return -1;
452 }
453 else if (active >= WAIT_OBJECT_0 &&
454 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
455 {
456 active -= WAIT_OBJECT_0;
457 }
458 else if (active >= WAIT_ABANDONED_0 &&
459 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
460 {
461 active -= WAIT_ABANDONED_0;
462 }
463
464 if (!GetExitCodeProcess (wait_hnd[active], &retval))
465 {
466 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
467 GetLastError ()));
468 retval = 1;
469 }
470 if (retval == STILL_ACTIVE)
471 {
472 /* Should never happen */
473 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
474 errno = EINVAL;
475 return -1;
476 }
477
478 /* Massage the exit code from the process to match the format expected
479 by the WIFSTOPPED et al macros in syswait.h. Only WIFSIGNALED and
480 WIFEXITED are supported; WIFSTOPPED doesn't make sense under NT. */
481
482 if (retval == STATUS_CONTROL_C_EXIT)
483 retval = SIGINT;
484 else
485 retval <<= 8;
486
487 cp = cps[active];
488 pid = cp->pid;
489 #ifdef FULL_DEBUG
490 DebPrint (("Wait signaled with process pid %d\n", cp->pid));
491 #endif
492
493 if (status)
494 {
495 *status = retval;
496 }
497 else if (synch_process_alive)
498 {
499 synch_process_alive = 0;
500
501 /* Report the status of the synchronous process. */
502 if (WIFEXITED (retval))
503 synch_process_retcode = WRETCODE (retval);
504 else if (WIFSIGNALED (retval))
505 {
506 int code = WTERMSIG (retval);
507 char *signame = 0;
508
509 if (code < NSIG)
510 {
511 /* Suppress warning if the table has const char *. */
512 signame = (char *) sys_siglist[code];
513 }
514 if (signame == 0)
515 signame = "unknown";
516
517 synch_process_death = signame;
518 }
519
520 reap_subprocess (cp);
521 }
522
523 return pid;
524 }
525
526 int
527 win32_is_dos_binary (char * filename)
528 {
529 IMAGE_DOS_HEADER dos_header;
530 DWORD signature;
531 int fd;
532 int is_dos_binary = FALSE;
533
534 fd = open (filename, O_RDONLY | O_BINARY, 0);
535 if (fd >= 0)
536 {
537 char * p = strrchr (filename, '.');
538
539 /* We can only identify DOS .com programs from the extension. */
540 if (p && stricmp (p, ".com") == 0)
541 is_dos_binary = TRUE;
542 else if (p && stricmp (p, ".bat") == 0)
543 {
544 /* A DOS shell script - it appears that CreateProcess is happy
545 to accept this (somewhat surprisingly); presumably it looks
546 at COMSPEC to determine what executable to actually invoke.
547 Therefore, we have to do the same here as well. */
548 p = getenv ("COMSPEC");
549 if (p)
550 is_dos_binary = win32_is_dos_binary (p);
551 }
552 else
553 {
554 /* Look for DOS .exe signature - if found, we must also check
555 that it isn't really a 16- or 32-bit Windows exe, since
556 both formats start with a DOS program stub. Note that
557 16-bit Windows executables use the OS/2 1.x format. */
558 if (read (fd, &dos_header, sizeof (dos_header)) == sizeof (dos_header)
559 && dos_header.e_magic == IMAGE_DOS_SIGNATURE
560 && lseek (fd, dos_header.e_lfanew, SEEK_SET) != -1)
561 {
562 if (read (fd, &signature, sizeof (signature)) != sizeof (signature)
563 || (signature != IMAGE_NT_SIGNATURE &&
564 LOWORD (signature) != IMAGE_OS2_SIGNATURE))
565 is_dos_binary = TRUE;
566 }
567 }
568 close (fd);
569 }
570
571 return is_dos_binary;
572 }
573
574 /* We pass our process ID to our children by setting up an environment
575 variable in their environment. */
576 char ppid_env_var_buffer[64];
577
578 /* When a new child process is created we need to register it in our list,
579 so intercept spawn requests. */
580 int
581 sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
582 {
583 Lisp_Object program, full;
584 char *cmdline, *env, *parg, **targ;
585 int arglen;
586 int pid;
587 child_process *cp;
588 int is_dos_binary;
589
590 /* We don't care about the other modes */
591 if (mode != _P_NOWAIT)
592 {
593 errno = EINVAL;
594 return -1;
595 }
596
597 /* Handle executable names without an executable suffix. */
598 program = make_string (cmdname, strlen (cmdname));
599 if (NILP (Ffile_executable_p (program)))
600 {
601 struct gcpro gcpro1;
602
603 full = Qnil;
604 GCPRO1 (program);
605 locate_file (Vexec_path, program, EXEC_SUFFIXES, &full, 1);
606 UNGCPRO;
607 if (NILP (full))
608 {
609 errno = EINVAL;
610 return -1;
611 }
612 cmdname = XSTRING (full)->_data;
613 argv[0] = cmdname;
614 }
615
616 /* make sure cmdname is in DOS format */
617 strcpy (cmdname = alloca (strlen (cmdname) + 1), argv[0]);
618 unixtodos_filename (cmdname);
619 argv[0] = cmdname;
620
621 /* Check if program is a DOS executable, and if so whether we are
622 allowed to start it. */
623 is_dos_binary = win32_is_dos_binary (cmdname);
624 if (is_dos_binary && dos_process_running)
625 {
626 errno = EAGAIN;
627 return -1;
628 }
629
630 /* we have to do some conjuring here to put argv and envp into the
631 form CreateProcess wants... argv needs to be a space separated/null
632 terminated list of parameters, and envp is a null
633 separated/double-null terminated list of parameters.
634
635 Additionally, zero-length args and args containing whitespace need
636 to be wrapped in double quotes. Args containing embedded double
637 quotes (as opposed to enclosing quotes, which we leave alone) are
638 usually illegal (most Win32 programs do not implement escaping of
639 double quotes - sad but true, at least for programs compiled with
640 MSVC), but we will escape quotes anyway for those programs that can
641 handle it. The Win32 gcc library from Cygnus doubles quotes to
642 escape them, so we will use that convention.
643
644 Since I have no idea how large argv and envp are likely to be
645 we figure out list lengths on the fly and allocate them. */
646
647 /* do argv... */
648 arglen = 0;
649 targ = argv;
650 while (*targ)
651 {
652 char * p = *targ;
653 int add_quotes = 0;
654
655 if (*p == 0)
656 add_quotes = 1;
657 while (*p)
658 if (*p++ == '"')
659 {
660 /* allow for embedded quotes to be doubled - we won't
661 actually double quotes that aren't embedded though */
662 arglen++;
663 add_quotes = 1;
664 }
665 else if (*p == ' ' || *p == '\t')
666 add_quotes = 1;
667 if (add_quotes)
668 arglen += 2;
669 arglen += strlen (*targ++) + 1;
670 }
671 cmdline = alloca (arglen);
672 targ = argv;
673 parg = cmdline;
674 while (*targ)
675 {
676 char * p = *targ;
677 int add_quotes = 0;
678
679 if (*p == 0)
680 add_quotes = 1;
681
682 if (!NILP (Vwin32_quote_process_args))
683 {
684 /* This is conditional because it sometimes causes more
685 problems than it solves, since argv arrays are not always
686 carefully constructed. M-x grep, for instance, passes the
687 whole command line as one argument, so it becomes
688 impossible to pass a regexp which contains spaces. */
689 for ( ; *p; p++)
690 if (*p == ' ' || *p == '\t' || *p == '"')
691 add_quotes = 1;
692 }
693 if (add_quotes)
694 {
695 char * first;
696 char * last;
697
698 p = *targ;
699 first = p;
700 last = p + strlen (p) - 1;
701 *parg++ = '"';
702 while (*p)
703 {
704 if (*p == '"' && p > first && p < last)
705 *parg++ = '"'; /* double up embedded quotes only */
706 *parg++ = *p++;
707 }
708 *parg++ = '"';
709 }
710 else
711 {
712 strcpy (parg, *targ);
713 parg += strlen (*targ);
714 }
715 *parg++ = ' ';
716 targ++;
717 }
718 *--parg = '\0';
719
720 /* and envp... */
721 arglen = 1;
722 targ = envp;
723 while (*targ)
724 {
725 arglen += strlen (*targ++) + 1;
726 }
727 sprintf (ppid_env_var_buffer, "__PARENT_PROCESS_ID=%d",
728 GetCurrentProcessId ());
729 arglen += strlen (ppid_env_var_buffer) + 1;
730
731 env = alloca (arglen);
732 targ = envp;
733 parg = env;
734 while (*targ)
735 {
736 strcpy (parg, *targ);
737 parg += strlen (*targ++);
738 *parg++ = '\0';
739 }
740 strcpy (parg, ppid_env_var_buffer);
741 parg += strlen (ppid_env_var_buffer);
742 *parg++ = '\0';
743 *parg = '\0';
744
745 cp = new_child ();
746 if (cp == NULL)
747 {
748 errno = EAGAIN;
749 return -1;
750 }
751
752 /* Now create the process. */
753 if (!create_child (cmdname, cmdline, env, &pid, cp))
754 {
755 delete_child (cp);
756 errno = ENOEXEC;
757 return -1;
758 }
759
760 if (is_dos_binary)
761 {
762 cp->is_dos_process = TRUE;
763 dos_process_running = TRUE;
764 }
765
766 return pid;
767 }
768
769 /* Emulate the select call
770 Wait for available input on any of the given rfds, or timeout if
771 a timeout is given and no input is detected
772 wfds and efds are not supported and must be NULL. */
773
774 #if 0
775 /* From ntterm.c */
776 extern HANDLE keyboard_handle;
777 #endif
778 /* From process.c */
779 extern int proc_buffered_char[];
780
781 int
782 sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
783 EMACS_TIME *timeout)
784 {
785 SELECT_TYPE orfds;
786 DWORD timeout_ms;
787 int i, nh, nr;
788 DWORD active;
789 child_process *cp;
790 HANDLE wait_hnd[MAXDESC];
791 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */
792
793 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
794 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
795 {
796 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
797 return 0;
798 }
799
800 /* Otherwise, we only handle rfds, so fail otherwise. */
801 if (rfds == NULL || wfds != NULL || efds != NULL)
802 {
803 errno = EINVAL;
804 return -1;
805 }
806
807 orfds = *rfds;
808 FD_ZERO (rfds);
809 nr = 0;
810
811 /* Build a list of handles to wait on. */
812 nh = 0;
813 for (i = 0; i < nfds; i++)
814 if (FD_ISSET (i, &orfds))
815 {
816 if (i == 0)
817 {
818 #if 0
819 if (keyboard_handle)
820 {
821 /* Handle stdin specially */
822 wait_hnd[nh] = keyboard_handle;
823 fdindex[nh] = i;
824 nh++;
825 }
826 #endif
827
828 /* Check for any emacs-generated input in the queue since
829 it won't be detected in the wait */
830 if (detect_input_pending ())
831 {
832 FD_SET (i, rfds);
833 return 1;
834 }
835 }
836 else
837 {
838 /* Child process and socket input */
839 cp = fd_info[i].cp;
840 if (cp)
841 {
842 int current_status = cp->status;
843
844 if (current_status == STATUS_READ_ACKNOWLEDGED)
845 {
846 /* Tell reader thread which file handle to use. */
847 cp->fd = i;
848 /* Wake up the reader thread for this process */
849 cp->status = STATUS_READ_READY;
850 if (!SetEvent (cp->char_consumed))
851 DebPrint (("nt_select.SetEvent failed with "
852 "%lu for fd %ld\n", GetLastError (), i));
853 }
854
855 #ifdef CHECK_INTERLOCK
856 /* slightly crude cross-checking of interlock between threads */
857
858 current_status = cp->status;
859 if (WaitForSingleObject (cp->char_avail, 0) == WAIT_OBJECT_0)
860 {
861 /* char_avail has been signalled, so status (which may
862 have changed) should indicate read has completed
863 but has not been acknowledged. */
864 current_status = cp->status;
865 if (current_status != STATUS_READ_SUCCEEDED &&
866 current_status != STATUS_READ_FAILED)
867 DebPrint (("char_avail set, but read not completed: status %d\n",
868 current_status));
869 }
870 else
871 {
872 /* char_avail has not been signalled, so status should
873 indicate that read is in progress; small possibility
874 that read has completed but event wasn't yet signalled
875 when we tested it (because a context switch occurred
876 or if running on separate CPUs). */
877 if (current_status != STATUS_READ_READY &&
878 current_status != STATUS_READ_IN_PROGRESS &&
879 current_status != STATUS_READ_SUCCEEDED &&
880 current_status != STATUS_READ_FAILED)
881 DebPrint (("char_avail reset, but read status is bad: %d\n",
882 current_status));
883 }
884 #endif
885 wait_hnd[nh] = cp->char_avail;
886 fdindex[nh] = i;
887 if (!wait_hnd[nh]) abort ();
888 nh++;
889 #ifdef FULL_DEBUG
890 DebPrint (("select waiting on child %d fd %d\n",
891 cp-child_procs, i));
892 #endif
893 }
894 else
895 {
896 /* Unable to find something to wait on for this fd, skip */
897 DebPrint (("sys_select: fd %ld is invalid! ignoring\n", i));
898 abort ();
899 }
900 }
901 }
902
903 /* Nothing to look for, so we didn't find anything */
904 if (nh == 0)
905 {
906 if (timeout)
907 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
908 return 0;
909 }
910
911 /*
912 Wait for input
913 If a child process dies while this is waiting, its pipe will break
914 so the reader thread will signal an error condition, thus, the wait
915 will wake up
916 */
917 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
918
919 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms);
920
921 if (active == WAIT_FAILED)
922 {
923 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
924 nh, timeout_ms, GetLastError ()));
925 /* don't return EBADF - this causes wait_reading_process_input to
926 abort; WAIT_FAILED is returned when single-stepping under
927 Windows 95 after switching thread focus in debugger, and
928 possibly at other times. */
929 errno = EINTR;
930 return -1;
931 }
932 else if (active == WAIT_TIMEOUT)
933 {
934 return 0;
935 }
936 else if (active >= WAIT_OBJECT_0 &&
937 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
938 {
939 active -= WAIT_OBJECT_0;
940 }
941 else if (active >= WAIT_ABANDONED_0 &&
942 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
943 {
944 active -= WAIT_ABANDONED_0;
945 }
946
947 /* Loop over all handles after active (now officially documented as
948 being the first signalled handle in the array). We do this to
949 ensure fairness, so that all channels with data available will be
950 processed - otherwise higher numbered channels could be starved. */
951 do
952 {
953 if (fdindex[active] == 0)
954 {
955 /* Keyboard input available */
956 FD_SET (0, rfds);
957 nr++;
958 }
959 else
960 {
961 /* must be a socket or pipe */
962 int current_status;
963
964 cp = fd_info[ fdindex[active] ].cp;
965
966 /* Read ahead should have completed, either succeeding or failing. */
967 FD_SET (fdindex[active], rfds);
968 nr++;
969 current_status = cp->status;
970 if (current_status != STATUS_READ_SUCCEEDED)
971 {
972 if (current_status != STATUS_READ_FAILED)
973 DebPrint (("internal error: subprocess pipe signalled "
974 "at the wrong time (status %d)\n!", current_status));
975
976 /* The child_process entry for a socket or pipe will be
977 freed when the last descriptor using it is closed; for
978 pipes, we call the SIGCHLD handler. */
979 if (fd_info[ fdindex[active] ].flags & FILE_PIPE)
980 {
981 /* The SIGCHLD handler will do a Wait so we know it won't
982 return until the process is dead
983 We force Wait to only wait for this process to avoid it
984 picking up other children that happen to be dead but that
985 we haven't noticed yet
986 SIG_DFL for SIGCHLD is ignore? */
987 if (sig_handlers[SIGCHLD] != SIG_DFL &&
988 sig_handlers[SIGCHLD] != SIG_IGN)
989 {
990 #ifdef FULL_DEBUG
991 DebPrint (("select calling SIGCHLD handler for pid %d\n",
992 cp->pid));
993 #endif
994 dead_child = cp;
995 sig_handlers[SIGCHLD] (SIGCHLD);
996 dead_child = NULL;
997 }
998
999 /* Clean up the child process entry in the table */
1000 reap_subprocess (cp);
1001 }
1002 }
1003 }
1004
1005 /* Test for input on remaining channels. */
1006 while (++active < nh)
1007 if (WaitForSingleObject (wait_hnd[active], 0) == WAIT_OBJECT_0)
1008 break;
1009 } while (active < nh);
1010
1011 return nr;
1012 }
1013
1014 /* Substitute for certain kill () operations */
1015 int
1016 sys_kill (int pid, int sig)
1017 {
1018 child_process *cp;
1019 HANDLE proc_hand;
1020 int need_to_free = 0;
1021 int rc = 0;
1022
1023 /* Only handle signals that will result in the process dying */
1024 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
1025 {
1026 errno = EINVAL;
1027 return -1;
1028 }
1029
1030 cp = find_child_pid (pid);
1031 if (cp == NULL)
1032 {
1033 proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid);
1034 if (proc_hand == NULL)
1035 {
1036 errno = EPERM;
1037 return -1;
1038 }
1039 need_to_free = 1;
1040 }
1041 else
1042 {
1043 proc_hand = cp->procinfo.hProcess;
1044 pid = cp->procinfo.dwProcessId;
1045 }
1046
1047 if (sig == SIGINT)
1048 {
1049 /* Ctrl-Break is NT equivalent of SIGINT. */
1050 if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
1051 {
1052 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
1053 "for pid %lu\n", GetLastError (), pid));
1054 errno = EINVAL;
1055 rc = -1;
1056 }
1057 }
1058 else
1059 {
1060 /* Kill the process. On Win32 this doesn't kill child processes
1061 so it doesn't work very well for shells which is why it's not
1062 used in every case. Also, don't try to terminate DOS processes
1063 (on Win95), because this will hang Emacs. */
1064 if (!(cp && cp->is_dos_process)
1065 && !TerminateProcess (proc_hand, 0xff))
1066 {
1067 DebPrint (("sys_kill.TerminateProcess returned %d "
1068 "for pid %lu\n", GetLastError (), pid));
1069 errno = EINVAL;
1070 rc = -1;
1071 }
1072 }
1073
1074 if (need_to_free)
1075 CloseHandle (proc_hand);
1076
1077 return rc;
1078 }
1079
1080 #if 0
1081 extern int report_file_error (CONST char *, Lisp_Object);
1082 #endif
1083 /* The following two routines are used to manipulate stdin, stdout, and
1084 stderr of our child processes.
1085
1086 Assuming that in, out, and err are *not* inheritable, we make them
1087 stdin, stdout, and stderr of the child as follows:
1088
1089 - Save the parent's current standard handles.
1090 - Set the std handles to inheritable duplicates of the ones being passed in.
1091 (Note that _get_osfhandle() is an io.h procedure that retrieves the
1092 NT file handle for a crt file descriptor.)
1093 - Spawn the child, which inherits in, out, and err as stdin,
1094 stdout, and stderr. (see Spawnve)
1095 - Close the std handles passed to the child.
1096 - Reset the parent's standard handles to the saved handles.
1097 (see reset_standard_handles)
1098 We assume that the caller closes in, out, and err after calling us. */
1099
1100 void
1101 prepare_standard_handles (int in, int out, int err, HANDLE handles[3])
1102 {
1103 HANDLE parent;
1104 HANDLE newstdin, newstdout, newstderr;
1105
1106 parent = GetCurrentProcess ();
1107
1108 handles[0] = GetStdHandle (STD_INPUT_HANDLE);
1109 handles[1] = GetStdHandle (STD_OUTPUT_HANDLE);
1110 handles[2] = GetStdHandle (STD_ERROR_HANDLE);
1111
1112 /* make inheritable copies of the new handles */
1113 if (!DuplicateHandle (parent,
1114 (HANDLE) _get_osfhandle (in),
1115 parent,
1116 &newstdin,
1117 0,
1118 TRUE,
1119 DUPLICATE_SAME_ACCESS))
1120 report_file_error ("Duplicating input handle for child", Qnil);
1121
1122 if (!DuplicateHandle (parent,
1123 (HANDLE) _get_osfhandle (out),
1124 parent,
1125 &newstdout,
1126 0,
1127 TRUE,
1128 DUPLICATE_SAME_ACCESS))
1129 report_file_error ("Duplicating output handle for child", Qnil);
1130
1131 if (!DuplicateHandle (parent,
1132 (HANDLE) _get_osfhandle (err),
1133 parent,
1134 &newstderr,
1135 0,
1136 TRUE,
1137 DUPLICATE_SAME_ACCESS))
1138 report_file_error ("Duplicating error handle for child", Qnil);
1139
1140 /* and store them as our std handles */
1141 if (!SetStdHandle (STD_INPUT_HANDLE, newstdin))
1142 report_file_error ("Changing stdin handle", Qnil);
1143
1144 if (!SetStdHandle (STD_OUTPUT_HANDLE, newstdout))
1145 report_file_error ("Changing stdout handle", Qnil);
1146
1147 if (!SetStdHandle (STD_ERROR_HANDLE, newstderr))
1148 report_file_error ("Changing stderr handle", Qnil);
1149 }
1150
1151 void
1152 reset_standard_handles (int in, int out, int err, HANDLE handles[3])
1153 {
1154 /* close the duplicated handles passed to the child */
1155 CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
1156 CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE));
1157 CloseHandle (GetStdHandle (STD_ERROR_HANDLE));
1158
1159 /* now restore parent's saved std handles */
1160 SetStdHandle (STD_INPUT_HANDLE, handles[0]);
1161 SetStdHandle (STD_OUTPUT_HANDLE, handles[1]);
1162 SetStdHandle (STD_ERROR_HANDLE, handles[2]);
1163 }
1164
1165 #ifdef HAVE_SOCKETS
1166
1167 /* To avoid problems with winsock implementations that work over dial-up
1168 connections causing or requiring a connection to exist while Emacs is
1169 running, Emacs no longer automatically loads winsock on startup if it
1170 is present. Instead, it will be loaded when open-network-stream is
1171 first called.
1172
1173 To allow full control over when winsock is loaded, we provide these
1174 two functions to dynamically load and unload winsock. This allows
1175 dial-up users to only be connected when they actually need to use
1176 socket services. */
1177
1178 /* From nt.c */
1179 extern HANDLE winsock_lib;
1180 extern BOOL term_winsock (void);
1181 extern BOOL init_winsock (int load_now);
1182
1183 extern Lisp_Object Vsystem_name;
1184
1185 DEFUN ("win32-has-winsock", Fwin32_has_winsock, 0, 1, "", /*
1186 Test for presence of the Windows socket library `winsock'.
1187 Returns non-nil if winsock support is present, nil otherwise.
1188
1189 If the optional argument LOAD-NOW is non-nil, the winsock library is
1190 also loaded immediately if not already loaded. If winsock is loaded,
1191 the winsock local hostname is returned (since this may be different from
1192 the value of `system-name' and should supplant it), otherwise t is
1193 returned to indicate winsock support is present.
1194 */
1195 (load_now))
1196 {
1197 int have_winsock;
1198
1199 have_winsock = init_winsock (!NILP (load_now));
1200 if (have_winsock)
1201 {
1202 if (winsock_lib != NULL)
1203 {
1204 /* Return new value for system-name. The best way to do this
1205 is to call init_system_name, saving and restoring the
1206 original value to avoid side-effects. */
1207 Lisp_Object orig_hostname = Vsystem_name;
1208 Lisp_Object hostname;
1209
1210 init_system_name ();
1211 hostname = Vsystem_name;
1212 Vsystem_name = orig_hostname;
1213 return hostname;
1214 }
1215 return Qt;
1216 }
1217 return Qnil;
1218 }
1219
1220 DEFUN ("win32-unload-winsock", Fwin32_unload_winsock, 0, 0, "", /*
1221 Unload the Windows socket library `winsock' if loaded.
1222 This is provided to allow dial-up socket connections to be disconnected
1223 when no longer needed. Returns nil without unloading winsock if any
1224 socket connections still exist.
1225 */
1226 ())
1227 {
1228 return term_winsock () ? Qt : Qnil;
1229 }
1230
1231 #endif /* HAVE_SOCKETS */
1232
1233
1234 syms_of_ntproc ()
1235 {
1236 #ifdef HAVE_SOCKETS
1237 DEFSUBR (Fwin32_has_winsock);
1238 DEFSUBR (Fwin32_unload_winsock);
1239 #endif
1240
1241 DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /*
1242 Non-nil enables quoting of process arguments to ensure correct parsing.
1243 Because Windows does not directly pass argv arrays to child processes,
1244 programs have to reconstruct the argv array by parsing the command
1245 line string. For an argument to contain a space, it must be enclosed
1246 in double quotes or it will be parsed as multiple arguments.
1247
1248 However, the argument list to call-process is not always correctly
1249 constructed (or arguments have already been quoted), so enabling this
1250 option may cause unexpected behavior.*/ );
1251 Vwin32_quote_process_args = Qnil;
1252
1253 DEFVAR_INT ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /*
1254 Forced delay before reading subprocess output.
1255 This is done to improve the buffering of subprocess output, by
1256 avoiding the inefficiency of frequently reading small amounts of data.
1257
1258 If positive, the value is the number of milliseconds to sleep before
1259 reading the subprocess output. If negative, the magnitude is the number
1260 of time slices to wait (effectively boosting the priority of the child
1261 process temporarily). A value of zero disables waiting entirely.*/ );
1262 Vwin32_pipe_read_delay = 50;
1263
1264 DEFVAR_LISP ("win32-downcase-file-names", &Vwin32_downcase_file_names /*
1265 Non-nil means convert all-upper case file names to lower case.
1266 This applies when performing completions and file name expansion.*/ );
1267 Vwin32_downcase_file_names = Qnil;
1268 }
1269 /* end of ntproc.c */