diff options
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 238 |
1 files changed, 129 insertions, 109 deletions
diff --git a/src/callproc.c b/src/callproc.c index 0242755eb5f..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 | 145 | ||
| 131 | if (call_process_exited) | 146 | #ifndef MSDOS |
| 132 | { | 147 | /* If the process still exists, kill its process group. */ |
| 133 | emacs_close (fd); | 148 | if (synch_process_pid) |
| 134 | return Qnil; | ||
| 135 | } | ||
| 136 | |||
| 137 | if (EMACS_KILLPG (pid, SIGINT) == 0) | ||
| 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 */ |
| @@ -493,16 +516,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 493 | if (fd_output >= 0) | 516 | if (fd_output >= 0) |
| 494 | fd1 = fd_output; | 517 | fd1 = fd_output; |
| 495 | 518 | ||
| 496 | /* Record that we're about to create a synchronous process. */ | ||
| 497 | synch_process_alive = 1; | ||
| 498 | |||
| 499 | /* These vars record information from process termination. | ||
| 500 | Clear them now before process can possibly terminate, | ||
| 501 | to avoid timing error if process terminates soon. */ | ||
| 502 | synch_process_death = 0; | ||
| 503 | synch_process_retcode = 0; | ||
| 504 | synch_process_termsig = 0; | ||
| 505 | |||
| 506 | if (NILP (error_file)) | 519 | if (NILP (error_file)) |
| 507 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 520 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 508 | else if (STRINGP (error_file)) | 521 | else if (STRINGP (error_file)) |
| @@ -535,23 +548,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 535 | 548 | ||
| 536 | #ifdef MSDOS /* MW, July 1993 */ | 549 | #ifdef MSDOS /* MW, July 1993 */ |
| 537 | /* Note that on MSDOS `child_setup' actually returns the child process | 550 | /* Note that on MSDOS `child_setup' actually returns the child process |
| 538 | 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. */ |
| 539 | below. */ | ||
| 540 | 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); |
| 541 | 553 | child_errno = errno; | |
| 542 | /* Record that the synchronous process exited and note its | ||
| 543 | termination status. */ | ||
| 544 | synch_process_alive = 0; | ||
| 545 | synch_process_retcode = pid; | ||
| 546 | if (synch_process_retcode < 0) /* means it couldn't be exec'ed */ | ||
| 547 | { | ||
| 548 | synchronize_system_messages_locale (); | ||
| 549 | synch_process_death = strerror (errno); | ||
| 550 | } | ||
| 551 | 554 | ||
| 552 | emacs_close (outfilefd); | 555 | emacs_close (outfilefd); |
| 553 | if (fd_error != outfilefd) | 556 | if (fd_error != outfilefd) |
| 554 | 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; | ||
| 555 | fd1 = -1; /* No harm in closing that one! */ | 566 | fd1 = -1; /* No harm in closing that one! */ |
| 556 | if (tempfile) | 567 | if (tempfile) |
| 557 | { | 568 | { |
| @@ -569,12 +580,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 569 | else | 580 | else |
| 570 | fd0 = -1; /* We are not going to read from tempfile. */ | 581 | fd0 = -1; /* We are not going to read from tempfile. */ |
| 571 | #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 | |||
| 572 | #ifdef WINDOWSNT | 594 | #ifdef WINDOWSNT |
| 573 | 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); |
| 574 | #else /* not WINDOWSNT */ | 596 | #else /* not WINDOWSNT */ |
| 575 | 597 | ||
| 576 | block_input (); | ||
| 577 | |||
| 578 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 598 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 579 | { | 599 | { |
| 580 | Lisp_Object volatile buffer_volatile = buffer; | 600 | Lisp_Object volatile buffer_volatile = buffer; |
| @@ -593,6 +613,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 593 | char **volatile new_argv_volatile = new_argv; | 613 | char **volatile new_argv_volatile = new_argv; |
| 594 | 614 | ||
| 595 | pid = vfork (); | 615 | pid = vfork (); |
| 616 | child_errno = errno; | ||
| 596 | 617 | ||
| 597 | buffer = buffer_volatile; | 618 | buffer = buffer_volatile; |
| 598 | coding_systems = coding_systems_volatile; | 619 | coding_systems = coding_systems_volatile; |
| @@ -612,6 +633,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 612 | 633 | ||
| 613 | if (pid == 0) | 634 | if (pid == 0) |
| 614 | { | 635 | { |
| 636 | unblock_child_signal (); | ||
| 637 | |||
| 615 | if (fd0 >= 0) | 638 | if (fd0 >= 0) |
| 616 | emacs_close (fd0); | 639 | emacs_close (fd0); |
| 617 | 640 | ||
| @@ -623,11 +646,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 623 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 646 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
| 624 | } | 647 | } |
| 625 | 648 | ||
| 626 | vfork_errno = errno; | ||
| 627 | unblock_input (); | ||
| 628 | |||
| 629 | #endif /* not WINDOWSNT */ | 649 | #endif /* not WINDOWSNT */ |
| 630 | 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 | |||
| 631 | /* The MSDOS case did this already. */ | 664 | /* The MSDOS case did this already. */ |
| 632 | if (fd_error >= 0) | 665 | if (fd_error >= 0) |
| 633 | emacs_close (fd_error); | 666 | emacs_close (fd_error); |
| @@ -644,9 +677,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 644 | 677 | ||
| 645 | if (pid < 0) | 678 | if (pid < 0) |
| 646 | { | 679 | { |
| 647 | if (fd0 >= 0) | 680 | errno = child_errno; |
| 648 | emacs_close (fd0); | ||
| 649 | errno = vfork_errno; | ||
| 650 | report_file_error ("Doing vfork", Qnil); | 681 | report_file_error ("Doing vfork", Qnil); |
| 651 | } | 682 | } |
| 652 | 683 | ||
| @@ -657,19 +688,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 657 | return Qnil; | 688 | return Qnil; |
| 658 | } | 689 | } |
| 659 | 690 | ||
| 660 | /* Enable sending signal if user quits below. */ | ||
| 661 | call_process_exited = 0; | ||
| 662 | |||
| 663 | #if defined (MSDOS) | 691 | #if defined (MSDOS) |
| 664 | /* MSDOS needs different cleanup information. */ | 692 | /* MSDOS needs different cleanup information. */ |
| 665 | cleanup_info_tail = build_string (tempfile ? tempfile : ""); | ||
| 666 | #else | ||
| 667 | cleanup_info_tail = INTEGER_TO_CONS (pid); | ||
| 668 | #endif /* not MSDOS */ | ||
| 669 | record_unwind_protect (call_process_cleanup, | 693 | record_unwind_protect (call_process_cleanup, |
| 670 | Fcons (Fcurrent_buffer (), | 694 | Fcons (Fcurrent_buffer (), |
| 671 | Fcons (INTEGER_TO_CONS (fd0), | 695 | build_string (tempfile ? tempfile : ""))); |
| 672 | cleanup_info_tail))); | 696 | #endif |
| 673 | 697 | ||
| 674 | if (BUFFERP (buffer)) | 698 | if (BUFFERP (buffer)) |
| 675 | Fset_buffer (buffer); | 699 | Fset_buffer (buffer); |
| @@ -856,38 +880,34 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 856 | 880 | ||
| 857 | #ifndef MSDOS | 881 | #ifndef MSDOS |
| 858 | /* Wait for it to terminate, unless it already has. */ | 882 | /* Wait for it to terminate, unless it already has. */ |
| 859 | if (output_to_buffer) | 883 | wait_for_termination (pid, &status, !output_to_buffer); |
| 860 | wait_for_termination (pid); | ||
| 861 | else | ||
| 862 | interruptible_wait_for_termination (pid); | ||
| 863 | #endif | 884 | #endif |
| 864 | 885 | ||
| 865 | immediate_quit = 0; | 886 | immediate_quit = 0; |
| 866 | 887 | ||
| 867 | /* 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 |
| 868 | when exiting. */ | 889 | when exiting. */ |
| 869 | call_process_exited = 1; | 890 | synch_process_pid = 0; |
| 870 | 891 | ||
| 871 | SAFE_FREE (); | 892 | SAFE_FREE (); |
| 872 | unbind_to (count, Qnil); | 893 | unbind_to (count, Qnil); |
| 873 | 894 | ||
| 874 | if (synch_process_termsig) | 895 | if (WIFSIGNALED (status)) |
| 875 | { | 896 | { |
| 876 | const char *signame; | 897 | const char *signame; |
| 877 | 898 | ||
| 878 | synchronize_system_messages_locale (); | 899 | synchronize_system_messages_locale (); |
| 879 | signame = strsignal (synch_process_termsig); | 900 | signame = strsignal (WTERMSIG (status)); |
| 880 | 901 | ||
| 881 | if (signame == 0) | 902 | if (signame == 0) |
| 882 | signame = "unknown"; | 903 | signame = "unknown"; |
| 883 | 904 | ||
| 884 | synch_process_death = signame; | 905 | return code_convert_string_norecord (build_string (signame), |
| 906 | Vlocale_coding_system, 0); | ||
| 885 | } | 907 | } |
| 886 | 908 | ||
| 887 | if (synch_process_death) | 909 | eassert (WIFEXITED (status)); |
| 888 | return code_convert_string_norecord (build_string (synch_process_death), | 910 | return make_number (WEXITSTATUS (status)); |
| 889 | Vlocale_coding_system, 0); | ||
| 890 | return make_number (synch_process_retcode); | ||
| 891 | } | 911 | } |
| 892 | 912 | ||
| 893 | static Lisp_Object | 913 | static Lisp_Object |