(VALBITS, GCTYPEBITS): Deleted; default is better.
[bpt/emacs.git] / src / w32proc.c
CommitLineData
6cdfb6e6
RS
1/* Process support for Windows NT port of GNU EMACS.
2 Copyright (C) 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs 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 later
9 version.
10
11 GNU Emacs 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 for
14 more details.
15
16 You should have received a copy of the GNU General Public License along
17 with GNU Emacs; see the file COPYING. If not, write to the Free Software
18 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 Drew Bliss Oct 14, 1993
21 Adapted from alarm.c by Tim Fleehart
22*/
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <io.h>
28#include <signal.h>
29
30#include "config.h"
31
32#include <windows.h>
33
34#include "lisp.h"
35#include "nt.h"
36#include "systime.h"
37
38/* #define FULL_DEBUG */
39
40typedef void (_CALLBACK_ *signal_handler)(int);
41
42/* Defined in process.h which conflicts with the local copy */
43#define _P_NOWAIT 1
44
45typedef struct _child_process
46{
47 int fd;
48 HANDLE char_avail;
49 HANDLE char_consumed;
50 char chr;
51 BOOL status;
52 HANDLE process;
53 DWORD pid;
54 HANDLE thrd;
55} child_process;
56
57#define MAX_CHILDREN MAXDESC
58
59#ifdef EMACSDEBUG
60void _CRTAPI1
61_DebPrint (char *fmt, ...)
62{
63 char buf[256];
64 va_list args;
65
66 va_start (args, fmt);
67 vsprintf (buf, fmt, args);
68 va_end (args);
69 OutputDebugString (buf);
70}
71#endif
72
73/* Child process management list. */
74static int child_proc_count = 0;
75static child_process child_procs[MAX_CHILDREN];
76static child_process *dead_child = NULL;
77
78#define CHILD_ACTIVE(cp) ((cp)->process != NULL)
79#define DEACTIVATE_CHILD(cp) ((cp)->process = NULL)
80
81/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
82static signal_handler sig_handlers[NSIG];
83
84/* Fake signal implementation to record the SIGCHLD handler. */
85signal_handler
86win32_signal (int sig, signal_handler handler)
87{
88 signal_handler old;
89
90 if (sig != SIGCHLD)
91 {
92 errno = EINVAL;
93 return SIG_ERR;
94 }
95 old = sig_handlers[sig];
96 sig_handlers[sig] = handler;
97 return old;
98}
99
100/* Find an unused process slot. */
101static child_process *
102new_child (void)
103{
104 child_process *cp;
105
106 if (child_proc_count == MAX_CHILDREN)
107 return NULL;
108
109 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
110 if (!CHILD_ACTIVE (cp))
111 return cp;
112 return &child_procs[child_proc_count++];
113}
114
115/* Find a child by pid. */
116static child_process *
117find_child_pid (DWORD pid)
118{
119 child_process *cp;
120
121 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
122 if (CHILD_ACTIVE (cp) && pid == cp->pid)
123 return cp;
124 return NULL;
125}
126
127/* Find a child by fd. */
128static child_process *
129find_child_fd (int fd)
130{
131 child_process *cp;
132
133 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
134 if (CHILD_ACTIVE (cp) && fd == cp->fd)
135 return cp;
136 return NULL;
137}
138
139/* Thread proc for child process reader threads
140 The threads just sit in a loop waiting for input
141 When they detect input, they signal the char_avail input to
142 wake up the select emulator
143 When the select emulator processes their input, it pulses
144 char_consumed so that the reader thread goes back to reading. */
145DWORD WINAPI
146reader_thread (void *arg)
147{
148 child_process *cp;
149
150 /* Our identity */
151 cp = (child_process *)arg;
152
153 /* We have to wait for the go-ahead before we can start */
154 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
155 return 0;
156 /* If something went wrong, quit */
157 if (!cp->status)
158 return 0;
159
160 for (;;)
161 {
162 /* Use read to get CRLF translation */
163 if (read (cp->fd, &cp->chr, sizeof (char)) == sizeof (char))
164 {
165 cp->status = TRUE;
166 }
167 else
168 {
169#ifdef FULL_DEBUG
170 DebPrint (("reader_thread.read failed with %lu for fd %ld\n",
171 GetLastError (), cp->fd));
172#endif
173 cp->status = FALSE;
174 }
175
176 if (!SetEvent (cp->char_avail))
177 {
178 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
179 GetLastError (), cp->fd));
180 break;
181 }
182
183 /* If the read died, the child has died so let the thread die */
184 if (!cp->status)
185 break;
186
187 /* Wait until our input is acknowledged before reading again */
188 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
189 {
190 DebPrint (("reader_thread.WaitForSingleObject failed with "
191 "%lu for fd %ld\n", GetLastError (), cp->fd));
192 break;
193 }
194 }
195 return 0;
196}
197
198static BOOL
199create_child (char *exe, char *cmdline, char *env,
200 PROCESS_INFORMATION *info)
201{
202 child_process *cp;
203 DWORD id;
204 STARTUPINFO start;
205 SECURITY_ATTRIBUTES sec_attrs;
206 SECURITY_DESCRIPTOR sec_desc;
207
208 cp = new_child ();
209 if (cp == NULL)
210 goto EH_Fail;
211
212 cp->fd = -1;
213
214 cp->char_avail = CreateEvent (NULL, FALSE, FALSE, NULL);
215 if (cp->char_avail == NULL)
216 goto EH_Fail;
217
218 cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
219 if (cp->char_consumed == NULL)
220 goto EH_char_avail;
221
222 cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
223 if (cp->thrd == NULL)
224 goto EH_char_consumed;
225
226 memset (&start, 0, sizeof (start));
227 start.cb = sizeof (start);
228
229 /* Explicitly specify no security */
230 if (!InitializeSecurityDescriptor (&sec_desc, SECURITY_DESCRIPTOR_REVISION))
231 goto EH_thrd;
232 if (!SetSecurityDescriptorDacl (&sec_desc, TRUE, NULL, FALSE))
233 goto EH_thrd;
234 sec_attrs.nLength = sizeof (sec_attrs);
235 sec_attrs.lpSecurityDescriptor = &sec_desc;
236 sec_attrs.bInheritHandle = FALSE;
237
238 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
239 CREATE_NEW_PROCESS_GROUP, env, NULL,
240 &start, info))
241 goto EH_thrd;
242 cp->process = info->hProcess;
243 cp->pid = info->dwProcessId;
244
245 return TRUE;
246
247 EH_thrd:
248 id = GetLastError ();
249
250 cp->status = FALSE;
251 SetEvent (cp->char_consumed);
252 EH_char_consumed:
253 CloseHandle (cp->char_consumed);
254 EH_char_avail:
255 CloseHandle (cp->char_avail);
256 EH_Fail:
257 return FALSE;
258}
259
260/* create_child doesn't know what emacs' file handle will be for waiting
261 on output from the child, so we need to make this additional call
262 to register the handle with the process
263 This way the select emulator knows how to match file handles with
264 entries in child_procs. */
265void
266register_child (int pid, int fd)
267{
268 child_process *cp;
269
270 cp = find_child_pid (pid);
271 if (cp == NULL)
272 {
273 DebPrint (("register_child unable to find pid %lu\n", pid));
274 return;
275 }
276
277#ifdef FULL_DEBUG
278 DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid));
279#endif
280
281 cp->fd = fd;
282 cp->status = TRUE;
283
284 /* Tell the reader thread to start */
285 if (!SetEvent (cp->char_consumed))
286 {
287 DebPrint (("register_child.SetEvent failed with %lu for fd %ld\n",
288 GetLastError (), cp->fd));
289 }
290}
291
292/* When a process dies its pipe will break so the reader thread will
293 signal failure to the select emulator.
294 The select emulator then calls this routine to clean up.
295 Since the thread signaled failure we can assume it is exiting. */
296static void
297remove_child (child_process *cp)
298{
299 /* Reap the thread */
300 if (WaitForSingleObject (cp->thrd, INFINITE) != WAIT_OBJECT_0)
301 {
302 DebPrint (("remove_child.WaitForSingleObject (thread) failed "
303 "with %lu for fd %ld\n", GetLastError (), cp->fd));
304 }
305 CloseHandle (cp->thrd);
306 CloseHandle (cp->char_consumed);
307 CloseHandle (cp->char_avail);
308
309 /* Reap the process */
310 if (WaitForSingleObject (cp->process, INFINITE) != WAIT_OBJECT_0)
311 {
312 DebPrint (("remove_child.WaitForSingleObject (process) failed "
313 "with %lu for fd %ld\n", GetLastError (), cp->fd));
314 }
315 CloseHandle (cp->process);
316
317 DEACTIVATE_CHILD (cp);
318}
319
320/* Wait for any of our existing child processes to die
321 When it does, close its handle
322 Return the pid and fill in the status if non-NULL. */
323int
324win32_wait (int *status)
325{
326 DWORD active, retval;
327 int nh;
328 child_process *cp, *cps[MAX_CHILDREN];
329 HANDLE wait_hnd[MAX_CHILDREN];
330
331 nh = 0;
332 if (dead_child != NULL)
333 {
334 /* We want to wait for a specific child */
335 wait_hnd[nh] = dead_child->process;
336 cps[nh] = dead_child;
337 nh++;
338 }
339 else
340 {
341 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
342 if (CHILD_ACTIVE (cp))
343 {
344 wait_hnd[nh] = cp->process;
345 cps[nh] = cp;
346 nh++;
347 }
348 }
349
350 if (nh == 0)
351 {
352 /* Nothing to wait on, so fail */
353 errno = ECHILD;
354 return -1;
355 }
356
357 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, INFINITE);
358 if (active == WAIT_FAILED)
359 {
360 errno = EBADF;
361 return -1;
362 }
363 else if (active == WAIT_TIMEOUT)
364 {
365 /* Should never happen */
366 errno = EINVAL;
367 return -1;
368 }
369 else if (active >= WAIT_OBJECT_0 &&
370 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
371 {
372 active -= WAIT_OBJECT_0;
373 }
374 else if (active >= WAIT_ABANDONED_0 &&
375 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
376 {
377 active -= WAIT_ABANDONED_0;
378 }
379
380 if (!GetExitCodeProcess (wait_hnd[active], &retval))
381 {
382 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
383 GetLastError ()));
384 retval = 1;
385 }
386 if (retval == STILL_ACTIVE)
387 {
388 /* Should never happen */
389 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
390 errno = EINVAL;
391 return -1;
392 }
393
394 cp = cps[active];
395#ifdef FULL_DEBUG
396 DebPrint (("Wait signaled with process pid %d\n", cp->pid));
397#endif
398
399 if (status)
400 {
401 /* In process.c the default WAITTYPE is defined.
402 Since we can't determine anything about why a process died
403 we can only return a code that looks like WIFEXITED */
404 *status = (retval & 0x7fffff) << 8;
405 }
406
407 return cp->pid;
408}
409
410/* We pass our process ID to our children by setting up an environment
411 variable in their environment. */
412char ppid_env_var_buffer[64];
413
414/* When a new child process is created we need to register it in our list,
415 so intercept spawn requests. */
416int
417win32_spawnve (int mode, char *cmdname, char **argv, char **envp)
418{
419 char *cmdline, *env, *parg, **targ;
420 int arglen;
421 PROCESS_INFORMATION pi;
422
423 if (child_proc_count == MAX_CHILDREN)
424 {
425 errno = EAGAIN;
426 return -1;
427 }
428
429 /* We don't care about the other modes */
430 if (mode != _P_NOWAIT)
431 {
432 errno = EINVAL;
433 return -1;
434 }
435
436 /* we have to do some conjuring here to put argv and envp into the
437 form CreateProcess wants... argv needs to be a space separated/null
438 terminated list of parameters, and envp is a null
439 separated/double-null terminated list of parameters.
440
441 Since I have no idea how large argv and envp are likely to be
442 we figure out list lengths on the fly and allocate them. */
443
444 /* do argv... */
445 arglen = 0;
446 targ = argv;
447 while (*targ)
448 {
449 arglen += strlen (*targ++) + 1;
450 }
451 cmdline = malloc (arglen);
452 if (cmdline == NULL)
453 {
454 errno = ENOMEM;
455 goto EH_Fail;
456 }
457 targ = argv;
458 parg = cmdline;
459 while (*targ)
460 {
461 strcpy (parg, *targ);
462 parg += strlen (*targ++);
463 *parg++ = ' ';
464 }
465 *--parg = '\0';
466
467 /* and envp... */
468 arglen = 1;
469 targ = envp;
470 while (*targ)
471 {
472 arglen += strlen (*targ++) + 1;
473 }
474 sprintf (ppid_env_var_buffer, "__PARENT_PROCESS_ID=%d",
475 GetCurrentProcessId ());
476 arglen += strlen (ppid_env_var_buffer) + 1;
477
478 env = malloc (arglen);
479 if (env == NULL)
480 {
481 errno = ENOMEM;
482 goto EH_cmdline;
483 }
484 targ = envp;
485 parg = env;
486 while (*targ)
487 {
488 strcpy (parg, *targ);
489 parg += strlen (*targ++);
490 *parg++ = '\0';
491 }
492 strcpy (parg, ppid_env_var_buffer);
493 parg += strlen (ppid_env_var_buffer);
494 *parg++ = '\0';
495 *parg = '\0';
496
497 /* Now create the process. */
498 if (!create_child (cmdname, cmdline, env, &pi))
499 {
500 errno = ENOEXEC;
501 goto EH_env;
502 }
503
504 return pi.dwProcessId;
505
506 EH_env:
507 free (env);
508 EH_cmdline:
509 free (cmdline);
510 EH_Fail:
511 return -1;
512}
513
514/* Emulate the select call
515 Wait for available input on any of the given rfds, or timeout if
516 a timeout is given and no input is detected
517 wfds and efds are not supported and must be NULL. */
518
519/* From ntterm.c */
520extern HANDLE keyboard_handle;
521/* From process.c */
522extern int proc_buffered_char[];
523
524int
525select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
526 EMACS_TIME *timeout)
527{
528 SELECT_TYPE orfds;
529 DWORD timeout_ms;
530 int i, nh, nr;
531 DWORD active;
532 child_process *cp, *cps[MAX_CHILDREN];
533 HANDLE wait_hnd[MAX_CHILDREN];
534
535 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
536 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
537 {
538 Sleep ((*timeout) * 1000);
539 return 0;
540 }
541
542 /* Otherwise, we only handle rfds, so fail otherwise. */
543 if (rfds == NULL || wfds != NULL || efds != NULL)
544 {
545 errno = EINVAL;
546 return -1;
547 }
548
549 orfds = *rfds;
550 FD_ZERO (rfds);
551 nr = 0;
552
553 /* Build a list of handles to wait on. */
554 nh = 0;
555 for (i = 0; i < nfds; i++)
556 if (FD_ISSET (i, &orfds))
557 {
558 if (i == 0)
559 {
560 /* Handle stdin specially */
561 wait_hnd[nh] = keyboard_handle;
562 cps[nh] = NULL;
563 nh++;
564
565 /* Check for any emacs-generated input in the queue since
566 it won't be detected in the wait */
567 if (detect_input_pending ())
568 {
569 FD_SET (i, rfds);
570 nr++;
571 }
572 }
573 else
574 {
575 /* Child process input */
576 cp = find_child_fd (i);
577 if (cp)
578 {
579#ifdef FULL_DEBUG
580 DebPrint (("select waiting on child %d fd %d\n",
581 cp-child_procs, i));
582#endif
583 wait_hnd[nh] = cp->char_avail;
584 cps[nh] = cp;
585 nh++;
586 }
587 else
588 {
589 /* Unable to find something to wait on for this fd, fail */
590 DebPrint (("select unable to find child process "
591 "for fd %ld\n", i));
592 nh = 0;
593 break;
594 }
595 }
596 }
597
598 /* Nothing to look for, so we didn't find anything */
599 if (nh == 0)
600 {
601 Sleep ((*timeout) * 1000);
602 return 0;
603 }
604
605 /* Check for immediate return without waiting */
606 if (nr > 0)
607 return nr;
608
609 /*
610 Wait for input
611 If a child process dies while this is waiting, its pipe will break
612 so the reader thread will signal an error condition, thus, the wait
613 will wake up
614 */
615 timeout_ms = timeout ? *timeout*1000 : INFINITE;
616 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms);
617 if (active == WAIT_FAILED)
618 {
619 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
620 nh, timeout_ms, GetLastError ()));
621 /* Is there a better error? */
622 errno = EBADF;
623 return -1;
624 }
625 else if (active == WAIT_TIMEOUT)
626 {
627 return 0;
628 }
629 else if (active >= WAIT_OBJECT_0 &&
630 active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
631 {
632 active -= WAIT_OBJECT_0;
633 }
634 else if (active >= WAIT_ABANDONED_0 &&
635 active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
636 {
637 active -= WAIT_ABANDONED_0;
638 }
639
640 if (cps[active] == NULL)
641 {
642 /* Keyboard input available */
643 FD_SET (0, rfds);
644 nr++;
645
646 /* This shouldn't be necessary, but apparently just setting the input
647 fd is not good enough for emacs */
648 read_input_waiting ();
649 }
650 else
651 {
652 /* Child process */
653 cp = cps[active];
654
655 /* If status is FALSE the read failed so don't report input */
656 if (cp->status)
657 {
658 FD_SET (cp->fd, rfds);
659 proc_buffered_char[cp->fd] = cp->chr;
660 nr++;
661 }
662 else
663 {
664 /* The SIGCHLD handler will do a Wait so we know it won't
665 return until the process is dead
666 We force Wait to only wait for this process to avoid it
667 picking up other children that happen to be dead but that
668 we haven't noticed yet
669 SIG_DFL for SIGCHLD is ignore? */
670 if (sig_handlers[SIGCHLD] != SIG_DFL &&
671 sig_handlers[SIGCHLD] != SIG_IGN)
672 {
673#ifdef FULL_DEBUG
674 DebPrint (("select calling SIGCHLD handler for pid %d\n",
675 cp->pid));
676#endif
677 dead_child = cp;
678 sig_handlers[SIGCHLD](SIGCHLD);
679 dead_child = NULL;
680 }
681
682 /* Clean up the child process entry in the table */
683 remove_child (cp);
684 }
685 }
686 return nr;
687}
688
689/*
690 Substitute for certain kill () operations
691 */
692int
693win32_kill_process (int pid, int sig)
694{
695 child_process *cp;
696
697 /* Only handle signals that will result in the process dying */
698 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
699 {
700 errno = EINVAL;
701 return -1;
702 }
703
704 cp = find_child_pid (pid);
705 if (cp == NULL)
706 {
707 DebPrint (("win32_kill_process didn't find a child with pid %lu\n", pid));
708 errno = ECHILD;
709 return -1;
710 }
711
712 if (sig == SIGINT)
713 {
714 /* Fake Ctrl-Break. */
715 if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
716 {
717 DebPrint (("win32_kill_process.GenerateConsoleCtrlEvent return %d "
718 "for pid %lu\n", GetLastError (), pid));
719 errno = EINVAL;
720 return -1;
721 }
722 }
723 else
724 {
725 /* Kill the process. On Win32 this doesn't kill child processes
726 so it doesn't work very well for shells which is why it's
727 not used in every case. */
728 if (!TerminateProcess (cp->process, 0xff))
729 {
730 DebPrint (("win32_kill_process.TerminateProcess returned %d "
731 "for pid %lu\n", GetLastError (), pid));
732 errno = EINVAL;
733 return -1;
734 }
735 }
736 return 0;
737}
738
739/* If the channel is a pipe this read might block since we don't
740 know how many characters are available, so check and read only
741 what's there
742 We also need to wake up the reader thread once we've read our data. */
743int
744read_child_output (int fd, char *buf, int max)
745{
746 HANDLE h;
747 int to_read, nchars;
748 DWORD waiting;
749 child_process *cp;
750
751 h = (HANDLE)_get_osfhandle (fd);
752 if (GetFileType (h) == FILE_TYPE_PIPE)
753 {
754 PeekNamedPipe (h, NULL, 0, NULL, &waiting, NULL);
755 to_read = min (waiting, (DWORD)max);
756 }
757 else
758 to_read = max;
759
760 /* Use read to get CRLF translation */
761 nchars = read (fd, buf, to_read);
762
763 if (GetFileType (h) == FILE_TYPE_PIPE)
764 {
765 /* Wake up the reader thread
766 for this process */
767 cp = find_child_fd (fd);
768 if (cp)
769 {
770 if (!SetEvent (cp->char_consumed))
771 DebPrint (("read_child_output.SetEvent failed with "
772 "%lu for fd %ld\n", GetLastError (), fd));
773 }
774 else
775 DebPrint (("read_child_output couldn't find a child with fd %d\n",
776 fd));
777 }
778
779 return nchars;
780}