Mercurial > hg > xemacs-beta
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, |