annotate src/ntproc.c @ 126:1370575f1259 xemacs-20-1p1

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