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