Mercurial > hg > xemacs-beta
comparison src/ntproc.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | a4f53d9b3154 |
children | 6240c7796c7a |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
48 #include "nt.h" | 48 #include "nt.h" |
49 #include "ntheap.h" /* From 19.34.6 */ | 49 #include "ntheap.h" /* From 19.34.6 */ |
50 #include "systime.h" | 50 #include "systime.h" |
51 #include "syssignal.h" | 51 #include "syssignal.h" |
52 #include "syswait.h" | 52 #include "syswait.h" |
53 #include "buffer.h" | |
54 #include "process.h" | 53 #include "process.h" |
55 /*#include "w32term.h"*/ /* From 19.34.6: sync in ? --marcpa */ | 54 /*#include "w32term.h"*/ /* From 19.34.6: sync in ? --marcpa */ |
56 | 55 |
57 /* #### I'm not going to play with shit. */ | 56 /* #### I'm not going to play with shit. */ |
58 #pragma warning (disable:4013 4024 4090) | 57 #pragma warning (disable:4013 4024 4090) |
59 | 58 |
60 /* Control whether spawnve quotes arguments as necessary to ensure | 59 /* Control whether spawnve quotes arguments as necessary to ensure |
61 correct parsing by child process. Because not all uses of spawnve | 60 correct parsing by child process. Because not all uses of spawnve |
62 are careful about constructing argv arrays, we make this behavior | 61 are careful about constructing argv arrays, we make this behaviour |
63 conditional (off by default). */ | 62 conditional (off by default). */ |
64 Lisp_Object Vwin32_quote_process_args; | 63 Lisp_Object Vwin32_quote_process_args; |
65 | 64 |
66 /* Control whether create_child causes the process' window to be | 65 /* Control whether create_child causes the process' window to be |
67 hidden. The default is nil. */ | 66 hidden. The default is nil. */ |
131 | 130 |
132 Initialize: | 131 Initialize: |
133 xzero (*cp); | 132 xzero (*cp); |
134 cp->fd = -1; | 133 cp->fd = -1; |
135 cp->pid = -1; | 134 cp->pid = -1; |
136 if (cp->procinfo.hProcess) | |
137 CloseHandle(cp->procinfo.hProcess); | |
138 cp->procinfo.hProcess = NULL; | 135 cp->procinfo.hProcess = NULL; |
139 cp->status = STATUS_READ_ERROR; | 136 cp->status = STATUS_READ_ERROR; |
140 | 137 |
141 /* use manual reset event so that select() will function properly */ | 138 /* use manual reset event so that select() will function properly */ |
142 cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL); | 139 cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL); |
235 child_process *cp; | 232 child_process *cp; |
236 | 233 |
237 /* Our identity */ | 234 /* Our identity */ |
238 cp = (child_process *)arg; | 235 cp = (child_process *)arg; |
239 | 236 |
240 /* <matts@tibco.com> - I think the test below is wrong - we don't | 237 /* We have to wait for the go-ahead before we can start */ |
241 want to wait for someone to signal char_consumed, as we haven't | |
242 read anything for them to consume yet! */ | |
243 | |
244 /* | |
245 if (cp == NULL || | 238 if (cp == NULL || |
246 WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) | 239 WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) |
247 */ | 240 return 1; |
248 | |
249 if (cp == NULL) | |
250 { | |
251 return 1; | |
252 } | |
253 | 241 |
254 for (;;) | 242 for (;;) |
255 { | 243 { |
256 int rc; | 244 int rc; |
257 | 245 |
265 GetLastError (), cp->fd)); | 253 GetLastError (), cp->fd)); |
266 return 1; | 254 return 1; |
267 } | 255 } |
268 | 256 |
269 if (rc == STATUS_READ_ERROR) | 257 if (rc == STATUS_READ_ERROR) |
270 { | 258 return 1; |
271 /* We are finished, so clean up handles and set to NULL so | |
272 that CHILD_ACTIVE will see what is going on */ | |
273 if (cp->char_avail) { | |
274 CloseHandle (cp->char_avail); | |
275 cp->char_avail = NULL; | |
276 } | |
277 if (cp->thrd) { | |
278 CloseHandle (cp->thrd); | |
279 cp->thrd = NULL; | |
280 } | |
281 if (cp->char_consumed) { | |
282 CloseHandle(cp->char_consumed); | |
283 cp->char_consumed = NULL; | |
284 } | |
285 if (cp->procinfo.hProcess) | |
286 { | |
287 CloseHandle (cp->procinfo.hProcess); | |
288 cp->procinfo.hProcess=NULL; | |
289 } | |
290 return 1; | |
291 } | |
292 | 259 |
293 /* If the read died, the child has died so let the thread die */ | 260 /* If the read died, the child has died so let the thread die */ |
294 if (rc == STATUS_READ_FAILED) | 261 if (rc == STATUS_READ_FAILED) |
295 break; | 262 break; |
296 | 263 |
300 DebPrint (("reader_thread.WaitForSingleObject failed with " | 267 DebPrint (("reader_thread.WaitForSingleObject failed with " |
301 "%lu for fd %ld\n", GetLastError (), cp->fd)); | 268 "%lu for fd %ld\n", GetLastError (), cp->fd)); |
302 break; | 269 break; |
303 } | 270 } |
304 } | 271 } |
305 /* We are finished, so clean up handles and set to NULL so that | |
306 CHILD_ACTIVE will see what is going on */ | |
307 if (cp->char_avail) { | |
308 CloseHandle (cp->char_avail); | |
309 cp->char_avail = NULL; | |
310 } | |
311 if (cp->thrd) { | |
312 CloseHandle (cp->thrd); | |
313 cp->thrd = NULL; | |
314 } | |
315 if (cp->char_consumed) { | |
316 CloseHandle(cp->char_consumed); | |
317 cp->char_consumed = NULL; | |
318 } | |
319 if (cp->procinfo.hProcess) | |
320 { | |
321 CloseHandle (cp->procinfo.hProcess); | |
322 cp->procinfo.hProcess=NULL; | |
323 } | |
324 | |
325 return 0; | 272 return 0; |
326 } | 273 } |
327 | 274 |
328 /* To avoid Emacs changing directory, we just record here the directory | 275 /* To avoid Emacs changing directory, we just record here the directory |
329 the new process should start in. This is set just before calling | 276 the new process should start in. This is set just before calling |
376 &start, &cp->procinfo)) | 323 &start, &cp->procinfo)) |
377 goto EH_Fail; | 324 goto EH_Fail; |
378 | 325 |
379 cp->pid = (int) cp->procinfo.dwProcessId; | 326 cp->pid = (int) cp->procinfo.dwProcessId; |
380 | 327 |
381 CloseHandle (cp->procinfo.hThread); | 328 /* Hack for Windows 95, which assigns large (ie negative) pids */ |
382 CloseHandle (cp->procinfo.hProcess); | 329 if (cp->pid < 0) |
383 cp->procinfo.hThread=NULL; | 330 cp->pid = -cp->pid; |
384 cp->procinfo.hProcess=NULL; | |
385 | 331 |
386 /* pid must fit in a Lisp_Int */ | 332 /* pid must fit in a Lisp_Int */ |
387 | 333 #ifdef USE_UNION_TYPE |
334 cp->pid = (cp->pid & ((1U << VALBITS) - 1)); | |
335 #else | |
336 cp->pid = (cp->pid & VALMASK); | |
337 #endif | |
388 | 338 |
389 *pPid = cp->pid; | 339 *pPid = cp->pid; |
390 | 340 |
391 return TRUE; | 341 return TRUE; |
392 | 342 |
562 { | 512 { |
563 UNGCPRO; | 513 UNGCPRO; |
564 errno = EINVAL; | 514 errno = EINVAL; |
565 return -1; | 515 return -1; |
566 } | 516 } |
567 GET_C_STRING_FILENAME_DATA_ALLOCA (full, cmdname); | 517 cmdname = XSTRING_DATA (full); |
568 } | 518 /* #### KLUDGE */ |
569 else | 519 *(char**)(argv[0]) = cmdname; |
570 { | |
571 (char*)cmdname = alloca (strlen (argv[0]) + 1); | |
572 strcpy ((char*)cmdname, argv[0]); | |
573 } | 520 } |
574 UNGCPRO; | 521 UNGCPRO; |
575 | 522 |
576 /* make sure argv[0] and cmdname are both in DOS format */ | 523 /* make sure argv[0] and cmdname are both in DOS format */ |
524 strcpy (cmdname = alloca (strlen (cmdname) + 1), argv[0]); | |
577 unixtodos_filename (cmdname); | 525 unixtodos_filename (cmdname); |
578 /* #### KLUDGE */ | 526 /* #### KLUDGE */ |
579 ((CONST char**)argv)[0] = cmdname; | 527 *(char**)(argv[0]) = cmdname; |
580 | 528 |
581 /* Determine whether program is a 16-bit DOS executable, or a Win32 | 529 /* Determine whether program is a 16-bit DOS executable, or a Win32 |
582 executable that is implicitly linked to the Cygnus dll (implying it | 530 executable that is implicitly linked to the Cygnus dll (implying it |
583 was compiled with the Cygnus GNU toolchain and hence relies on | 531 was compiled with the Cygnus GNU toolchain and hence relies on |
584 cygwin.dll to parse the command line - we use this to decide how to | 532 cygwin.dll to parse the command line - we use this to decide how to |
717 last = p + strlen (p) - 1; | 665 last = p + strlen (p) - 1; |
718 *parg++ = '"'; | 666 *parg++ = '"'; |
719 #if 0 | 667 #if 0 |
720 /* This version does not escape quotes if they occur at the | 668 /* This version does not escape quotes if they occur at the |
721 beginning or end of the arg - this could lead to incorrect | 669 beginning or end of the arg - this could lead to incorrect |
722 behavior when the arg itself represents a command line | 670 behaviour when the arg itself represents a command line |
723 containing quoted args. I believe this was originally done | 671 containing quoted args. I believe this was originally done |
724 as a hack to make some things work, before | 672 as a hack to make some things work, before |
725 `win32-quote-process-args' was added. */ | 673 `win32-quote-process-args' was added. */ |
726 while (*p) | 674 while (*p) |
727 { | 675 { |
1328 | 1276 |
1329 | 1277 |
1330 void | 1278 void |
1331 syms_of_ntproc () | 1279 syms_of_ntproc () |
1332 { | 1280 { |
1281 Qhigh = intern ("high"); | |
1282 Qlow = intern ("low"); | |
1283 | |
1333 DEFSUBR (Fwin32_short_file_name); | 1284 DEFSUBR (Fwin32_short_file_name); |
1334 DEFSUBR (Fwin32_long_file_name); | 1285 DEFSUBR (Fwin32_long_file_name); |
1335 DEFSUBR (Fwin32_set_process_priority); | 1286 DEFSUBR (Fwin32_set_process_priority); |
1336 DEFSUBR (Fwin32_get_locale_info); | 1287 DEFSUBR (Fwin32_get_locale_info); |
1337 DEFSUBR (Fwin32_get_current_locale_id); | 1288 DEFSUBR (Fwin32_get_current_locale_id); |
1338 DEFSUBR (Fwin32_get_default_locale_id); | 1289 DEFSUBR (Fwin32_get_default_locale_id); |
1339 DEFSUBR (Fwin32_get_valid_locale_ids); | 1290 DEFSUBR (Fwin32_get_valid_locale_ids); |
1340 DEFSUBR (Fwin32_set_current_locale); | 1291 DEFSUBR (Fwin32_set_current_locale); |
1341 } | |
1342 | |
1343 | |
1344 void | |
1345 vars_of_ntproc (void) | |
1346 { | |
1347 Qhigh = intern ("high"); | |
1348 Qlow = intern ("low"); | |
1349 | 1292 |
1350 DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /* | 1293 DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /* |
1351 Non-nil enables quoting of process arguments to ensure correct parsing. | 1294 Non-nil enables quoting of process arguments to ensure correct parsing. |
1352 Because Windows does not directly pass argv arrays to child processes, | 1295 Because Windows does not directly pass argv arrays to child processes, |
1353 programs have to reconstruct the argv array by parsing the command | 1296 programs have to reconstruct the argv array by parsing the command |
1374 allowing only only DOS subprocess to run at a time (whether started directly | 1317 allowing only only DOS subprocess to run at a time (whether started directly |
1375 or indirectly by Emacs), and preventing Emacs from cleanly terminating the | 1318 or indirectly by Emacs), and preventing Emacs from cleanly terminating the |
1376 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't | 1319 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't |
1377 otherwise respond to interrupts from Emacs. | 1320 otherwise respond to interrupts from Emacs. |
1378 */ ); | 1321 */ ); |
1379 Vwin32_start_process_share_console = Qt; | 1322 Vwin32_start_process_share_console = Qnil; |
1380 | 1323 |
1381 DEFVAR_LISP ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /* | 1324 DEFVAR_LISP ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /* |
1382 Forced delay before reading subprocess output. | 1325 Forced delay before reading subprocess output. |
1383 This is done to improve the buffering of subprocess output, by | 1326 This is done to improve the buffering of subprocess output, by |
1384 avoiding the inefficiency of frequently reading small amounts of data. | 1327 avoiding the inefficiency of frequently reading small amounts of data. |
1399 the truename of a file can be slow. | 1342 the truename of a file can be slow. |
1400 */ ); | 1343 */ ); |
1401 Vwin32_generate_fake_inodes = Qnil; | 1344 Vwin32_generate_fake_inodes = Qnil; |
1402 #endif | 1345 #endif |
1403 } | 1346 } |
1404 | |
1405 /* end of ntproc.c */ | 1347 /* end of ntproc.c */ |