comparison src/process-nt.c @ 278:90d73dddcdc4 r21-0b37

Import from CVS: tag r21-0b37
author cvs
date Mon, 13 Aug 2007 10:31:29 +0200
parents 6330739388db
children 7df0dd720c89
comparison
equal deleted inserted replaced
277:cfdf3ff11843 278:90d73dddcdc4
28 28
29 #include "hash.h" 29 #include "hash.h"
30 #include "lstream.h" 30 #include "lstream.h"
31 #include "process.h" 31 #include "process.h"
32 #include "procimpl.h" 32 #include "procimpl.h"
33 #include "sysdep.h"
33 34
34 #include <windows.h> 35 #include <windows.h>
36 #include <shellapi.h>
35 37
36 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */ 38 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */
37 struct nt_process_data 39 struct nt_process_data
38 { 40 {
39 HANDLE h_process; 41 HANDLE h_process;
122 * must signal an error instead. 124 * must signal an error instead.
123 */ 125 */
124 126
125 /* #### This function completely ignores Vprocess_environment */ 127 /* #### This function completely ignores Vprocess_environment */
126 128
129 static void
130 signal_cannot_launch (char* image_file, DWORD err)
131 {
132 mswindows_set_errno (err);
133 error ("Starting \"%s\": %s", image_file, strerror (errno));
134 }
135
127 static int 136 static int
128 nt_create_process (struct Lisp_Process *p, 137 nt_create_process (struct Lisp_Process *p,
129 char **argv, CONST char *current_dir) 138 char **argv, CONST char *current_dir)
130 { 139 {
131 HANDLE hmyshove, hmyslurp, hprocin, hprocout; 140 HANDLE hmyshove, hmyslurp, hprocin, hprocout;
132 LPTSTR command_line; 141 LPTSTR command_line;
142 BOOL do_io, windowed;
143
144 /* Find out whether the application is windowed or not */
145 {
146 /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most
147 errors. This leads to bogus error message. */
148 DWORD image_type = SHGetFileInfo (argv[0], 0, NULL, 0, SHGFI_EXETYPE);
149 if (image_type == 0)
150 signal_cannot_launch (argv[0], (GetLastError () == ERROR_FILE_NOT_FOUND
151 ? ERROR_BAD_FORMAT : GetLastError ()));
152 windowed = HIWORD (image_type) != 0;
153 }
154
155 /* Decide whether to do I/O on process handles, or just mark the
156 process exited immediately upon successful launching. We do I/O if the
157 process is a console one, or if it is windowed but windowed_process_io
158 is non-zero */
159 do_io = !windowed || windowed_process_io ;
133 160
134 /* Create two unidirectional named pipes */ 161 if (do_io)
135 { 162 {
136 HANDLE htmp; 163 /* Create two unidirectional named pipes */
137 SECURITY_ATTRIBUTES sa; 164 HANDLE htmp;
138 165 SECURITY_ATTRIBUTES sa;
139 sa.nLength = sizeof(sa); 166
140 sa.bInheritHandle = TRUE; 167 sa.nLength = sizeof(sa);
141 sa.lpSecurityDescriptor = NULL; 168 sa.bInheritHandle = TRUE;
142 169 sa.lpSecurityDescriptor = NULL;
143 CreatePipe (&hprocin, &hmyshove, &sa, 0); 170
144 CreatePipe (&hmyslurp, &hprocout, &sa, 0); 171 CreatePipe (&hprocin, &hmyshove, &sa, 0);
145 172 CreatePipe (&hmyslurp, &hprocout, &sa, 0);
146 /* Stupid Win32 allows to create a pipe with *both* ends either 173
147 inheritable or not. We need process ends inheritable, and local 174 /* Stupid Win32 allows to create a pipe with *both* ends either
148 ends not inheritable. */ 175 inheritable or not. We need process ends inheritable, and local
149 /* #### Perhaps even stupider me does not know how to do this better */ 176 ends not inheritable. */
150 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp, 177 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp,
151 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); 178 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
152 hmyshove = htmp; 179 hmyshove = htmp;
153 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(), &htmp, 180 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(), &htmp,
154 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); 181 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
155 hmyslurp = htmp; 182 hmyslurp = htmp;
156 } 183 }
157 184
158 /* Convert an argv vector into Win32 style command line. 185 /* Convert an argv vector into Win32 style command line.
159 186
160 #### This works only for cmd, and not for cygwin bash. Perhaps, 187 #### This works only for cmd, and not for cygwin bash. Perhaps,
161 instead of ad-hoc fiddling with different methods for quoting 188 instead of ad-hoc fiddling with different methods for quoting
184 /* Create process */ 211 /* Create process */
185 { 212 {
186 STARTUPINFO si; 213 STARTUPINFO si;
187 PROCESS_INFORMATION pi; 214 PROCESS_INFORMATION pi;
188 DWORD err; 215 DWORD err;
189 BOOL windowed;
190 216
191 xzero (si); 217 xzero (si);
192 si.hStdInput = hprocin; 218 si.dwFlags = STARTF_USESHOWWINDOW;
193 si.hStdOutput = hprocout; 219 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
194 si.hStdError = hprocout; 220 if (do_io)
195 si.wShowWindow = SW_HIDE; 221 {
196 si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 222 si.hStdInput = hprocin;
197 223 si.hStdOutput = hprocout;
224 si.hStdError = hprocout;
225 si.dwFlags |= STARTF_USESTDHANDLES;
226 }
227
198 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, 228 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE,
199 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP | CREATE_SUSPENDED, 229 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
200 NULL, current_dir, &si, &pi) 230 NULL, current_dir, &si, &pi)
201 ? 0 : GetLastError ()); 231 ? 0 : GetLastError ());
202 232
203 CloseHandle (hprocin); 233 if (do_io)
204 CloseHandle (hprocout); 234 {
205 235 /* These just have been inherited; we do not need a copy */
206 /* See if we succeeded with process creation */ 236 CloseHandle (hprocin);
237 CloseHandle (hprocout);
238 }
239
240 /* Handle process creation failure */
207 if (err) 241 if (err)
208 { 242 {
209 process_error__One_of_those_nasty_uses_for_goto_statement: 243 if (do_io)
210 CloseHandle (hmyshove);
211 CloseHandle (hmyslurp);
212 error ("Cannot start \"%s\": error code was %lu", argv[0], err);
213 }
214
215 /* Determine if the new process is a windowed one */
216 windowed = WaitForInputIdle (pi.hProcess, 100) == WAIT_TIMEOUT;
217 if (windowed)
218 {
219 /* We restart windowed process fire-and forget style, and
220 indicate successful process creation, just as if the
221 process ended instantly upon launching */
222 CloseHandle (hmyshove);
223 CloseHandle (hmyslurp);
224 /* TerminateProcess is safe becuase the process is not yet
225 running */
226 TerminateProcess (pi.hProcess, 0);
227 si.dwFlags = STARTF_USESHOWWINDOW;
228 si.wShowWindow = SW_SHOWNORMAL;
229 if (!CreateProcess (NULL, command_line, NULL, NULL, FALSE,
230 DETACHED_PROCESS , NULL, current_dir, &si, &pi))
231 { 244 {
232 err = GetLastError (); 245 CloseHandle (hmyshove);
233 goto process_error__One_of_those_nasty_uses_for_goto_statement; 246 CloseHandle (hmyslurp);
234 } 247 }
235 248 signal_cannot_launch (argv[0], GetLastError ());
236 /* We just launched a windowed process. Fake it as if a 249 }
237 process launched has already ended */ 250
251 /* The process started successfully */
252 if (do_io)
253 {
254 NT_DATA(p)->h_process = pi.hProcess;
255 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
256 }
257 else
258 {
259 /* Indicate as if the process has exited immediately. */
238 p->status_symbol = Qexit; 260 p->status_symbol = Qexit;
239
240 /* Get rid of process and thread handles */
241 CloseHandle (pi.hThread);
242 CloseHandle (pi.hProcess); 261 CloseHandle (pi.hProcess);
243 } 262 }
244 else 263
245 { 264 CloseHandle (pi.hThread);
246 /* Just started a console subprocess */ 265
247 266 /* Hack to support Windows 95 negative pids */
248 NT_DATA(p)->h_process = pi.hProcess;
249
250 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
251
252 /* We created it suspended. Resume the only thread */
253 ResumeThread (pi.hThread);
254 CloseHandle (pi.hThread);
255 }
256
257 return ((int)pi.dwProcessId < 0 267 return ((int)pi.dwProcessId < 0
258 ? -(int)pi.dwProcessId : (int)pi.dwProcessId); 268 ? -(int)pi.dwProcessId : (int)pi.dwProcessId);
259 } 269 }
260 } 270 }
261 271