diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 156 |
1 files changed, 36 insertions, 120 deletions
diff --git a/src/process.c b/src/process.c index 007a07942e6..7b21d060cf8 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -91,6 +91,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 91 | #include <pty.h> | 91 | #include <pty.h> |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | #include <c-ctype.h> | ||
| 95 | #include <sig2str.h> | ||
| 96 | |||
| 94 | #endif /* subprocesses */ | 97 | #endif /* subprocesses */ |
| 95 | 98 | ||
| 96 | #include "systime.h" | 99 | #include "systime.h" |
| @@ -773,7 +776,6 @@ get_process (register Lisp_Object name) | |||
| 773 | } | 776 | } |
| 774 | 777 | ||
| 775 | 778 | ||
| 776 | #ifdef SIGCHLD | ||
| 777 | /* Fdelete_process promises to immediately forget about the process, but in | 779 | /* Fdelete_process promises to immediately forget about the process, but in |
| 778 | reality, Emacs needs to remember those processes until they have been | 780 | reality, Emacs needs to remember those processes until they have been |
| 779 | treated by the SIGCHLD handler and waitpid has been invoked on them; | 781 | treated by the SIGCHLD handler and waitpid has been invoked on them; |
| @@ -781,17 +783,14 @@ get_process (register Lisp_Object name) | |||
| 781 | 783 | ||
| 782 | Some processes created by call-process are also put onto this list. */ | 784 | Some processes created by call-process are also put onto this list. */ |
| 783 | static Lisp_Object deleted_pid_list; | 785 | static Lisp_Object deleted_pid_list; |
| 784 | #endif | ||
| 785 | 786 | ||
| 786 | void | 787 | void |
| 787 | record_deleted_pid (pid_t pid) | 788 | record_deleted_pid (pid_t pid) |
| 788 | { | 789 | { |
| 789 | #ifdef SIGCHLD | ||
| 790 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), | 790 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), |
| 791 | /* GC treated elements set to nil. */ | 791 | /* GC treated elements set to nil. */ |
| 792 | Fdelq (Qnil, deleted_pid_list)); | 792 | Fdelq (Qnil, deleted_pid_list)); |
| 793 | 793 | ||
| 794 | #endif | ||
| 795 | } | 794 | } |
| 796 | 795 | ||
| 797 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, | 796 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, |
| @@ -1581,9 +1580,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1581 | #ifndef WINDOWSNT | 1580 | #ifndef WINDOWSNT |
| 1582 | int wait_child_setup[2]; | 1581 | int wait_child_setup[2]; |
| 1583 | #endif | 1582 | #endif |
| 1584 | #ifdef SIGCHLD | ||
| 1585 | sigset_t blocked; | 1583 | sigset_t blocked; |
| 1586 | #endif | ||
| 1587 | /* Use volatile to protect variables from being clobbered by vfork. */ | 1584 | /* Use volatile to protect variables from being clobbered by vfork. */ |
| 1588 | volatile int forkin, forkout; | 1585 | volatile int forkin, forkout; |
| 1589 | volatile int pty_flag = 0; | 1586 | volatile int pty_flag = 0; |
| @@ -1680,13 +1677,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1680 | 1677 | ||
| 1681 | block_input (); | 1678 | block_input (); |
| 1682 | 1679 | ||
| 1683 | #ifdef SIGCHLD | ||
| 1684 | /* Block SIGCHLD until we have a chance to store the new fork's | 1680 | /* Block SIGCHLD until we have a chance to store the new fork's |
| 1685 | pid in its process structure. */ | 1681 | pid in its process structure. */ |
| 1686 | sigemptyset (&blocked); | 1682 | sigemptyset (&blocked); |
| 1687 | sigaddset (&blocked, SIGCHLD); | 1683 | sigaddset (&blocked, SIGCHLD); |
| 1688 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 1684 | pthread_sigmask (SIG_BLOCK, &blocked, 0); |
| 1689 | #endif | ||
| 1690 | 1685 | ||
| 1691 | #ifndef WINDOWSNT | 1686 | #ifndef WINDOWSNT |
| 1692 | pid = vfork (); | 1687 | pid = vfork (); |
| @@ -1794,10 +1789,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1794 | /* Emacs ignores SIGPIPE, but the child should not. */ | 1789 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 1795 | signal (SIGPIPE, SIG_DFL); | 1790 | signal (SIGPIPE, SIG_DFL); |
| 1796 | 1791 | ||
| 1797 | #ifdef SIGCHLD | ||
| 1798 | /* Stop blocking signals in the child. */ | 1792 | /* Stop blocking signals in the child. */ |
| 1799 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1793 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 1800 | #endif | ||
| 1801 | 1794 | ||
| 1802 | if (pty_flag) | 1795 | if (pty_flag) |
| 1803 | child_setup_tty (xforkout); | 1796 | child_setup_tty (xforkout); |
| @@ -1818,9 +1811,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1818 | XPROCESS (process)->alive = 1; | 1811 | XPROCESS (process)->alive = 1; |
| 1819 | 1812 | ||
| 1820 | /* Stop blocking signals in the parent. */ | 1813 | /* Stop blocking signals in the parent. */ |
| 1821 | #ifdef SIGCHLD | ||
| 1822 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1814 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 1823 | #endif | ||
| 1824 | unblock_input (); | 1815 | unblock_input (); |
| 1825 | 1816 | ||
| 1826 | if (pid < 0) | 1817 | if (pid < 0) |
| @@ -4612,7 +4603,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4612 | yielding EBADF here or at select() call above. | 4603 | yielding EBADF here or at select() call above. |
| 4613 | So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF | 4604 | So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF |
| 4614 | in m/ibmrt-aix.h), and here we just ignore the select error. | 4605 | in m/ibmrt-aix.h), and here we just ignore the select error. |
| 4615 | Cleanup occurs c/o status_notify after SIGCLD. */ | 4606 | Cleanup occurs c/o status_notify after SIGCHLD. */ |
| 4616 | no_avail = 1; /* Cannot depend on values returned */ | 4607 | no_avail = 1; /* Cannot depend on values returned */ |
| 4617 | #else | 4608 | #else |
| 4618 | emacs_abort (); | 4609 | emacs_abort (); |
| @@ -4810,10 +4801,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4810 | #endif /* HAVE_PTYS */ | 4801 | #endif /* HAVE_PTYS */ |
| 4811 | /* If we can detect process termination, don't consider the | 4802 | /* If we can detect process termination, don't consider the |
| 4812 | process gone just because its pipe is closed. */ | 4803 | process gone just because its pipe is closed. */ |
| 4813 | #ifdef SIGCHLD | ||
| 4814 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) | 4804 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) |
| 4815 | ; | 4805 | ; |
| 4816 | #endif | ||
| 4817 | else | 4806 | else |
| 4818 | { | 4807 | { |
| 4819 | /* Preserve status of processes already terminated. */ | 4808 | /* Preserve status of processes already terminated. */ |
| @@ -5676,7 +5665,7 @@ return t unconditionally. */) | |||
| 5676 | 5665 | ||
| 5677 | If we can, we try to signal PROCESS by sending control characters | 5666 | If we can, we try to signal PROCESS by sending control characters |
| 5678 | down the pty. This allows us to signal inferiors who have changed | 5667 | down the pty. This allows us to signal inferiors who have changed |
| 5679 | their uid, for which killpg would return an EPERM error. */ | 5668 | their uid, for which kill would return an EPERM error. */ |
| 5680 | 5669 | ||
| 5681 | static void | 5670 | static void |
| 5682 | process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | 5671 | process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, |
| @@ -5814,7 +5803,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5814 | if (!NILP (current_group)) | 5803 | if (!NILP (current_group)) |
| 5815 | { | 5804 | { |
| 5816 | if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) | 5805 | if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) |
| 5817 | EMACS_KILLPG (gid, signo); | 5806 | kill (-gid, signo); |
| 5818 | } | 5807 | } |
| 5819 | else | 5808 | else |
| 5820 | { | 5809 | { |
| @@ -5822,7 +5811,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5822 | kill (gid, signo); | 5811 | kill (gid, signo); |
| 5823 | } | 5812 | } |
| 5824 | #else /* ! defined (TIOCSIGSEND) */ | 5813 | #else /* ! defined (TIOCSIGSEND) */ |
| 5825 | EMACS_KILLPG (gid, signo); | 5814 | kill (-gid, signo); |
| 5826 | #endif /* ! defined (TIOCSIGSEND) */ | 5815 | #endif /* ! defined (TIOCSIGSEND) */ |
| 5827 | } | 5816 | } |
| 5828 | 5817 | ||
| @@ -5927,6 +5916,27 @@ traffic. */) | |||
| 5927 | return process; | 5916 | return process; |
| 5928 | } | 5917 | } |
| 5929 | 5918 | ||
| 5919 | /* Return the integer value of the signal whose abbreviation is ABBR, | ||
| 5920 | or a negative number if there is no such signal. */ | ||
| 5921 | static int | ||
| 5922 | abbr_to_signal (char const *name) | ||
| 5923 | { | ||
| 5924 | int i, signo; | ||
| 5925 | char sigbuf[20]; /* Large enough for all valid signal abbreviations. */ | ||
| 5926 | |||
| 5927 | if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3)) | ||
| 5928 | name += 3; | ||
| 5929 | |||
| 5930 | for (i = 0; i < sizeof sigbuf; i++) | ||
| 5931 | { | ||
| 5932 | sigbuf[i] = c_toupper (name[i]); | ||
| 5933 | if (! sigbuf[i]) | ||
| 5934 | return str2sig (sigbuf, &signo) == 0 ? signo : -1; | ||
| 5935 | } | ||
| 5936 | |||
| 5937 | return -1; | ||
| 5938 | } | ||
| 5939 | |||
| 5930 | DEFUN ("signal-process", Fsignal_process, Ssignal_process, | 5940 | DEFUN ("signal-process", Fsignal_process, Ssignal_process, |
| 5931 | 2, 2, "sProcess (name or number): \nnSignal code: ", | 5941 | 2, 2, "sProcess (name or number): \nnSignal code: ", |
| 5932 | doc: /* Send PROCESS the signal with code SIGCODE. | 5942 | doc: /* Send PROCESS the signal with code SIGCODE. |
| @@ -5937,6 +5947,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 5937 | (Lisp_Object process, Lisp_Object sigcode) | 5947 | (Lisp_Object process, Lisp_Object sigcode) |
| 5938 | { | 5948 | { |
| 5939 | pid_t pid; | 5949 | pid_t pid; |
| 5950 | int signo; | ||
| 5940 | 5951 | ||
| 5941 | if (STRINGP (process)) | 5952 | if (STRINGP (process)) |
| 5942 | { | 5953 | { |
| @@ -5966,12 +5977,11 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 5966 | error ("Cannot signal process %s", SDATA (XPROCESS (process)->name)); | 5977 | error ("Cannot signal process %s", SDATA (XPROCESS (process)->name)); |
| 5967 | } | 5978 | } |
| 5968 | 5979 | ||
| 5969 | #define parse_signal(NAME, VALUE) \ | ||
| 5970 | else if (!xstrcasecmp (name, NAME)) \ | ||
| 5971 | XSETINT (sigcode, VALUE) | ||
| 5972 | |||
| 5973 | if (INTEGERP (sigcode)) | 5980 | if (INTEGERP (sigcode)) |
| 5974 | CHECK_TYPE_RANGED_INTEGER (int, sigcode); | 5981 | { |
| 5982 | CHECK_TYPE_RANGED_INTEGER (int, sigcode); | ||
| 5983 | signo = XINT (sigcode); | ||
| 5984 | } | ||
| 5975 | else | 5985 | else |
| 5976 | { | 5986 | { |
| 5977 | char *name; | 5987 | char *name; |
| @@ -5979,96 +5989,12 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 5979 | CHECK_SYMBOL (sigcode); | 5989 | CHECK_SYMBOL (sigcode); |
| 5980 | name = SSDATA (SYMBOL_NAME (sigcode)); | 5990 | name = SSDATA (SYMBOL_NAME (sigcode)); |
| 5981 | 5991 | ||
| 5982 | if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3)) | 5992 | signo = abbr_to_signal (name); |
| 5983 | name += 3; | 5993 | if (signo < 0) |
| 5984 | |||
| 5985 | if (0) | ||
| 5986 | ; | ||
| 5987 | #ifdef SIGUSR1 | ||
| 5988 | parse_signal ("usr1", SIGUSR1); | ||
| 5989 | #endif | ||
| 5990 | #ifdef SIGUSR2 | ||
| 5991 | parse_signal ("usr2", SIGUSR2); | ||
| 5992 | #endif | ||
| 5993 | parse_signal ("term", SIGTERM); | ||
| 5994 | #ifdef SIGHUP | ||
| 5995 | parse_signal ("hup", SIGHUP); | ||
| 5996 | #endif | ||
| 5997 | parse_signal ("int", SIGINT); | ||
| 5998 | #ifdef SIGQUIT | ||
| 5999 | parse_signal ("quit", SIGQUIT); | ||
| 6000 | #endif | ||
| 6001 | parse_signal ("ill", SIGILL); | ||
| 6002 | parse_signal ("abrt", SIGABRT); | ||
| 6003 | #ifdef SIGEMT | ||
| 6004 | parse_signal ("emt", SIGEMT); | ||
| 6005 | #endif | ||
| 6006 | #ifdef SIGKILL | ||
| 6007 | parse_signal ("kill", SIGKILL); | ||
| 6008 | #endif | ||
| 6009 | parse_signal ("fpe", SIGFPE); | ||
| 6010 | #ifdef SIGBUS | ||
| 6011 | parse_signal ("bus", SIGBUS); | ||
| 6012 | #endif | ||
| 6013 | parse_signal ("segv", SIGSEGV); | ||
| 6014 | #ifdef SIGSYS | ||
| 6015 | parse_signal ("sys", SIGSYS); | ||
| 6016 | #endif | ||
| 6017 | #ifdef SIGPIPE | ||
| 6018 | parse_signal ("pipe", SIGPIPE); | ||
| 6019 | #endif | ||
| 6020 | #ifdef SIGALRM | ||
| 6021 | parse_signal ("alrm", SIGALRM); | ||
| 6022 | #endif | ||
| 6023 | #ifdef SIGURG | ||
| 6024 | parse_signal ("urg", SIGURG); | ||
| 6025 | #endif | ||
| 6026 | #ifdef SIGSTOP | ||
| 6027 | parse_signal ("stop", SIGSTOP); | ||
| 6028 | #endif | ||
| 6029 | #ifdef SIGTSTP | ||
| 6030 | parse_signal ("tstp", SIGTSTP); | ||
| 6031 | #endif | ||
| 6032 | #ifdef SIGCONT | ||
| 6033 | parse_signal ("cont", SIGCONT); | ||
| 6034 | #endif | ||
| 6035 | #ifdef SIGCHLD | ||
| 6036 | parse_signal ("chld", SIGCHLD); | ||
| 6037 | #endif | ||
| 6038 | #ifdef SIGTTIN | ||
| 6039 | parse_signal ("ttin", SIGTTIN); | ||
| 6040 | #endif | ||
| 6041 | #ifdef SIGTTOU | ||
| 6042 | parse_signal ("ttou", SIGTTOU); | ||
| 6043 | #endif | ||
| 6044 | #ifdef SIGIO | ||
| 6045 | parse_signal ("io", SIGIO); | ||
| 6046 | #endif | ||
| 6047 | #ifdef SIGXCPU | ||
| 6048 | parse_signal ("xcpu", SIGXCPU); | ||
| 6049 | #endif | ||
| 6050 | #ifdef SIGXFSZ | ||
| 6051 | parse_signal ("xfsz", SIGXFSZ); | ||
| 6052 | #endif | ||
| 6053 | #ifdef SIGVTALRM | ||
| 6054 | parse_signal ("vtalrm", SIGVTALRM); | ||
| 6055 | #endif | ||
| 6056 | #ifdef SIGPROF | ||
| 6057 | parse_signal ("prof", SIGPROF); | ||
| 6058 | #endif | ||
| 6059 | #ifdef SIGWINCH | ||
| 6060 | parse_signal ("winch", SIGWINCH); | ||
| 6061 | #endif | ||
| 6062 | #ifdef SIGINFO | ||
| 6063 | parse_signal ("info", SIGINFO); | ||
| 6064 | #endif | ||
| 6065 | else | ||
| 6066 | error ("Undefined signal name %s", name); | 5994 | error ("Undefined signal name %s", name); |
| 6067 | } | 5995 | } |
| 6068 | 5996 | ||
| 6069 | #undef parse_signal | 5997 | return make_number (kill (pid, signo)); |
| 6070 | |||
| 6071 | return make_number (kill (pid, XINT (sigcode))); | ||
| 6072 | } | 5998 | } |
| 6073 | 5999 | ||
| 6074 | DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, | 6000 | DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, |
| @@ -6150,8 +6076,6 @@ process has been transmitted to the serial port. */) | |||
| 6150 | return process; | 6076 | return process; |
| 6151 | } | 6077 | } |
| 6152 | 6078 | ||
| 6153 | #ifdef SIGCHLD | ||
| 6154 | |||
| 6155 | /* The main Emacs thread records child processes in three places: | 6079 | /* The main Emacs thread records child processes in three places: |
| 6156 | 6080 | ||
| 6157 | - Vprocess_alist, for asynchronous subprocesses, which are child | 6081 | - Vprocess_alist, for asynchronous subprocesses, which are child |
| @@ -6268,8 +6192,6 @@ deliver_child_signal (int sig) | |||
| 6268 | { | 6192 | { |
| 6269 | deliver_process_signal (sig, handle_child_signal); | 6193 | deliver_process_signal (sig, handle_child_signal); |
| 6270 | } | 6194 | } |
| 6271 | |||
| 6272 | #endif /* SIGCHLD */ | ||
| 6273 | 6195 | ||
| 6274 | 6196 | ||
| 6275 | static Lisp_Object | 6197 | static Lisp_Object |
| @@ -7118,7 +7040,6 @@ init_process_emacs (void) | |||
| 7118 | 7040 | ||
| 7119 | inhibit_sentinels = 0; | 7041 | inhibit_sentinels = 0; |
| 7120 | 7042 | ||
| 7121 | #ifdef SIGCHLD | ||
| 7122 | #ifndef CANNOT_DUMP | 7043 | #ifndef CANNOT_DUMP |
| 7123 | if (! noninteractive || initialized) | 7044 | if (! noninteractive || initialized) |
| 7124 | #endif | 7045 | #endif |
| @@ -7127,7 +7048,6 @@ init_process_emacs (void) | |||
| 7127 | emacs_sigaction_init (&action, deliver_child_signal); | 7048 | emacs_sigaction_init (&action, deliver_child_signal); |
| 7128 | sigaction (SIGCHLD, &action, 0); | 7049 | sigaction (SIGCHLD, &action, 0); |
| 7129 | } | 7050 | } |
| 7130 | #endif | ||
| 7131 | 7051 | ||
| 7132 | FD_ZERO (&input_wait_mask); | 7052 | FD_ZERO (&input_wait_mask); |
| 7133 | FD_ZERO (&non_keyboard_wait_mask); | 7053 | FD_ZERO (&non_keyboard_wait_mask); |
| @@ -7154,9 +7074,7 @@ init_process_emacs (void) | |||
| 7154 | #endif | 7074 | #endif |
| 7155 | 7075 | ||
| 7156 | Vprocess_alist = Qnil; | 7076 | Vprocess_alist = Qnil; |
| 7157 | #ifdef SIGCHLD | ||
| 7158 | deleted_pid_list = Qnil; | 7077 | deleted_pid_list = Qnil; |
| 7159 | #endif | ||
| 7160 | for (i = 0; i < MAXDESC; i++) | 7078 | for (i = 0; i < MAXDESC; i++) |
| 7161 | { | 7079 | { |
| 7162 | chan_process[i] = Qnil; | 7080 | chan_process[i] = Qnil; |
| @@ -7283,9 +7201,7 @@ syms_of_process (void) | |||
| 7283 | DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); | 7201 | DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); |
| 7284 | 7202 | ||
| 7285 | staticpro (&Vprocess_alist); | 7203 | staticpro (&Vprocess_alist); |
| 7286 | #ifdef SIGCHLD | ||
| 7287 | staticpro (&deleted_pid_list); | 7204 | staticpro (&deleted_pid_list); |
| 7288 | #endif | ||
| 7289 | 7205 | ||
| 7290 | #endif /* subprocesses */ | 7206 | #endif /* subprocesses */ |
| 7291 | 7207 | ||