comparison src/callproc.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents a300bb07d72d
children bbff43aa5eb7
comparison
equal deleted inserted replaced
379:76b7d63099ad 380:8626e4521993
26 26
27 #include "buffer.h" 27 #include "buffer.h"
28 #include "commands.h" 28 #include "commands.h"
29 #include "insdel.h" 29 #include "insdel.h"
30 #include "lstream.h" 30 #include "lstream.h"
31 #include <paths.h>
32 #include "process.h" 31 #include "process.h"
33 #include "sysdep.h" 32 #include "sysdep.h"
34 #include "window.h" 33 #include "window.h"
35 #ifdef FILE_CODING 34 #ifdef FILE_CODING
36 #include "file-coding.h" 35 #include "file-coding.h"
312 #endif 311 #endif
313 } 312 }
314 313
315 { 314 {
316 /* child_setup must clobber environ in systems with true vfork. 315 /* child_setup must clobber environ in systems with true vfork.
317 Protect it from permanent change. */ 316 Protect it from permanent change. */
318 REGISTER char **save_environ = environ; 317 REGISTER char **save_environ = environ;
319 REGISTER int fd1 = fd[1]; 318 REGISTER int fd1 = fd[1];
320 int fd_error = fd1; 319 int fd_error = fd1;
321 char **env; 320 char **env;
322
323 #ifdef EMACS_BTL
324 /* when performance monitoring is on, turn it off before the vfork(),
325 as the child has no handler for the signal -- when back in the
326 parent process, turn it back on if it was really on when you "turned
327 it off" */
328 int logging_on = cadillac_stop_logging ();
329 #endif /* EMACS_BTL */
330 321
331 env = environ; 322 env = environ;
332 323
333 /* Record that we're about to create a synchronous process. */ 324 /* Record that we're about to create a synchronous process. */
334 synch_process_alive = 1; 325 synch_process_alive = 1;
383 file. */ 374 file. */
384 disconnect_controlling_terminal (); 375 disconnect_controlling_terminal ();
385 child_setup (filefd, fd1, fd_error, new_argv, 376 child_setup (filefd, fd1, fd_error, new_argv,
386 (char *) XSTRING_DATA (current_dir)); 377 (char *) XSTRING_DATA (current_dir));
387 } 378 }
388 #ifdef EMACS_BTL
389 else if (logging_on)
390 cadillac_start_logging ();
391 #endif
392 if (fd_error >= 0) 379 if (fd_error >= 0)
393 close (fd_error); 380 close (fd_error);
394 381
395 #endif /* not WINDOWSNT */ 382 #endif /* not WINDOWSNT */
396 383
532 } 519 }
533 } 520 }
534 521
535 522
536 523
524 /* Move the file descriptor FD so that its number is not less than MIN. *
525 The original file descriptor remains open. */
526 static int
527 relocate_fd (int fd, int min)
528 {
529 if (fd >= min)
530 return fd;
531 else
532 {
533 int newfd = dup (fd);
534 if (newfd == -1)
535 {
536 stderr_out ("Error while setting up child: %s\n",
537 strerror (errno));
538 _exit (1);
539 }
540 return relocate_fd (newfd, min);
541 }
542 }
543
537 /* This is the last thing run in a newly forked inferior 544 /* This is the last thing run in a newly forked inferior
538 either synchronous or asynchronous. 545 either synchronous or asynchronous.
539 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2. 546 Copy descriptors IN, OUT and ERR
547 as descriptors STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO.
540 Initialize inferior's priority, pgrp, connected dir and environment. 548 Initialize inferior's priority, pgrp, connected dir and environment.
541 then exec another program based on new_argv. 549 then exec another program based on new_argv.
542 550
543 This function may change environ for the superior process. 551 This function may change environ for the superior process.
544 Therefore, the superior process must save and restore the value 552 Therefore, the superior process must save and restore the value
551 559
552 CURRENT_DIR is an elisp string giving the path of the current 560 CURRENT_DIR is an elisp string giving the path of the current
553 directory the subprocess should have. Since we can't really signal 561 directory the subprocess should have. Since we can't really signal
554 a decent error from within the child, this should be verified as an 562 a decent error from within the child, this should be verified as an
555 executable directory by the parent. */ 563 executable directory by the parent. */
556
557 static int relocate_fd (int fd, int min);
558 564
559 #ifdef WINDOWSNT 565 #ifdef WINDOWSNT
560 int 566 int
561 #else 567 #else
562 void 568 void
683 #else /* not WINDOWSNT */ 689 #else /* not WINDOWSNT */
684 /* Make sure that in, out, and err are not actually already in 690 /* Make sure that in, out, and err are not actually already in
685 descriptors zero, one, or two; this could happen if Emacs is 691 descriptors zero, one, or two; this could happen if Emacs is
686 started with its standard in, out, or error closed, as might 692 started with its standard in, out, or error closed, as might
687 happen under X. */ 693 happen under X. */
688 { 694 in = relocate_fd (in, 3);
689 int oin = in, oout = out; 695 out = relocate_fd (out, 3);
690 696 err = relocate_fd (err, 3);
691 /* We have to avoid relocating the same descriptor twice! */ 697
692 698 /* Set the standard input/output channels of the new process. */
693 in = relocate_fd (in, 3); 699 close (STDIN_FILENO);
694 700 close (STDOUT_FILENO);
695 if (out == oin) out = in; 701 close (STDERR_FILENO);
696 else out = relocate_fd (out, 3); 702
697 703 dup2 (in, STDIN_FILENO);
698 if (err == oin) err = in; 704 dup2 (out, STDOUT_FILENO);
699 else if (err == oout) err = out; 705 dup2 (err, STDERR_FILENO);
700 else err = relocate_fd (err, 3); 706
701 }
702
703 close (0);
704 close (1);
705 close (2);
706
707 dup2 (in, 0);
708 dup2 (out, 1);
709 dup2 (err, 2);
710
711 close (in); 707 close (in);
712 close (out); 708 close (out);
713 close (err); 709 close (err);
714 710
715 /* I can't think of any reason why child processes need any more 711 /* I can't think of any reason why child processes need any more
717 close just the ones that need to be, but the following brute 713 close just the ones that need to be, but the following brute
718 force approach is certainly effective, and not too slow. */ 714 force approach is certainly effective, and not too slow. */
719 { 715 {
720 int fd; 716 int fd;
721 for (fd=3; fd<=64; fd++) 717 for (fd=3; fd<=64; fd++)
722 { 718 close (fd);
723 close(fd);
724 }
725 } 719 }
726 #endif /* not WINDOWSNT */ 720 #endif /* not WINDOWSNT */
727 721
728 #ifdef vipc 722 #ifdef vipc
729 something missing here; 723 something missing here;
745 execvp (new_argv[0], new_argv); 739 execvp (new_argv[0], new_argv);
746 740
747 stdout_out ("Can't exec program %s\n", new_argv[0]); 741 stdout_out ("Can't exec program %s\n", new_argv[0]);
748 _exit (1); 742 _exit (1);
749 #endif /* not WINDOWSNT */ 743 #endif /* not WINDOWSNT */
750 }
751
752 /* Move the file descriptor FD so that its number is not less than MIN.
753 If the file descriptor is moved at all, the original is freed. */
754 static int
755 relocate_fd (int fd, int min)
756 {
757 if (fd >= min)
758 return fd;
759 else
760 {
761 int new = dup (fd);
762 if (new == -1)
763 {
764 stderr_out ("Error while setting up child: %s\n",
765 strerror (errno));
766 _exit (1);
767 }
768 /* Note that we hold the original FD open while we recurse,
769 to guarantee we'll get a new FD if we need it. */
770 new = relocate_fd (new, min);
771 close (fd);
772 return new;
773 }
774 } 744 }
775 745
776 static int 746 static int
777 getenv_internal (CONST Bufbyte *var, 747 getenv_internal (CONST Bufbyte *var,
778 Bytecount varlen, 748 Bytecount varlen,