diff options
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 255 |
1 files changed, 130 insertions, 125 deletions
diff --git a/src/callproc.c b/src/callproc.c index 167663a45c6..21c52d09e6b 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -67,88 +67,110 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 67 | /* Pattern used by call-process-region to make temp files. */ | 67 | /* Pattern used by call-process-region to make temp files. */ |
| 68 | static Lisp_Object Vtemp_file_name_pattern; | 68 | static Lisp_Object Vtemp_file_name_pattern; |
| 69 | 69 | ||
| 70 | /* True if we are about to fork off a synchronous process or if we | 70 | /* The next two variables are valid only while record-unwind-protect |
| 71 | are waiting for it. */ | 71 | is in place during call-process for a synchronous subprocess. At |
| 72 | bool synch_process_alive; | 72 | other times, their contents are irrelevant. Doing this via static |
| 73 | 73 | C variables is more convenient than putting them into the arguments | |
| 74 | /* Nonzero => this is a string explaining death of synchronous subprocess. */ | 74 | of record-unwind-protect, as they need to be updated at randomish |
| 75 | const char *synch_process_death; | 75 | times in the code, and Lisp cannot always store these values as |
| 76 | Emacs integers. It's safe to use static variables here, as the | ||
| 77 | code is never invoked reentrantly. */ | ||
| 78 | |||
| 79 | /* If nonzero, a process-ID that has not been reaped. */ | ||
| 80 | static pid_t synch_process_pid; | ||
| 81 | |||
| 82 | /* If nonnegative, a file descriptor that has not been closed. */ | ||
| 83 | static int synch_process_fd; | ||
| 84 | |||
| 85 | /* Block SIGCHLD. */ | ||
| 76 | 86 | ||
| 77 | /* Nonzero => this is the signal number that terminated the subprocess. */ | 87 | static void |
| 78 | int synch_process_termsig; | 88 | block_child_signal (void) |
| 89 | { | ||
| 90 | #ifdef SIGCHLD | ||
| 91 | sigset_t blocked; | ||
| 92 | sigemptyset (&blocked); | ||
| 93 | sigaddset (&blocked, SIGCHLD); | ||
| 94 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 95 | #endif | ||
| 96 | } | ||
| 79 | 97 | ||
| 80 | /* If synch_process_death is zero, | 98 | /* Unblock SIGCHLD. */ |
| 81 | this is exit code of synchronous subprocess. */ | ||
| 82 | int synch_process_retcode; | ||
| 83 | 99 | ||
| 84 | 100 | static void | |
| 85 | /* Clean up when exiting Fcall_process. | 101 | unblock_child_signal (void) |
| 86 | On MSDOS, delete the temporary file on any kind of termination. | 102 | { |
| 87 | On Unix, kill the process and any children on termination by signal. */ | 103 | #ifdef SIGCHLD |
| 104 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | ||
| 105 | #endif | ||
| 106 | } | ||
| 88 | 107 | ||
| 89 | /* True if this is termination due to exit. */ | 108 | /* Clean up when exiting call_process_cleanup. */ |
| 90 | static bool call_process_exited; | ||
| 91 | 109 | ||
| 92 | static Lisp_Object | 110 | static Lisp_Object |
| 93 | call_process_kill (Lisp_Object fdpid) | 111 | call_process_kill (Lisp_Object ignored) |
| 94 | { | 112 | { |
| 95 | int fd; | 113 | if (0 <= synch_process_fd) |
| 96 | pid_t pid; | 114 | emacs_close (synch_process_fd); |
| 97 | CONS_TO_INTEGER (Fcar (fdpid), int, fd); | 115 | |
| 98 | CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); | 116 | /* If PID is reapable, kill it and record it as a deleted process. |
| 99 | emacs_close (fd); | 117 | Do this in a critical section. Unless PID is wedged it will be |
| 100 | EMACS_KILLPG (pid, SIGKILL); | 118 | reaped on receipt of the first SIGCHLD after the critical section. */ |
| 101 | synch_process_alive = 0; | 119 | if (synch_process_pid) |
| 120 | { | ||
| 121 | block_child_signal (); | ||
| 122 | record_deleted_pid (synch_process_pid); | ||
| 123 | EMACS_KILLPG (synch_process_pid, SIGKILL); | ||
| 124 | unblock_child_signal (); | ||
| 125 | } | ||
| 126 | |||
| 102 | return Qnil; | 127 | return Qnil; |
| 103 | } | 128 | } |
| 104 | 129 | ||
| 130 | /* Clean up when exiting Fcall_process. | ||
| 131 | On MSDOS, delete the temporary file on any kind of termination. | ||
| 132 | On Unix, kill the process and any children on termination by signal. */ | ||
| 133 | |||
| 105 | static Lisp_Object | 134 | static Lisp_Object |
| 106 | call_process_cleanup (Lisp_Object arg) | 135 | call_process_cleanup (Lisp_Object arg) |
| 107 | { | 136 | { |
| 108 | Lisp_Object fdpid = Fcdr (arg); | 137 | #ifdef MSDOS |
| 109 | int fd; | 138 | Lisp_Object buffer = Fcar (arg); |
| 110 | #if defined (MSDOS) | 139 | Lisp_Object file = Fcdr (arg); |
| 111 | Lisp_Object file; | ||
| 112 | #else | 140 | #else |
| 113 | pid_t pid; | 141 | Lisp_Object buffer = arg; |
| 114 | #endif | 142 | #endif |
| 115 | 143 | ||
| 116 | Fset_buffer (Fcar (arg)); | 144 | Fset_buffer (buffer); |
| 117 | CONS_TO_INTEGER (Fcar (fdpid), int, fd); | ||
| 118 | |||
| 119 | #if defined (MSDOS) | ||
| 120 | /* for MSDOS fdpid is really (fd . tempfile) */ | ||
| 121 | file = Fcdr (fdpid); | ||
| 122 | /* FD is -1 and FILE is "" when we didn't actually create a | ||
| 123 | temporary file in call-process. */ | ||
| 124 | if (fd >= 0) | ||
| 125 | emacs_close (fd); | ||
| 126 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | ||
| 127 | unlink (SDATA (file)); | ||
| 128 | #else /* not MSDOS */ | ||
| 129 | CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); | ||
| 130 | |||
| 131 | if (call_process_exited) | ||
| 132 | { | ||
| 133 | emacs_close (fd); | ||
| 134 | return Qnil; | ||
| 135 | } | ||
| 136 | 145 | ||
| 137 | if (EMACS_KILLPG (pid, SIGINT) == 0) | 146 | #ifndef MSDOS |
| 147 | /* If the process still exists, kill its process group. */ | ||
| 148 | if (synch_process_pid) | ||
| 138 | { | 149 | { |
| 139 | ptrdiff_t count = SPECPDL_INDEX (); | 150 | ptrdiff_t count = SPECPDL_INDEX (); |
| 140 | record_unwind_protect (call_process_kill, fdpid); | 151 | EMACS_KILLPG (synch_process_pid, SIGINT); |
| 152 | record_unwind_protect (call_process_kill, make_number (0)); | ||
| 141 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); | 153 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); |
| 142 | immediate_quit = 1; | 154 | immediate_quit = 1; |
| 143 | QUIT; | 155 | QUIT; |
| 144 | wait_for_termination (pid); | 156 | wait_for_termination (synch_process_pid, 0, 1); |
| 157 | synch_process_pid = 0; | ||
| 145 | immediate_quit = 0; | 158 | immediate_quit = 0; |
| 146 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ | 159 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ |
| 147 | message1 ("Waiting for process to die...done"); | 160 | message1 ("Waiting for process to die...done"); |
| 148 | } | 161 | } |
| 149 | synch_process_alive = 0; | 162 | #endif |
| 150 | emacs_close (fd); | 163 | |
| 151 | #endif /* not MSDOS */ | 164 | if (0 <= synch_process_fd) |
| 165 | emacs_close (synch_process_fd); | ||
| 166 | |||
| 167 | #ifdef MSDOS | ||
| 168 | /* FILE is "" when we didn't actually create a temporary file in | ||
| 169 | call-process. */ | ||
| 170 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | ||
| 171 | unlink (SDATA (file)); | ||
| 172 | #endif | ||
| 173 | |||
| 152 | return Qnil; | 174 | return Qnil; |
| 153 | } | 175 | } |
| 154 | 176 | ||
| @@ -181,9 +203,10 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | |||
| 181 | usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | 203 | usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) |
| 182 | (ptrdiff_t nargs, Lisp_Object *args) | 204 | (ptrdiff_t nargs, Lisp_Object *args) |
| 183 | { | 205 | { |
| 184 | Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail; | 206 | Lisp_Object infile, buffer, current_dir, path; |
| 185 | bool display_p; | 207 | bool display_p; |
| 186 | int fd0, fd1, filefd; | 208 | int fd0, fd1, filefd; |
| 209 | int status; | ||
| 187 | ptrdiff_t count = SPECPDL_INDEX (); | 210 | ptrdiff_t count = SPECPDL_INDEX (); |
| 188 | USE_SAFE_ALLOCA; | 211 | USE_SAFE_ALLOCA; |
| 189 | 212 | ||
| @@ -199,7 +222,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 199 | #else | 222 | #else |
| 200 | pid_t pid; | 223 | pid_t pid; |
| 201 | #endif | 224 | #endif |
| 202 | int vfork_errno; | 225 | int child_errno; |
| 203 | int fd_output = -1; | 226 | int fd_output = -1; |
| 204 | struct coding_system process_coding; /* coding-system of process output */ | 227 | struct coding_system process_coding; /* coding-system of process output */ |
| 205 | struct coding_system argument_coding; /* coding-system of arguments */ | 228 | struct coding_system argument_coding; /* coding-system of arguments */ |
| @@ -488,24 +511,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 488 | } | 511 | } |
| 489 | 512 | ||
| 490 | { | 513 | { |
| 491 | /* child_setup must clobber environ in systems with true vfork. | ||
| 492 | Protect it from permanent change. */ | ||
| 493 | char **save_environ = environ; | ||
| 494 | int fd_error = fd1; | 514 | int fd_error = fd1; |
| 495 | 515 | ||
| 496 | if (fd_output >= 0) | 516 | if (fd_output >= 0) |
| 497 | fd1 = fd_output; | 517 | fd1 = fd_output; |
| 498 | 518 | ||
| 499 | /* Record that we're about to create a synchronous process. */ | ||
| 500 | synch_process_alive = 1; | ||
| 501 | |||
| 502 | /* These vars record information from process termination. | ||
| 503 | Clear them now before process can possibly terminate, | ||
| 504 | to avoid timing error if process terminates soon. */ | ||
| 505 | synch_process_death = 0; | ||
| 506 | synch_process_retcode = 0; | ||
| 507 | synch_process_termsig = 0; | ||
| 508 | |||
| 509 | if (NILP (error_file)) | 519 | if (NILP (error_file)) |
| 510 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 520 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 511 | else if (STRINGP (error_file)) | 521 | else if (STRINGP (error_file)) |
| @@ -538,23 +548,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 538 | 548 | ||
| 539 | #ifdef MSDOS /* MW, July 1993 */ | 549 | #ifdef MSDOS /* MW, July 1993 */ |
| 540 | /* Note that on MSDOS `child_setup' actually returns the child process | 550 | /* Note that on MSDOS `child_setup' actually returns the child process |
| 541 | exit status, not its PID, so we assign it to `synch_process_retcode' | 551 | exit status, not its PID, so assign it to status below. */ |
| 542 | below. */ | ||
| 543 | pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); | 552 | pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); |
| 544 | 553 | child_errno = errno; | |
| 545 | /* Record that the synchronous process exited and note its | ||
| 546 | termination status. */ | ||
| 547 | synch_process_alive = 0; | ||
| 548 | synch_process_retcode = pid; | ||
| 549 | if (synch_process_retcode < 0) /* means it couldn't be exec'ed */ | ||
| 550 | { | ||
| 551 | synchronize_system_messages_locale (); | ||
| 552 | synch_process_death = strerror (errno); | ||
| 553 | } | ||
| 554 | 554 | ||
| 555 | emacs_close (outfilefd); | 555 | emacs_close (outfilefd); |
| 556 | if (fd_error != outfilefd) | 556 | if (fd_error != outfilefd) |
| 557 | emacs_close (fd_error); | 557 | emacs_close (fd_error); |
| 558 | if (pid < 0) | ||
| 559 | { | ||
| 560 | synchronize_system_messages_locale (); | ||
| 561 | return | ||
| 562 | code_convert_string_norecord (build_string (strerror (child_errno)), | ||
| 563 | Vlocale_coding_system, 0); | ||
| 564 | } | ||
| 565 | status = pid; | ||
| 558 | fd1 = -1; /* No harm in closing that one! */ | 566 | fd1 = -1; /* No harm in closing that one! */ |
| 559 | if (tempfile) | 567 | if (tempfile) |
| 560 | { | 568 | { |
| @@ -572,12 +580,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 572 | else | 580 | else |
| 573 | fd0 = -1; /* We are not going to read from tempfile. */ | 581 | fd0 = -1; /* We are not going to read from tempfile. */ |
| 574 | #else /* not MSDOS */ | 582 | #else /* not MSDOS */ |
| 583 | |||
| 584 | /* Do the unwind-protect now, even though the pid is not known, so | ||
| 585 | that no storage allocation is done in the critical section. | ||
| 586 | The actual PID will be filled in during the critical section. */ | ||
| 587 | synch_process_pid = 0; | ||
| 588 | synch_process_fd = fd0; | ||
| 589 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); | ||
| 590 | |||
| 591 | block_input (); | ||
| 592 | block_child_signal (); | ||
| 593 | |||
| 575 | #ifdef WINDOWSNT | 594 | #ifdef WINDOWSNT |
| 576 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 595 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
| 577 | #else /* not WINDOWSNT */ | 596 | #else /* not WINDOWSNT */ |
| 578 | 597 | ||
| 579 | block_input (); | ||
| 580 | |||
| 581 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 598 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 582 | { | 599 | { |
| 583 | Lisp_Object volatile buffer_volatile = buffer; | 600 | Lisp_Object volatile buffer_volatile = buffer; |
| @@ -594,9 +611,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 594 | ptrdiff_t volatile count_volatile = count; | 611 | ptrdiff_t volatile count_volatile = count; |
| 595 | ptrdiff_t volatile sa_count_volatile = sa_count; | 612 | ptrdiff_t volatile sa_count_volatile = sa_count; |
| 596 | char **volatile new_argv_volatile = new_argv; | 613 | char **volatile new_argv_volatile = new_argv; |
| 597 | char **volatile new_save_environ = save_environ; | ||
| 598 | 614 | ||
| 599 | pid = vfork (); | 615 | pid = vfork (); |
| 616 | child_errno = errno; | ||
| 600 | 617 | ||
| 601 | buffer = buffer_volatile; | 618 | buffer = buffer_volatile; |
| 602 | coding_systems = coding_systems_volatile; | 619 | coding_systems = coding_systems_volatile; |
| @@ -612,11 +629,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 612 | count = count_volatile; | 629 | count = count_volatile; |
| 613 | sa_count = sa_count_volatile; | 630 | sa_count = sa_count_volatile; |
| 614 | new_argv = new_argv_volatile; | 631 | new_argv = new_argv_volatile; |
| 615 | save_environ = new_save_environ; | ||
| 616 | } | 632 | } |
| 617 | 633 | ||
| 618 | if (pid == 0) | 634 | if (pid == 0) |
| 619 | { | 635 | { |
| 636 | unblock_child_signal (); | ||
| 637 | |||
| 620 | if (fd0 >= 0) | 638 | if (fd0 >= 0) |
| 621 | emacs_close (fd0); | 639 | emacs_close (fd0); |
| 622 | 640 | ||
| @@ -628,18 +646,26 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 628 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 646 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
| 629 | } | 647 | } |
| 630 | 648 | ||
| 631 | vfork_errno = errno; | ||
| 632 | unblock_input (); | ||
| 633 | |||
| 634 | #endif /* not WINDOWSNT */ | 649 | #endif /* not WINDOWSNT */ |
| 635 | 650 | ||
| 651 | child_errno = errno; | ||
| 652 | |||
| 653 | if (0 < pid) | ||
| 654 | { | ||
| 655 | if (INTEGERP (buffer)) | ||
| 656 | record_deleted_pid (pid); | ||
| 657 | else | ||
| 658 | synch_process_pid = pid; | ||
| 659 | } | ||
| 660 | |||
| 661 | unblock_child_signal (); | ||
| 662 | unblock_input (); | ||
| 663 | |||
| 636 | /* The MSDOS case did this already. */ | 664 | /* The MSDOS case did this already. */ |
| 637 | if (fd_error >= 0) | 665 | if (fd_error >= 0) |
| 638 | emacs_close (fd_error); | 666 | emacs_close (fd_error); |
| 639 | #endif /* not MSDOS */ | 667 | #endif /* not MSDOS */ |
| 640 | 668 | ||
| 641 | environ = save_environ; | ||
| 642 | |||
| 643 | /* Close most of our file descriptors, but not fd0 | 669 | /* Close most of our file descriptors, but not fd0 |
| 644 | since we will use that to read input from. */ | 670 | since we will use that to read input from. */ |
| 645 | emacs_close (filefd); | 671 | emacs_close (filefd); |
| @@ -651,9 +677,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 651 | 677 | ||
| 652 | if (pid < 0) | 678 | if (pid < 0) |
| 653 | { | 679 | { |
| 654 | if (fd0 >= 0) | 680 | errno = child_errno; |
| 655 | emacs_close (fd0); | ||
| 656 | errno = vfork_errno; | ||
| 657 | report_file_error ("Doing vfork", Qnil); | 681 | report_file_error ("Doing vfork", Qnil); |
| 658 | } | 682 | } |
| 659 | 683 | ||
| @@ -664,19 +688,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 664 | return Qnil; | 688 | return Qnil; |
| 665 | } | 689 | } |
| 666 | 690 | ||
| 667 | /* Enable sending signal if user quits below. */ | ||
| 668 | call_process_exited = 0; | ||
| 669 | |||
| 670 | #if defined (MSDOS) | 691 | #if defined (MSDOS) |
| 671 | /* MSDOS needs different cleanup information. */ | 692 | /* MSDOS needs different cleanup information. */ |
| 672 | cleanup_info_tail = build_string (tempfile ? tempfile : ""); | ||
| 673 | #else | ||
| 674 | cleanup_info_tail = INTEGER_TO_CONS (pid); | ||
| 675 | #endif /* not MSDOS */ | ||
| 676 | record_unwind_protect (call_process_cleanup, | 693 | record_unwind_protect (call_process_cleanup, |
| 677 | Fcons (Fcurrent_buffer (), | 694 | Fcons (Fcurrent_buffer (), |
| 678 | Fcons (INTEGER_TO_CONS (fd0), | 695 | build_string (tempfile ? tempfile : ""))); |
| 679 | cleanup_info_tail))); | 696 | #endif |
| 680 | 697 | ||
| 681 | if (BUFFERP (buffer)) | 698 | if (BUFFERP (buffer)) |
| 682 | Fset_buffer (buffer); | 699 | Fset_buffer (buffer); |
| @@ -863,38 +880,34 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 863 | 880 | ||
| 864 | #ifndef MSDOS | 881 | #ifndef MSDOS |
| 865 | /* Wait for it to terminate, unless it already has. */ | 882 | /* Wait for it to terminate, unless it already has. */ |
| 866 | if (output_to_buffer) | 883 | wait_for_termination (pid, &status, !output_to_buffer); |
| 867 | wait_for_termination (pid); | ||
| 868 | else | ||
| 869 | interruptible_wait_for_termination (pid); | ||
| 870 | #endif | 884 | #endif |
| 871 | 885 | ||
| 872 | immediate_quit = 0; | 886 | immediate_quit = 0; |
| 873 | 887 | ||
| 874 | /* Don't kill any children that the subprocess may have left behind | 888 | /* Don't kill any children that the subprocess may have left behind |
| 875 | when exiting. */ | 889 | when exiting. */ |
| 876 | call_process_exited = 1; | 890 | synch_process_pid = 0; |
| 877 | 891 | ||
| 878 | SAFE_FREE (); | 892 | SAFE_FREE (); |
| 879 | unbind_to (count, Qnil); | 893 | unbind_to (count, Qnil); |
| 880 | 894 | ||
| 881 | if (synch_process_termsig) | 895 | if (WIFSIGNALED (status)) |
| 882 | { | 896 | { |
| 883 | const char *signame; | 897 | const char *signame; |
| 884 | 898 | ||
| 885 | synchronize_system_messages_locale (); | 899 | synchronize_system_messages_locale (); |
| 886 | signame = strsignal (synch_process_termsig); | 900 | signame = strsignal (WTERMSIG (status)); |
| 887 | 901 | ||
| 888 | if (signame == 0) | 902 | if (signame == 0) |
| 889 | signame = "unknown"; | 903 | signame = "unknown"; |
| 890 | 904 | ||
| 891 | synch_process_death = signame; | 905 | return code_convert_string_norecord (build_string (signame), |
| 906 | Vlocale_coding_system, 0); | ||
| 892 | } | 907 | } |
| 893 | 908 | ||
| 894 | if (synch_process_death) | 909 | eassert (WIFEXITED (status)); |
| 895 | return code_convert_string_norecord (build_string (synch_process_death), | 910 | return make_number (WEXITSTATUS (status)); |
| 896 | Vlocale_coding_system, 0); | ||
| 897 | return make_number (synch_process_retcode); | ||
| 898 | } | 911 | } |
| 899 | 912 | ||
| 900 | static Lisp_Object | 913 | static Lisp_Object |
| @@ -1092,10 +1105,6 @@ add_env (char **env, char **new_env, char *string) | |||
| 1092 | Initialize inferior's priority, pgrp, connected dir and environment. | 1105 | Initialize inferior's priority, pgrp, connected dir and environment. |
| 1093 | then exec another program based on new_argv. | 1106 | then exec another program based on new_argv. |
| 1094 | 1107 | ||
| 1095 | This function may change environ for the superior process. | ||
| 1096 | Therefore, the superior process must save and restore the value | ||
| 1097 | of environ around the vfork and the call to this function. | ||
| 1098 | |||
| 1099 | If SET_PGRP, put the subprocess into a separate process group. | 1108 | If SET_PGRP, put the subprocess into a separate process group. |
| 1100 | 1109 | ||
| 1101 | CURRENT_DIR is an elisp string giving the path of the current | 1110 | CURRENT_DIR is an elisp string giving the path of the current |
| @@ -1298,11 +1307,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1298 | setpgid (0, 0); | 1307 | setpgid (0, 0); |
| 1299 | tcsetpgrp (0, pid); | 1308 | tcsetpgrp (0, pid); |
| 1300 | 1309 | ||
| 1301 | /* execvp does not accept an environment arg so the only way | 1310 | execve (new_argv[0], new_argv, env); |
| 1302 | to pass this environment is to set environ. Our caller | ||
| 1303 | is responsible for restoring the ambient value of environ. */ | ||
| 1304 | environ = env; | ||
| 1305 | execvp (new_argv[0], new_argv); | ||
| 1306 | 1311 | ||
| 1307 | emacs_write (1, "Can't exec program: ", 20); | 1312 | emacs_write (1, "Can't exec program: ", 20); |
| 1308 | emacs_write (1, new_argv[0], strlen (new_argv[0])); | 1313 | emacs_write (1, new_argv[0], strlen (new_argv[0])); |