1 /* Process support for Windows NT port of GNU EMACS.
2 Copyright (C) 1992 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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
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
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.
20 Drew Bliss Oct 14, 1993
21 Adapted from alarm.c by Tim Fleehart
38 /* #define FULL_DEBUG */
40 typedef void (_CALLBACK_
*signal_handler
)(int);
42 /* Defined in process.h which conflicts with the local copy */
45 typedef struct _child_process
57 #define MAX_CHILDREN MAXDESC
61 _DebPrint (char *fmt
, ...)
67 vsprintf (buf
, fmt
, args
);
69 OutputDebugString (buf
);
73 /* Child process management list. */
74 static int child_proc_count
= 0;
75 static child_process child_procs
[MAX_CHILDREN
];
76 static child_process
*dead_child
= NULL
;
78 #define CHILD_ACTIVE(cp) ((cp)->process != NULL)
79 #define DEACTIVATE_CHILD(cp) ((cp)->process = NULL)
81 /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
82 static signal_handler sig_handlers
[NSIG
];
84 /* Fake signal implementation to record the SIGCHLD handler. */
86 win32_signal (int sig
, signal_handler handler
)
95 old
= sig_handlers
[sig
];
96 sig_handlers
[sig
] = handler
;
100 /* Find an unused process slot. */
101 static child_process
*
106 if (child_proc_count
== MAX_CHILDREN
)
109 for (cp
= child_procs
+(child_proc_count
-1); cp
>= child_procs
; cp
--)
110 if (!CHILD_ACTIVE (cp
))
112 return &child_procs
[child_proc_count
++];
115 /* Find a child by pid. */
116 static child_process
*
117 find_child_pid (DWORD pid
)
121 for (cp
= child_procs
+(child_proc_count
-1); cp
>= child_procs
; cp
--)
122 if (CHILD_ACTIVE (cp
) && pid
== cp
->pid
)
127 /* Find a child by fd. */
128 static child_process
*
129 find_child_fd (int fd
)
133 for (cp
= child_procs
+(child_proc_count
-1); cp
>= child_procs
; cp
--)
134 if (CHILD_ACTIVE (cp
) && fd
== cp
->fd
)
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. */
146 reader_thread (void *arg
)
151 cp
= (child_process
*)arg
;
153 /* We have to wait for the go-ahead before we can start */
154 if (WaitForSingleObject (cp
->char_consumed
, INFINITE
) != WAIT_OBJECT_0
)
156 /* If something went wrong, quit */
162 /* Use read to get CRLF translation */
163 if (read (cp
->fd
, &cp
->chr
, sizeof (char)) == sizeof (char))
170 DebPrint (("reader_thread.read failed with %lu for fd %ld\n",
171 GetLastError (), cp
->fd
));
176 if (!SetEvent (cp
->char_avail
))
178 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
179 GetLastError (), cp
->fd
));
183 /* If the read died, the child has died so let the thread die */
187 /* Wait until our input is acknowledged before reading again */
188 if (WaitForSingleObject (cp
->char_consumed
, INFINITE
) != WAIT_OBJECT_0
)
190 DebPrint (("reader_thread.WaitForSingleObject failed with "
191 "%lu for fd %ld\n", GetLastError (), cp
->fd
));
199 create_child (char *exe
, char *cmdline
, char *env
,
200 PROCESS_INFORMATION
*info
)
205 SECURITY_ATTRIBUTES sec_attrs
;
206 SECURITY_DESCRIPTOR sec_desc
;
214 cp
->char_avail
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
215 if (cp
->char_avail
== NULL
)
218 cp
->char_consumed
= CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
219 if (cp
->char_consumed
== NULL
)
222 cp
->thrd
= CreateThread (NULL
, 1024, reader_thread
, cp
, 0, &id
);
223 if (cp
->thrd
== NULL
)
224 goto EH_char_consumed
;
226 memset (&start
, 0, sizeof (start
));
227 start
.cb
= sizeof (start
);
229 /* Explicitly specify no security */
230 if (!InitializeSecurityDescriptor (&sec_desc
, SECURITY_DESCRIPTOR_REVISION
))
232 if (!SetSecurityDescriptorDacl (&sec_desc
, TRUE
, NULL
, FALSE
))
234 sec_attrs
.nLength
= sizeof (sec_attrs
);
235 sec_attrs
.lpSecurityDescriptor
= &sec_desc
;
236 sec_attrs
.bInheritHandle
= FALSE
;
238 if (!CreateProcess (exe
, cmdline
, &sec_attrs
, NULL
, TRUE
,
239 CREATE_NEW_PROCESS_GROUP
, env
, NULL
,
242 cp
->process
= info
->hProcess
;
243 cp
->pid
= info
->dwProcessId
;
248 id
= GetLastError ();
251 SetEvent (cp
->char_consumed
);
253 CloseHandle (cp
->char_consumed
);
255 CloseHandle (cp
->char_avail
);
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. */
266 register_child (int pid
, int fd
)
270 cp
= find_child_pid (pid
);
273 DebPrint (("register_child unable to find pid %lu\n", pid
));
278 DebPrint (("register_child registered fd %d with pid %lu\n", fd
, pid
));
284 /* Tell the reader thread to start */
285 if (!SetEvent (cp
->char_consumed
))
287 DebPrint (("register_child.SetEvent failed with %lu for fd %ld\n",
288 GetLastError (), cp
->fd
));
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. */
297 remove_child (child_process
*cp
)
299 /* Reap the thread */
300 if (WaitForSingleObject (cp
->thrd
, INFINITE
) != WAIT_OBJECT_0
)
302 DebPrint (("remove_child.WaitForSingleObject (thread) failed "
303 "with %lu for fd %ld\n", GetLastError (), cp
->fd
));
305 CloseHandle (cp
->thrd
);
306 CloseHandle (cp
->char_consumed
);
307 CloseHandle (cp
->char_avail
);
309 /* Reap the process */
310 if (WaitForSingleObject (cp
->process
, INFINITE
) != WAIT_OBJECT_0
)
312 DebPrint (("remove_child.WaitForSingleObject (process) failed "
313 "with %lu for fd %ld\n", GetLastError (), cp
->fd
));
315 CloseHandle (cp
->process
);
317 DEACTIVATE_CHILD (cp
);
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. */
324 win32_wait (int *status
)
326 DWORD active
, retval
;
328 child_process
*cp
, *cps
[MAX_CHILDREN
];
329 HANDLE wait_hnd
[MAX_CHILDREN
];
332 if (dead_child
!= NULL
)
334 /* We want to wait for a specific child */
335 wait_hnd
[nh
] = dead_child
->process
;
336 cps
[nh
] = dead_child
;
341 for (cp
= child_procs
+(child_proc_count
-1); cp
>= child_procs
; cp
--)
342 if (CHILD_ACTIVE (cp
))
344 wait_hnd
[nh
] = cp
->process
;
352 /* Nothing to wait on, so fail */
357 active
= WaitForMultipleObjects (nh
, wait_hnd
, FALSE
, INFINITE
);
358 if (active
== WAIT_FAILED
)
363 else if (active
== WAIT_TIMEOUT
)
365 /* Should never happen */
369 else if (active
>= WAIT_OBJECT_0
&&
370 active
< WAIT_OBJECT_0
+MAXIMUM_WAIT_OBJECTS
)
372 active
-= WAIT_OBJECT_0
;
374 else if (active
>= WAIT_ABANDONED_0
&&
375 active
< WAIT_ABANDONED_0
+MAXIMUM_WAIT_OBJECTS
)
377 active
-= WAIT_ABANDONED_0
;
380 if (!GetExitCodeProcess (wait_hnd
[active
], &retval
))
382 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
386 if (retval
== STILL_ACTIVE
)
388 /* Should never happen */
389 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
396 DebPrint (("Wait signaled with process pid %d\n", cp
->pid
));
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;
410 /* We pass our process ID to our children by setting up an environment
411 variable in their environment. */
412 char ppid_env_var_buffer
[64];
414 /* When a new child process is created we need to register it in our list,
415 so intercept spawn requests. */
417 win32_spawnve (int mode
, char *cmdname
, char **argv
, char **envp
)
419 char *cmdline
, *env
, *parg
, **targ
;
421 PROCESS_INFORMATION pi
;
423 if (child_proc_count
== MAX_CHILDREN
)
429 /* We don't care about the other modes */
430 if (mode
!= _P_NOWAIT
)
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.
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. */
449 arglen
+= strlen (*targ
++) + 1;
451 cmdline
= malloc (arglen
);
461 strcpy (parg
, *targ
);
462 parg
+= strlen (*targ
++);
472 arglen
+= strlen (*targ
++) + 1;
474 sprintf (ppid_env_var_buffer
, "__PARENT_PROCESS_ID=%d",
475 GetCurrentProcessId ());
476 arglen
+= strlen (ppid_env_var_buffer
) + 1;
478 env
= malloc (arglen
);
488 strcpy (parg
, *targ
);
489 parg
+= strlen (*targ
++);
492 strcpy (parg
, ppid_env_var_buffer
);
493 parg
+= strlen (ppid_env_var_buffer
);
497 /* Now create the process. */
498 if (!create_child (cmdname
, cmdline
, env
, &pi
))
504 return pi
.dwProcessId
;
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. */
520 extern HANDLE keyboard_handle
;
522 extern int proc_buffered_char
[];
525 select (int nfds
, SELECT_TYPE
*rfds
, SELECT_TYPE
*wfds
, SELECT_TYPE
*efds
,
532 child_process
*cp
, *cps
[MAX_CHILDREN
];
533 HANDLE wait_hnd
[MAX_CHILDREN
];
535 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
536 if (rfds
== NULL
&& wfds
== NULL
&& efds
== NULL
&& timeout
!= NULL
)
538 Sleep ((*timeout
) * 1000);
542 /* Otherwise, we only handle rfds, so fail otherwise. */
543 if (rfds
== NULL
|| wfds
!= NULL
|| efds
!= NULL
)
553 /* Build a list of handles to wait on. */
555 for (i
= 0; i
< nfds
; i
++)
556 if (FD_ISSET (i
, &orfds
))
560 /* Handle stdin specially */
561 wait_hnd
[nh
] = keyboard_handle
;
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 ())
575 /* Child process input */
576 cp
= find_child_fd (i
);
580 DebPrint (("select waiting on child %d fd %d\n",
583 wait_hnd
[nh
] = cp
->char_avail
;
589 /* Unable to find something to wait on for this fd, fail */
590 DebPrint (("select unable to find child process "
598 /* Nothing to look for, so we didn't find anything */
601 Sleep ((*timeout
) * 1000);
605 /* Check for immediate return without waiting */
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
615 timeout_ms
= timeout
? *timeout
*1000 : INFINITE
;
616 active
= WaitForMultipleObjects (nh
, wait_hnd
, FALSE
, timeout_ms
);
617 if (active
== WAIT_FAILED
)
619 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
620 nh
, timeout_ms
, GetLastError ()));
621 /* Is there a better error? */
625 else if (active
== WAIT_TIMEOUT
)
629 else if (active
>= WAIT_OBJECT_0
&&
630 active
< WAIT_OBJECT_0
+MAXIMUM_WAIT_OBJECTS
)
632 active
-= WAIT_OBJECT_0
;
634 else if (active
>= WAIT_ABANDONED_0
&&
635 active
< WAIT_ABANDONED_0
+MAXIMUM_WAIT_OBJECTS
)
637 active
-= WAIT_ABANDONED_0
;
640 if (cps
[active
] == NULL
)
642 /* Keyboard input available */
646 /* This shouldn't be necessary, but apparently just setting the input
647 fd is not good enough for emacs */
648 read_input_waiting ();
655 /* If status is FALSE the read failed so don't report input */
658 FD_SET (cp
->fd
, rfds
);
659 proc_buffered_char
[cp
->fd
] = cp
->chr
;
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
)
674 DebPrint (("select calling SIGCHLD handler for pid %d\n",
678 sig_handlers
[SIGCHLD
](SIGCHLD
);
682 /* Clean up the child process entry in the table */
690 Substitute for certain kill () operations
693 win32_kill_process (int pid
, int sig
)
697 /* Only handle signals that will result in the process dying */
698 if (sig
!= SIGINT
&& sig
!= SIGKILL
&& sig
!= SIGQUIT
&& sig
!= SIGHUP
)
704 cp
= find_child_pid (pid
);
707 DebPrint (("win32_kill_process didn't find a child with pid %lu\n", pid
));
714 /* Fake Ctrl-Break. */
715 if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, pid
))
717 DebPrint (("win32_kill_process.GenerateConsoleCtrlEvent return %d "
718 "for pid %lu\n", GetLastError (), pid
));
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))
730 DebPrint (("win32_kill_process.TerminateProcess returned %d "
731 "for pid %lu\n", GetLastError (), pid
));
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
742 We also need to wake up the reader thread once we've read our data. */
744 read_child_output (int fd
, char *buf
, int max
)
751 h
= (HANDLE
)_get_osfhandle (fd
);
752 if (GetFileType (h
) == FILE_TYPE_PIPE
)
754 PeekNamedPipe (h
, NULL
, 0, NULL
, &waiting
, NULL
);
755 to_read
= min (waiting
, (DWORD
)max
);
760 /* Use read to get CRLF translation */
761 nchars
= read (fd
, buf
, to_read
);
763 if (GetFileType (h
) == FILE_TYPE_PIPE
)
765 /* Wake up the reader thread
767 cp
= find_child_fd (fd
);
770 if (!SetEvent (cp
->char_consumed
))
771 DebPrint (("read_child_output.SetEvent failed with "
772 "%lu for fd %ld\n", GetLastError (), fd
));
775 DebPrint (("read_child_output couldn't find a child with fd %d\n",