1 /* Process support for Windows NT port of GNU EMACS.
2 Copyright (C) 1992, 1995 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
);
230 start
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
231 start
.wShowWindow
= SW_HIDE
;
233 start
.hStdInput
= GetStdHandle (STD_INPUT_HANDLE
);
234 start
.hStdOutput
= GetStdHandle (STD_OUTPUT_HANDLE
);
235 start
.hStdError
= GetStdHandle (STD_ERROR_HANDLE
);
236 #endif /* HAVE_NTGUI */
238 /* Explicitly specify no security */
239 if (!InitializeSecurityDescriptor (&sec_desc
, SECURITY_DESCRIPTOR_REVISION
))
241 if (!SetSecurityDescriptorDacl (&sec_desc
, TRUE
, NULL
, FALSE
))
243 sec_attrs
.nLength
= sizeof (sec_attrs
);
244 sec_attrs
.lpSecurityDescriptor
= &sec_desc
;
245 sec_attrs
.bInheritHandle
= FALSE
;
247 if (!CreateProcess (exe
, cmdline
, &sec_attrs
, NULL
, TRUE
,
248 CREATE_NEW_PROCESS_GROUP
, env
, NULL
,
251 cp
->process
= info
->hProcess
;
252 cp
->pid
= info
->dwProcessId
;
257 id
= GetLastError ();
260 SetEvent (cp
->char_consumed
);
262 CloseHandle (cp
->char_consumed
);
264 CloseHandle (cp
->char_avail
);
269 /* create_child doesn't know what emacs' file handle will be for waiting
270 on output from the child, so we need to make this additional call
271 to register the handle with the process
272 This way the select emulator knows how to match file handles with
273 entries in child_procs. */
275 register_child (int pid
, int fd
)
279 cp
= find_child_pid (pid
);
282 DebPrint (("register_child unable to find pid %lu\n", pid
));
287 DebPrint (("register_child registered fd %d with pid %lu\n", fd
, pid
));
293 /* Tell the reader thread to start */
294 if (!SetEvent (cp
->char_consumed
))
296 DebPrint (("register_child.SetEvent failed with %lu for fd %ld\n",
297 GetLastError (), cp
->fd
));
301 /* When a process dies its pipe will break so the reader thread will
302 signal failure to the select emulator.
303 The select emulator then calls this routine to clean up.
304 Since the thread signaled failure we can assume it is exiting. */
306 remove_child (child_process
*cp
)
308 /* Reap the thread */
309 if (WaitForSingleObject (cp
->thrd
, INFINITE
) != WAIT_OBJECT_0
)
311 DebPrint (("remove_child.WaitForSingleObject (thread) failed "
312 "with %lu for fd %ld\n", GetLastError (), cp
->fd
));
314 CloseHandle (cp
->thrd
);
315 CloseHandle (cp
->char_consumed
);
316 CloseHandle (cp
->char_avail
);
318 /* Reap the process */
319 if (WaitForSingleObject (cp
->process
, INFINITE
) != WAIT_OBJECT_0
)
321 DebPrint (("remove_child.WaitForSingleObject (process) failed "
322 "with %lu for fd %ld\n", GetLastError (), cp
->fd
));
324 CloseHandle (cp
->process
);
326 DEACTIVATE_CHILD (cp
);
329 /* Wait for any of our existing child processes to die
330 When it does, close its handle
331 Return the pid and fill in the status if non-NULL. */
333 /* From callproc.c */
334 extern int synch_process_alive
;
335 extern int synch_process_retcode
;
338 win32_wait (int *status
)
340 DWORD active
, retval
;
342 child_process
*cp
, *cps
[MAX_CHILDREN
];
343 HANDLE wait_hnd
[MAX_CHILDREN
];
346 if (dead_child
!= NULL
)
348 /* We want to wait for a specific child */
349 wait_hnd
[nh
] = dead_child
->process
;
350 cps
[nh
] = dead_child
;
355 for (cp
= child_procs
+(child_proc_count
-1); cp
>= child_procs
; cp
--)
356 if (CHILD_ACTIVE (cp
))
358 wait_hnd
[nh
] = cp
->process
;
366 /* Nothing to wait on, so fail */
371 active
= WaitForMultipleObjects (nh
, wait_hnd
, FALSE
, INFINITE
);
372 if (active
== WAIT_FAILED
)
377 else if (active
== WAIT_TIMEOUT
)
379 /* Should never happen */
383 else if (active
>= WAIT_OBJECT_0
&&
384 active
< WAIT_OBJECT_0
+MAXIMUM_WAIT_OBJECTS
)
386 active
-= WAIT_OBJECT_0
;
388 else if (active
>= WAIT_ABANDONED_0
&&
389 active
< WAIT_ABANDONED_0
+MAXIMUM_WAIT_OBJECTS
)
391 active
-= WAIT_ABANDONED_0
;
394 if (!GetExitCodeProcess (wait_hnd
[active
], &retval
))
396 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
400 if (retval
== STILL_ACTIVE
)
402 /* Should never happen */
403 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
408 /* Massage the exit code from the process to match the format expected
409 by the WIFSTOPPED et al macros in syswait.h. Only WIFSIGNALLED and
410 WIFEXITED are supported; WIFSTOPPED doesn't make sense under NT. */
412 if (retval
== STATUS_CONTROL_C_EXIT
)
423 else if (synch_process_alive
)
425 synch_process_alive
= 0;
426 synch_process_retcode
= retval
;
428 TerminateThread (cp
->thrd
, 0);
429 CloseHandle (cp
->thrd
);
430 CloseHandle (cp
->char_consumed
);
431 CloseHandle (cp
->char_avail
);
432 CloseHandle (cp
->process
);
433 DEACTIVATE_CHILD (cp
);
439 /* We pass our process ID to our children by setting up an environment
440 variable in their environment. */
441 char ppid_env_var_buffer
[64];
443 /* When a new child process is created we need to register it in our list,
444 so intercept spawn requests. */
446 win32_spawnve (int mode
, char *cmdname
, char **argv
, char **envp
)
448 Lisp_Object program
, full
;
449 char *cmdline
, *env
, *parg
, **targ
;
451 PROCESS_INFORMATION pi
;
453 /* Handle executable names without an executable suffix. */
454 program
= make_string (cmdname
, strlen (cmdname
));
455 if (NILP (Ffile_executable_p (program
)))
461 openp (Vexec_path
, program
, EXEC_SUFFIXES
, &full
, 1);
468 cmdname
= XSTRING (full
)->data
;
472 if (child_proc_count
== MAX_CHILDREN
)
478 /* We don't care about the other modes */
479 if (mode
!= _P_NOWAIT
)
485 /* we have to do some conjuring here to put argv and envp into the
486 form CreateProcess wants... argv needs to be a space separated/null
487 terminated list of parameters, and envp is a null
488 separated/double-null terminated list of parameters.
490 Since I have no idea how large argv and envp are likely to be
491 we figure out list lengths on the fly and allocate them. */
498 arglen
+= strlen (*targ
++) + 1;
500 cmdline
= malloc (arglen
);
510 strcpy (parg
, *targ
);
511 parg
+= strlen (*targ
++);
521 arglen
+= strlen (*targ
++) + 1;
523 sprintf (ppid_env_var_buffer
, "__PARENT_PROCESS_ID=%d",
524 GetCurrentProcessId ());
525 arglen
+= strlen (ppid_env_var_buffer
) + 1;
527 env
= malloc (arglen
);
537 strcpy (parg
, *targ
);
538 parg
+= strlen (*targ
++);
541 strcpy (parg
, ppid_env_var_buffer
);
542 parg
+= strlen (ppid_env_var_buffer
);
546 /* Now create the process. */
547 if (!create_child (cmdname
, cmdline
, env
, &pi
))
553 return pi
.dwProcessId
;
563 /* Emulate the select call
564 Wait for available input on any of the given rfds, or timeout if
565 a timeout is given and no input is detected
566 wfds and efds are not supported and must be NULL. */
569 extern HANDLE keyboard_handle
;
571 extern int proc_buffered_char
[];
574 sys_select (int nfds
, SELECT_TYPE
*rfds
, SELECT_TYPE
*wfds
, SELECT_TYPE
*efds
,
581 child_process
*cp
, *cps
[MAX_CHILDREN
+ 1];
582 HANDLE wait_hnd
[MAX_CHILDREN
+ 1];
584 BOOL keyboardwait
= FALSE
;
585 #endif /* HAVE_NTGUI */
587 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
588 if (rfds
== NULL
&& wfds
== NULL
&& efds
== NULL
&& timeout
!= NULL
)
591 Sleep (timeout
->tv_sec
* 1000 + timeout
->tv_usec
/ 1000);
593 Sleep ((*timeout
) * 1000);
598 /* Otherwise, we only handle rfds, so fail otherwise. */
599 if (rfds
== NULL
|| wfds
!= NULL
|| efds
!= NULL
)
609 /* Build a list of handles to wait on. */
611 for (i
= 0; i
< nfds
; i
++)
612 if (FD_ISSET (i
, &orfds
))
617 keyboardwait
= TRUE
;
619 /* Handle stdin specially */
620 wait_hnd
[nh
] = keyboard_handle
;
623 #endif /* HAVE_NTGUI */
625 /* Check for any emacs-generated input in the queue since
626 it won't be detected in the wait */
627 if (detect_input_pending ())
635 /* Child process input */
636 cp
= find_child_fd (i
);
640 DebPrint (("select waiting on child %d fd %d\n",
643 wait_hnd
[nh
] = cp
->char_avail
;
649 /* Unable to find something to wait on for this fd, fail */
650 DebPrint (("select unable to find child process "
658 /* Never do this in win32 since we will not get paint messages */
661 /* Nothing to look for, so we didn't find anything */
666 Sleep (timeout
->tv_sec
* 1000 + timeout
->tv_usec
/ 1000);
668 Sleep ((*timeout
) * 1000);
672 #endif /* !HAVE_NTGUI */
674 /* Check for immediate return without waiting */
680 If a child process dies while this is waiting, its pipe will break
681 so the reader thread will signal an error condition, thus, the wait
685 timeout_ms
= timeout
? (timeout
->tv_sec
* 1000 + timeout
->tv_usec
/ 1000) : INFINITE
;
687 timeout_ms
= timeout
? *timeout
*1000 : INFINITE
;
690 active
= MsgWaitForMultipleObjects (nh
, wait_hnd
, FALSE
, timeout_ms
,QS_ALLINPUT
);
692 active
= WaitForMultipleObjects (nh
, wait_hnd
, FALSE
, timeout_ms
);
693 #endif /* HAVE_NTGUI */
694 if (active
== WAIT_FAILED
)
696 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
697 nh
, timeout_ms
, GetLastError ()));
698 /* Is there a better error? */
702 else if (active
== WAIT_TIMEOUT
)
707 else if (active
== WAIT_OBJECT_0
+ nh
)
709 /* Keyboard input available */
712 /* This shouldn't be necessary, but apparently just setting the input
713 fd is not good enough for emacs */
714 // read_input_waiting ();
718 #endif /* HAVE_NTGUI */
719 else if (active
>= WAIT_OBJECT_0
&&
720 active
< WAIT_OBJECT_0
+MAXIMUM_WAIT_OBJECTS
)
722 active
-= WAIT_OBJECT_0
;
724 else if (active
>= WAIT_ABANDONED_0
&&
725 active
< WAIT_ABANDONED_0
+MAXIMUM_WAIT_OBJECTS
)
727 active
-= WAIT_ABANDONED_0
;
730 if (cps
[active
] == NULL
)
732 /* Keyboard input available */
736 /* This shouldn't be necessary, but apparently just setting the input
737 fd is not good enough for emacs */
738 read_input_waiting ();
745 /* If status is FALSE the read failed so don't report input */
748 FD_SET (cp
->fd
, rfds
);
749 proc_buffered_char
[cp
->fd
] = cp
->chr
;
754 /* The SIGCHLD handler will do a Wait so we know it won't
755 return until the process is dead
756 We force Wait to only wait for this process to avoid it
757 picking up other children that happen to be dead but that
758 we haven't noticed yet
759 SIG_DFL for SIGCHLD is ignore? */
760 if (sig_handlers
[SIGCHLD
] != SIG_DFL
&&
761 sig_handlers
[SIGCHLD
] != SIG_IGN
)
764 DebPrint (("select calling SIGCHLD handler for pid %d\n",
768 sig_handlers
[SIGCHLD
](SIGCHLD
);
772 /* Clean up the child process entry in the table */
780 Substitute for certain kill () operations
783 win32_kill_process (int pid
, int sig
)
787 /* Only handle signals that will result in the process dying */
788 if (sig
!= SIGINT
&& sig
!= SIGKILL
&& sig
!= SIGQUIT
&& sig
!= SIGHUP
)
794 cp
= find_child_pid (pid
);
797 DebPrint (("win32_kill_process didn't find a child with pid %lu\n", pid
));
804 /* Fake Ctrl-Break. */
805 if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, pid
))
807 DebPrint (("win32_kill_process.GenerateConsoleCtrlEvent return %d "
808 "for pid %lu\n", GetLastError (), pid
));
815 /* Kill the process. On Win32 this doesn't kill child processes
816 so it doesn't work very well for shells which is why it's
817 not used in every case. */
818 if (!TerminateProcess (cp
->process
, 0xff))
820 DebPrint (("win32_kill_process.TerminateProcess returned %d "
821 "for pid %lu\n", GetLastError (), pid
));
829 /* If the channel is a pipe this read might block since we don't
830 know how many characters are available, so check and read only
832 We also need to wake up the reader thread once we've read our data. */
834 read_child_output (int fd
, char *buf
, int max
)
841 h
= (HANDLE
)_get_osfhandle (fd
);
842 if (GetFileType (h
) == FILE_TYPE_PIPE
)
844 PeekNamedPipe (h
, NULL
, 0, NULL
, &waiting
, NULL
);
845 to_read
= min (waiting
, (DWORD
)max
);
850 /* Use read to get CRLF translation */
851 nchars
= read (fd
, buf
, to_read
);
853 if (GetFileType (h
) == FILE_TYPE_PIPE
)
855 /* Wake up the reader thread
857 cp
= find_child_fd (fd
);
860 if (!SetEvent (cp
->char_consumed
))
861 DebPrint (("read_child_output.SetEvent failed with "
862 "%lu for fd %ld\n", GetLastError (), fd
));
865 DebPrint (("read_child_output couldn't find a child with fd %d\n",