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.