Mercurial > hg > xemacs-beta
comparison src/callproc.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 | a300bb07d72d |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
102 static Lisp_Object | 102 static Lisp_Object |
103 call_process_cleanup (Lisp_Object fdpid) | 103 call_process_cleanup (Lisp_Object fdpid) |
104 { | 104 { |
105 int fd = XINT (Fcar (fdpid)); | 105 int fd = XINT (Fcar (fdpid)); |
106 int pid = XINT (Fcdr (fdpid)); | 106 int pid = XINT (Fcdr (fdpid)); |
107 #ifdef WINDOWSNT | |
108 HANDLE pHandle; | |
109 #endif | |
110 | 107 |
111 if (!call_process_exited && | 108 if (!call_process_exited && |
112 EMACS_KILLPG (pid, SIGINT) == 0) | 109 EMACS_KILLPG (pid, SIGINT) == 0) |
113 { | 110 { |
114 int speccount = specpdl_depth (); | 111 int speccount = specpdl_depth (); |
115 | 112 |
116 record_unwind_protect (call_process_kill, fdpid); | 113 record_unwind_protect (call_process_kill, fdpid); |
117 /* #### "c-G" -- need non-consing Single-key-description */ | 114 /* #### "c-G" -- need non-consing Single-key-description */ |
118 message ("Waiting for process to die...(type C-g again to kill it instantly)"); | 115 message ("Waiting for process to die...(type C-g again to kill it instantly)"); |
119 | 116 |
120 #ifdef WINDOWSNT | |
121 pHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); | |
122 if (pHandle == NULL) | |
123 { | |
124 warn_when_safe (Qprocess, Qerror, | |
125 "OpenProcess returns NULL process handle."); | |
126 } | |
127 wait_for_termination (pHandle); | |
128 #else | |
129 wait_for_termination (pid); | 117 wait_for_termination (pid); |
130 #endif | |
131 | 118 |
132 /* "Discard" the unwind protect. */ | 119 /* "Discard" the unwind protect. */ |
133 XCAR (fdpid) = Qnil; | 120 XCAR (fdpid) = Qnil; |
134 XCDR (fdpid) = Qnil; | 121 XCDR (fdpid) = Qnil; |
135 unbind_to (speccount, Qnil); | 122 unbind_to (speccount, Qnil); |
181 { | 168 { |
182 /* This function can GC */ | 169 /* This function can GC */ |
183 Lisp_Object infile, buffer, current_dir, display, path; | 170 Lisp_Object infile, buffer, current_dir, display, path; |
184 int fd[2]; | 171 int fd[2]; |
185 int filefd; | 172 int filefd; |
186 #ifdef WINDOWSNT | |
187 HANDLE pHandle; | |
188 #endif | |
189 int pid; | 173 int pid; |
190 char buf[16384]; | 174 char buf[16384]; |
191 char *bufptr = buf; | 175 char *bufptr = buf; |
192 int bufsize = 16384; | 176 int bufsize = 16384; |
193 int speccount = specpdl_depth (); | 177 int speccount = specpdl_depth (); |
222 * called by various filename-hacking routines might relocate strings */ | 206 * called by various filename-hacking routines might relocate strings */ |
223 /* Make sure that the child will be able to chdir to the current | 207 /* Make sure that the child will be able to chdir to the current |
224 buffer's current directory. We can't just have the child check | 208 buffer's current directory. We can't just have the child check |
225 for an error when it does the chdir, since it's in a vfork. */ | 209 for an error when it does the chdir, since it's in a vfork. */ |
226 | 210 |
211 NGCPRO2 (current_dir, path); /* Caller gcprotects args[] */ | |
227 current_dir = current_buffer->directory; | 212 current_dir = current_buffer->directory; |
228 NGCPRO2 (current_dir, path); /* Caller gcprotects args[] */ | |
229 current_dir = Funhandled_file_name_directory (current_dir); | 213 current_dir = Funhandled_file_name_directory (current_dir); |
230 current_dir = expand_and_dir_to_file (current_dir, Qnil); | 214 current_dir = expand_and_dir_to_file (current_dir, Qnil); |
231 #if 0 | 215 #if 0 |
232 /* This is in FSF, but it breaks everything in the presence of | 216 /* This is in FSF, but it breaks everything in the presence of |
233 ange-ftp-visited files, so away with it. */ | 217 ange-ftp-visited files, so away with it. */ |
301 for (i = 4; i < nargs; i++) | 285 for (i = 4; i < nargs; i++) |
302 { | 286 { |
303 CHECK_STRING (args[i]); | 287 CHECK_STRING (args[i]); |
304 new_argv[i - 3] = (char *) XSTRING_DATA (args[i]); | 288 new_argv[i - 3] = (char *) XSTRING_DATA (args[i]); |
305 } | 289 } |
290 new_argv[nargs - 3] = 0; | |
306 } | 291 } |
307 new_argv[max(nargs - 3,1)] = 0; | |
308 | 292 |
309 if (NILP (path)) | 293 if (NILP (path)) |
310 report_file_error ("Searching for program", Fcons (args[0], Qnil)); | 294 report_file_error ("Searching for program", Fcons (args[0], Qnil)); |
311 new_argv[0] = (char *) XSTRING_DATA (path); | 295 new_argv[0] = (char *) XSTRING_DATA (path); |
312 | 296 |
370 ); | 354 ); |
371 } | 355 } |
372 | 356 |
373 if (fd_error < 0) | 357 if (fd_error < 0) |
374 { | 358 { |
375 int save_errno = errno; | |
376 close (filefd); | 359 close (filefd); |
377 close (fd[0]); | 360 close (fd[0]); |
378 if (fd1 >= 0) | 361 if (fd1 >= 0) |
379 close (fd1); | 362 close (fd1); |
380 errno = save_errno; | |
381 report_file_error ("Cannot open", Fcons(error_file, Qnil)); | 363 report_file_error ("Cannot open", Fcons(error_file, Qnil)); |
382 } | 364 } |
383 | 365 |
384 fork_error = Qnil; | 366 fork_error = Qnil; |
385 #ifdef WINDOWSNT | 367 #ifdef WINDOWSNT |
386 pid = child_setup (filefd, fd1, fd_error, new_argv, | 368 pid = child_setup (filefd, fd1, fd_error, new_argv, |
387 (char *) XSTRING_DATA (current_dir)); | 369 (char *) XSTRING_DATA (current_dir)); |
388 if (!INTP (buffer)) | |
389 { | |
390 /* OpenProcess() as soon after child_setup as possible. It's too | |
391 late once the process terminated. */ | |
392 pHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); | |
393 if (pHandle == NULL) | |
394 { | |
395 stderr_out ("Fcall_process_internal: pHandle == NULL, GetLastError () = %d, (int)pHandle = %d\n", GetLastError (), (int)pHandle); | |
396 } | |
397 } | |
398 /* Close STDERR into the parent process. We no longer need it. */ | |
399 if (fd_error >= 0) | |
400 close (fd_error); | |
401 #else /* not WINDOWSNT */ | 370 #else /* not WINDOWSNT */ |
402 pid = fork (); | 371 pid = fork (); |
403 | 372 |
404 if (pid == 0) | 373 if (pid == 0) |
405 { | 374 { |
435 } | 404 } |
436 | 405 |
437 if (!NILP (fork_error)) | 406 if (!NILP (fork_error)) |
438 signal_error (Qfile_error, fork_error); | 407 signal_error (Qfile_error, fork_error); |
439 | 408 |
440 #ifndef WINDOWSNT | |
441 if (pid < 0) | 409 if (pid < 0) |
442 { | 410 { |
443 int save_errno = errno; | |
444 if (fd[0] >= 0) | 411 if (fd[0] >= 0) |
445 close (fd[0]); | 412 close (fd[0]); |
446 errno = save_errno; | |
447 report_file_error ("Doing fork", Qnil); | 413 report_file_error ("Doing fork", Qnil); |
448 } | 414 } |
449 #endif | |
450 | 415 |
451 if (INTP (buffer)) | 416 if (INTP (buffer)) |
452 { | 417 { |
453 if (fd[0] >= 0) | 418 if (fd[0] >= 0) |
454 close (fd[0]); | 419 close (fd[0]); |
552 Lstream_close (XLSTREAM (instream)); | 517 Lstream_close (XLSTREAM (instream)); |
553 NUNGCPRO; | 518 NUNGCPRO; |
554 | 519 |
555 QUIT; | 520 QUIT; |
556 /* Wait for it to terminate, unless it already has. */ | 521 /* Wait for it to terminate, unless it already has. */ |
557 #ifdef WINDOWSNT | |
558 wait_for_termination (pHandle); | |
559 #else | |
560 wait_for_termination (pid); | 522 wait_for_termination (pid); |
561 #endif | |
562 | 523 |
563 /* Don't kill any children that the subprocess may have left behind | 524 /* Don't kill any children that the subprocess may have left behind |
564 when exiting. */ | 525 when exiting. */ |
565 call_process_exited = 1; | 526 call_process_exited = 1; |
566 unbind_to (speccount, Qnil); | 527 unbind_to (speccount, Qnil); |
613 #ifdef SET_EMACS_PRIORITY | 574 #ifdef SET_EMACS_PRIORITY |
614 if (emacs_priority != 0) | 575 if (emacs_priority != 0) |
615 nice (- emacs_priority); | 576 nice (- emacs_priority); |
616 #endif | 577 #endif |
617 | 578 |
618 /* Under Windows, we are not in a child process at all, so we should | |
619 not close handles inherited from the parent -- we are the parent | |
620 and doing so will screw up all manner of things! Similarly, most | |
621 of the rest of the cleanup done in this function is not done | |
622 under Windows. | |
623 | |
624 #### This entire child_setup() function is an utter and complete | |
625 piece of shit. I would rewrite it, at the very least splitting | |
626 out the Windows and non-Windows stuff into two completely | |
627 different functions; but instead I'm trying to make it go away | |
628 entirely, using the Lisp definition in process.el. What's left | |
629 is to fix up the routines in event-msw.c (and in event-Xt.c and | |
630 event-tty.c) to allow for stream devices to be handled correctly. | |
631 There isn't much to do, in fact, and I'll fix it shortly. That | |
632 way, the Lisp definition can be used non-interactively too. */ | |
633 #if !defined (NO_SUBPROCESSES) && !defined (WINDOWSNT) | 579 #if !defined (NO_SUBPROCESSES) && !defined (WINDOWSNT) |
634 /* Close Emacs's descriptors that this process should not have. */ | 580 /* Close Emacs's descriptors that this process should not have. */ |
635 close_process_descs (); | 581 close_process_descs (); |
636 #endif /* not NO_SUBPROCESSES */ | 582 #endif /* not NO_SUBPROCESSES */ |
637 #ifndef WINDOWSNT | |
638 close_load_descs (); | 583 close_load_descs (); |
639 #endif | |
640 | 584 |
641 /* Note that use of alloca is always safe here. It's obvious for systems | 585 /* Note that use of alloca is always safe here. It's obvious for systems |
642 that do not have true vfork or that have true (stack) alloca. | 586 that do not have true vfork or that have true (stack) alloca. |
643 If using vfork and C_ALLOCA it is safe because that changes | 587 If using vfork and C_ALLOCA it is safe because that changes |
644 the superior's static variables as if the superior had done alloca | 588 the superior's static variables as if the superior had done alloca |
798 to pass this environment is to set environ. Our caller | 742 to pass this environment is to set environ. Our caller |
799 is responsible for restoring the ambient value of environ. */ | 743 is responsible for restoring the ambient value of environ. */ |
800 environ = env; | 744 environ = env; |
801 execvp (new_argv[0], new_argv); | 745 execvp (new_argv[0], new_argv); |
802 | 746 |
803 stdout_out ("Can't exec program %s\n", new_argv[0]); | 747 stdout_out ("Cant't exec program %s\n", new_argv[0]); |
804 _exit (1); | 748 _exit (1); |
805 #endif /* not WINDOWSNT */ | 749 #endif /* not WINDOWSNT */ |
806 } | 750 } |
807 | 751 |
808 /* Move the file descriptor FD so that its number is not less than MIN. | 752 /* Move the file descriptor FD so that its number is not less than MIN. |