Mercurial > hg > xemacs-beta
comparison src/callproc.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 4af0ddfb7c5b |
children | b8cc9ab3f761 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
41 #include "syssignal.h" /* Always include before systty.h */ | 41 #include "syssignal.h" /* Always include before systty.h */ |
42 #include "systty.h" | 42 #include "systty.h" |
43 | 43 |
44 #ifdef WINDOWSNT | 44 #ifdef WINDOWSNT |
45 #define _P_NOWAIT 1 /* from process.h */ | 45 #define _P_NOWAIT 1 /* from process.h */ |
46 #include <windows.h> | |
47 #include "nt.h" | 46 #include "nt.h" |
48 #endif | 47 #endif |
49 | 48 |
50 #ifdef DOS_NT | 49 #ifdef DOS_NT |
51 /* When we are starting external processes we need to know whether they | 50 /* When we are starting external processes we need to know whether they |
66 /* True iff we are about to fork off a synchronous process or if we | 65 /* True iff we are about to fork off a synchronous process or if we |
67 are waiting for it. */ | 66 are waiting for it. */ |
68 volatile int synch_process_alive; | 67 volatile int synch_process_alive; |
69 | 68 |
70 /* Nonzero => this is a string explaining death of synchronous subprocess. */ | 69 /* Nonzero => this is a string explaining death of synchronous subprocess. */ |
71 CONST char *synch_process_death; | 70 const char *synch_process_death; |
72 | 71 |
73 /* If synch_process_death is zero, | 72 /* If synch_process_death is zero, |
74 this is exit code of synchronous subprocess. */ | 73 this is exit code of synchronous subprocess. */ |
75 int synch_process_retcode; | 74 int synch_process_retcode; |
76 | 75 |
79 On Unix, kill the process and any children on termination by signal. */ | 78 On Unix, kill the process and any children on termination by signal. */ |
80 | 79 |
81 /* Nonzero if this is termination due to exit. */ | 80 /* Nonzero if this is termination due to exit. */ |
82 static int call_process_exited; | 81 static int call_process_exited; |
83 | 82 |
83 Lisp_Object Vlisp_EXEC_SUFFIXES; | |
84 | 84 |
85 static Lisp_Object | 85 static Lisp_Object |
86 call_process_kill (Lisp_Object fdpid) | 86 call_process_kill (Lisp_Object fdpid) |
87 { | 87 { |
88 Lisp_Object fd = Fcar (fdpid); | 88 Lisp_Object fd = Fcar (fdpid); |
99 } | 99 } |
100 | 100 |
101 static Lisp_Object | 101 static Lisp_Object |
102 call_process_cleanup (Lisp_Object fdpid) | 102 call_process_cleanup (Lisp_Object fdpid) |
103 { | 103 { |
104 int fd = XINT (Fcar (fdpid)); | 104 int fd = XINT (Fcar (fdpid)); |
105 int pid = XINT (Fcdr (fdpid)); | 105 int pid = XINT (Fcdr (fdpid)); |
106 | 106 |
107 if (!call_process_exited && | 107 if (!call_process_exited && |
108 EMACS_KILLPG (pid, SIGINT) == 0) | 108 EMACS_KILLPG (pid, SIGINT) == 0) |
109 { | 109 { |
111 | 111 |
112 record_unwind_protect (call_process_kill, fdpid); | 112 record_unwind_protect (call_process_kill, fdpid); |
113 /* #### "c-G" -- need non-consing Single-key-description */ | 113 /* #### "c-G" -- need non-consing Single-key-description */ |
114 message ("Waiting for process to die...(type C-g again to kill it instantly)"); | 114 message ("Waiting for process to die...(type C-g again to kill it instantly)"); |
115 | 115 |
116 #ifdef WINDOWSNT | |
117 { | |
118 HANDLE pHandle = OpenProcess (PROCESS_ALL_ACCESS, 0, pid); | |
119 if (pHandle == NULL) | |
120 warn_when_safe (Qprocess, Qwarning, | |
121 "cannot open process (PID %d) for cleanup", pid); | |
122 else | |
123 wait_for_termination (pHandle); | |
124 } | |
125 #else | |
116 wait_for_termination (pid); | 126 wait_for_termination (pid); |
127 #endif | |
117 | 128 |
118 /* "Discard" the unwind protect. */ | 129 /* "Discard" the unwind protect. */ |
119 XCAR (fdpid) = Qnil; | 130 XCAR (fdpid) = Qnil; |
120 XCDR (fdpid) = Qnil; | 131 XCDR (fdpid) = Qnil; |
121 unbind_to (speccount, Qnil); | 132 unbind_to (speccount, Qnil); |
167 { | 178 { |
168 /* This function can GC */ | 179 /* This function can GC */ |
169 Lisp_Object infile, buffer, current_dir, display, path; | 180 Lisp_Object infile, buffer, current_dir, display, path; |
170 int fd[2]; | 181 int fd[2]; |
171 int filefd; | 182 int filefd; |
183 #ifdef WINDOWSNT | |
184 HANDLE pHandle; | |
185 #endif | |
172 int pid; | 186 int pid; |
173 char buf[16384]; | 187 char buf[16384]; |
174 char *bufptr = buf; | 188 char *bufptr = buf; |
175 int bufsize = 16384; | 189 int bufsize = 16384; |
176 int speccount = specpdl_depth (); | 190 int speccount = specpdl_depth (); |
191 error ("Operating system cannot handle asynchronous subprocesses"); | 205 error ("Operating system cannot handle asynchronous subprocesses"); |
192 #endif /* NO_SUBPROCESSES */ | 206 #endif /* NO_SUBPROCESSES */ |
193 | 207 |
194 /* Do this before building new_argv because GC in Lisp code | 208 /* Do this before building new_argv because GC in Lisp code |
195 * called by various filename-hacking routines might relocate strings */ | 209 * called by various filename-hacking routines might relocate strings */ |
196 locate_file (Vexec_path, args[0], EXEC_SUFFIXES, &path, X_OK); | 210 locate_file (Vexec_path, args[0], Vlisp_EXEC_SUFFIXES, &path, X_OK); |
197 | 211 |
198 /* Make sure that the child will be able to chdir to the current | 212 /* Make sure that the child will be able to chdir to the current |
199 buffer's current directory, or its unhandled equivalent. We | 213 buffer's current directory, or its unhandled equivalent. We |
200 can't just have the child check for an error when it does the | 214 can't just have the child check for an error when it does the |
201 chdir, since it's in a vfork. */ | 215 chdir, since it's in a vfork. */ |
284 for (i = 4; i < nargs; i++) | 298 for (i = 4; i < nargs; i++) |
285 { | 299 { |
286 CHECK_STRING (args[i]); | 300 CHECK_STRING (args[i]); |
287 new_argv[i - 3] = (char *) XSTRING_DATA (args[i]); | 301 new_argv[i - 3] = (char *) XSTRING_DATA (args[i]); |
288 } | 302 } |
289 new_argv[nargs - 3] = 0; | |
290 } | 303 } |
304 new_argv[max(nargs - 3,1)] = 0; | |
291 | 305 |
292 if (NILP (path)) | 306 if (NILP (path)) |
293 report_file_error ("Searching for program", Fcons (args[0], Qnil)); | 307 report_file_error ("Searching for program", Fcons (args[0], Qnil)); |
294 new_argv[0] = (char *) XSTRING_DATA (path); | 308 new_argv[0] = (char *) XSTRING_DATA (path); |
295 | 309 |
332 | 346 |
333 if (NILP (error_file)) | 347 if (NILP (error_file)) |
334 fd_error = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY); | 348 fd_error = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY); |
335 else if (STRINGP (error_file)) | 349 else if (STRINGP (error_file)) |
336 { | 350 { |
337 fd_error = open ((CONST char *) XSTRING_DATA (error_file), | 351 fd_error = open ((const char *) XSTRING_DATA (error_file), |
338 #ifdef DOS_NT | 352 #ifdef DOS_NT |
339 O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, | 353 O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, |
340 S_IREAD | S_IWRITE | 354 S_IREAD | S_IWRITE |
341 #else /* not DOS_NT */ | 355 #else /* not DOS_NT */ |
342 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, | 356 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, |
356 | 370 |
357 fork_error = Qnil; | 371 fork_error = Qnil; |
358 #ifdef WINDOWSNT | 372 #ifdef WINDOWSNT |
359 pid = child_setup (filefd, fd1, fd_error, new_argv, | 373 pid = child_setup (filefd, fd1, fd_error, new_argv, |
360 (char *) XSTRING_DATA (current_dir)); | 374 (char *) XSTRING_DATA (current_dir)); |
375 if (!INTP (buffer)) | |
376 { | |
377 /* OpenProcess() as soon after child_setup as possible. It's too | |
378 late once the process terminated. */ | |
379 pHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); | |
380 #if 0 | |
381 if (pHandle == NULL) | |
382 { | |
383 /* #### seems to cause crash in unbind_to(...) below. APA */ | |
384 warn_when_safe (Qprocess, Qwarning, | |
385 "cannot open process to wait for"); | |
386 } | |
387 #endif | |
388 } | |
389 /* Close STDERR into the parent process. We no longer need it. */ | |
390 if (fd_error >= 0) | |
391 close (fd_error); | |
361 #else /* not WINDOWSNT */ | 392 #else /* not WINDOWSNT */ |
362 pid = fork (); | 393 pid = fork (); |
363 | 394 |
364 if (pid == 0) | 395 if (pid == 0) |
365 { | 396 { |
391 } | 422 } |
392 | 423 |
393 if (!NILP (fork_error)) | 424 if (!NILP (fork_error)) |
394 signal_error (Qfile_error, fork_error); | 425 signal_error (Qfile_error, fork_error); |
395 | 426 |
427 #ifndef WINDOWSNT | |
396 if (pid < 0) | 428 if (pid < 0) |
397 { | 429 { |
398 if (fd[0] >= 0) | 430 if (fd[0] >= 0) |
399 close (fd[0]); | 431 close (fd[0]); |
400 report_file_error ("Doing fork", Qnil); | 432 report_file_error ("Doing fork", Qnil); |
401 } | 433 } |
434 #endif | |
402 | 435 |
403 if (INTP (buffer)) | 436 if (INTP (buffer)) |
404 { | 437 { |
405 if (fd[0] >= 0) | 438 if (fd[0] >= 0) |
406 close (fd[0]); | 439 close (fd[0]); |
447 less than 1024--save that for the next bufferfull. */ | 480 less than 1024--save that for the next bufferfull. */ |
448 | 481 |
449 nread = 0; | 482 nread = 0; |
450 while (nread < bufsize - 1024) | 483 while (nread < bufsize - 1024) |
451 { | 484 { |
452 int this_read | 485 ssize_t this_read |
453 = Lstream_read (XLSTREAM (instream), bufptr + nread, | 486 = Lstream_read (XLSTREAM (instream), bufptr + nread, |
454 bufsize - nread); | 487 bufsize - nread); |
455 | 488 |
456 if (this_read < 0) | 489 if (this_read < 0) |
457 goto give_up; | 490 goto give_up; |
466 | 499 |
467 /* Now NREAD is the total amount of data in the buffer. */ | 500 /* Now NREAD is the total amount of data in the buffer. */ |
468 if (nread == 0) | 501 if (nread == 0) |
469 break; | 502 break; |
470 | 503 |
504 #if 0 | |
471 #ifdef DOS_NT | 505 #ifdef DOS_NT |
472 /* Until we pull out of MULE things like | 506 /* Until we pull out of MULE things like |
473 make_decoding_input_stream(), we do the following which is | 507 make_decoding_input_stream(), we do the following which is |
474 less elegant. --marcpa */ | 508 less elegant. --marcpa */ |
509 /* We did. -- kkm */ | |
475 { | 510 { |
476 int lf_count = 0; | 511 int lf_count = 0; |
477 if (NILP (Vbinary_process_output)) { | 512 if (NILP (Vbinary_process_output)) { |
478 nread = crlf_to_lf(nread, bufptr, &lf_count); | 513 nread = crlf_to_lf(nread, bufptr, &lf_count); |
479 } | 514 } |
480 } | 515 } |
516 #endif | |
481 #endif | 517 #endif |
482 | 518 |
483 total_read += nread; | 519 total_read += nread; |
484 | 520 |
485 if (!NILP (buffer)) | 521 if (!NILP (buffer)) |
504 Lstream_close (XLSTREAM (instream)); | 540 Lstream_close (XLSTREAM (instream)); |
505 NUNGCPRO; | 541 NUNGCPRO; |
506 | 542 |
507 QUIT; | 543 QUIT; |
508 /* Wait for it to terminate, unless it already has. */ | 544 /* Wait for it to terminate, unless it already has. */ |
545 #ifdef WINDOWSNT | |
546 wait_for_termination (pHandle); | |
547 #else | |
509 wait_for_termination (pid); | 548 wait_for_termination (pid); |
549 #endif | |
510 | 550 |
511 /* Don't kill any children that the subprocess may have left behind | 551 /* Don't kill any children that the subprocess may have left behind |
512 when exiting. */ | 552 when exiting. */ |
513 call_process_exited = 1; | 553 call_process_exited = 1; |
514 unbind_to (speccount, Qnil); | 554 unbind_to (speccount, Qnil); |
566 int | 606 int |
567 #else | 607 #else |
568 void | 608 void |
569 #endif | 609 #endif |
570 child_setup (int in, int out, int err, char **new_argv, | 610 child_setup (int in, int out, int err, char **new_argv, |
571 CONST char *current_dir) | 611 const char *current_dir) |
572 { | 612 { |
573 char **env; | 613 char **env; |
574 char *pwd; | 614 char *pwd; |
575 #ifdef WINDOWSNT | 615 #ifdef WINDOWSNT |
576 int cpid; | 616 int cpid; |
642 CONSP (tail) && STRINGP (XCAR (tail)); | 682 CONSP (tail) && STRINGP (XCAR (tail)); |
643 tail = XCDR (tail)) | 683 tail = XCDR (tail)) |
644 { | 684 { |
645 char **ep = env; | 685 char **ep = env; |
646 char *envvar_external; | 686 char *envvar_external; |
647 Bufbyte *envvar_internal = XSTRING_DATA (XCAR (tail)); | 687 |
648 | 688 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (tail), |
649 GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA (envvar_internal, envvar_external); | 689 C_STRING_ALLOCA, envvar_external, |
690 Qfile_name); | |
650 | 691 |
651 /* See if envvar_external duplicates any string already in the env. | 692 /* See if envvar_external duplicates any string already in the env. |
652 If so, don't put it in. | 693 If so, don't put it in. |
653 When an env var has multiple definitions, | 694 When an env var has multiple definitions, |
654 we keep the definition that comes first in process-environment. */ | 695 we keep the definition that comes first in process-environment. */ |
720 something missing here; | 761 something missing here; |
721 #endif /* vipc */ | 762 #endif /* vipc */ |
722 | 763 |
723 #ifdef WINDOWSNT | 764 #ifdef WINDOWSNT |
724 /* Spawn the child. (See ntproc.c:Spawnve). */ | 765 /* Spawn the child. (See ntproc.c:Spawnve). */ |
725 cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env); | 766 cpid = spawnve (_P_NOWAIT, new_argv[0], (const char* const*)new_argv, |
767 (const char* const*)env); | |
726 if (cpid == -1) | 768 if (cpid == -1) |
727 /* An error occurred while trying to spawn the process. */ | 769 /* An error occurred while trying to spawn the process. */ |
728 report_file_error ("Spawning child process", Qnil); | 770 report_file_error ("Spawning child process", Qnil); |
729 reset_standard_handles (in, out, err, handles); | 771 reset_standard_handles (in, out, err, handles); |
730 return cpid; | 772 return cpid; |
739 _exit (1); | 781 _exit (1); |
740 #endif /* not WINDOWSNT */ | 782 #endif /* not WINDOWSNT */ |
741 } | 783 } |
742 | 784 |
743 static int | 785 static int |
744 getenv_internal (CONST Bufbyte *var, | 786 getenv_internal (const Bufbyte *var, |
745 Bytecount varlen, | 787 Bytecount varlen, |
746 Bufbyte **value, | 788 Bufbyte **value, |
747 Bytecount *valuelen) | 789 Bytecount *valuelen) |
748 { | 790 { |
749 Lisp_Object scan; | 791 Lisp_Object scan; |
802 } | 844 } |
803 | 845 |
804 /* A version of getenv that consults process_environment, easily | 846 /* A version of getenv that consults process_environment, easily |
805 callable from C. */ | 847 callable from C. */ |
806 char * | 848 char * |
807 egetenv (CONST char *var) | 849 egetenv (const char *var) |
808 { | 850 { |
809 Bufbyte *value; | 851 Bufbyte *value; |
810 Bytecount valuelen; | 852 Bytecount valuelen; |
811 | 853 |
812 if (getenv_internal ((CONST Bufbyte *) var, strlen (var), &value, &valuelen)) | 854 if (getenv_internal ((const Bufbyte *) var, strlen (var), &value, &valuelen)) |
813 return (char *) value; | 855 return (char *) value; |
814 else | 856 else |
815 return 0; | 857 return 0; |
816 } | 858 } |
817 | 859 |
825 /* jwz: always initialize Vprocess_environment, so that egetenv() | 867 /* jwz: always initialize Vprocess_environment, so that egetenv() |
826 works in temacs. */ | 868 works in temacs. */ |
827 char **envp; | 869 char **envp; |
828 Vprocess_environment = Qnil; | 870 Vprocess_environment = Qnil; |
829 for (envp = environ; envp && *envp; envp++) | 871 for (envp = environ; envp && *envp; envp++) |
830 { | 872 Vprocess_environment = |
831 Vprocess_environment = Fcons (build_ext_string (*envp, FORMAT_OS), | 873 Fcons (build_ext_string (*envp, Qfile_name), Vprocess_environment); |
832 Vprocess_environment); | |
833 } | |
834 } | 874 } |
835 | 875 |
836 { | 876 { |
837 /* Initialize shell-file-name from environment variables or best guess. */ | 877 /* Initialize shell-file-name from environment variables or best guess. */ |
838 #ifdef WINDOWSNT | 878 #ifdef WINDOWSNT |
839 CONST char *shell = egetenv ("COMSPEC"); | 879 const char *shell = egetenv ("COMSPEC"); |
840 if (!shell) shell = "\\WINNT\\system32\\cmd.exe"; | 880 if (!shell) shell = "\\WINNT\\system32\\cmd.exe"; |
841 #else /* not WINDOWSNT */ | 881 #else /* not WINDOWSNT */ |
842 CONST char *shell = egetenv ("SHELL"); | 882 const char *shell = egetenv ("SHELL"); |
843 if (!shell) shell = "/bin/sh"; | 883 if (!shell) shell = "/bin/sh"; |
844 #endif | 884 #endif |
845 | 885 |
846 Vshell_file_name = build_string (shell); | 886 Vshell_file_name = build_string (shell); |
847 } | 887 } |
895 List of environment variables for subprocesses to inherit. | 935 List of environment variables for subprocesses to inherit. |
896 Each element should be a string of the form ENVVARNAME=VALUE. | 936 Each element should be a string of the form ENVVARNAME=VALUE. |
897 The environment which Emacs inherits is placed in this variable | 937 The environment which Emacs inherits is placed in this variable |
898 when Emacs starts. | 938 when Emacs starts. |
899 */ ); | 939 */ ); |
900 } | 940 |
941 Vlisp_EXEC_SUFFIXES = build_string (EXEC_SUFFIXES); | |
942 staticpro (&Vlisp_EXEC_SUFFIXES); | |
943 } |