# HG changeset patch # User Christian Brabandt # Date 1501619404 -7200 # Node ID cca097489de57e36e34d673c96ae8ab73cfc3687 # Parent 7075721ff2840b3068a2b70b57cd2a262f8121ac patch 8.0.0839: cannot kill a job in a terminal with CTRL-C commit https://github.com/vim/vim/commit/fae428354213b54626ff9e29faa5fd86161da942 Author: Bram Moolenaar Date: Tue Aug 1 22:24:26 2017 +0200 patch 8.0.0839: cannot kill a job in a terminal with CTRL-C Problem: Cannot kill a job in a terminal with CTRL-C. Solution: Set the controlling tty and send SIGINT. (closes https://github.com/vim/vim/issues/1910) diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4194,6 +4194,26 @@ open_pty(int *pty_master_fd, int *pty_sl } #endif +/* + * Send SIGINT to a child process if "c" is an interrupt character. + */ + void +may_send_sigint(int c UNUSED, pid_t pid UNUSED, pid_t wpid UNUSED) +{ +# ifdef SIGINT + if (c == Ctrl_C || c == intr_char) + { +# ifdef HAVE_SETSID + kill(-pid, SIGINT); +# else + kill(0, SIGINT); +# endif + if (wpid > 0) + kill(wpid, SIGINT); + } +# endif +} + int mch_call_shell( char_u *cmd, @@ -4765,23 +4785,12 @@ mch_call_shell( */ if (len == 1 && (pty_master_fd < 0 || cmd != NULL)) { -# ifdef SIGINT /* * Send SIGINT to the child's group or all * processes in our group. */ - if (ta_buf[ta_len] == Ctrl_C - || ta_buf[ta_len] == intr_char) - { -# ifdef HAVE_SETSID - kill(-pid, SIGINT); -# else - kill(0, SIGINT); -# endif - if (wpid > 0) - kill(wpid, SIGINT); - } -# endif + may_send_sigint(ta_buf[ta_len], pid, wpid); + if (pty_master_fd < 0 && toshell_fd >= 0 && ta_buf[ta_len] == Ctrl_D) { @@ -5360,15 +5369,26 @@ mch_job_start(char **argv, job_T *job, j if (null_fd >= 0) close(null_fd); + if (pty_slave_fd >= 0) + { + /* push stream discipline modules */ + SetupSlavePTY(pty_slave_fd); +# ifdef TIOCSCTTY + /* Try to become controlling tty (probably doesn't work, + * unless run by root) */ + ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); +# endif + } + /* See above for type of argv. */ execvp(argv[0], argv); if (stderr_works) perror("executing job failed"); -#ifdef EXITFREE +# ifdef EXITFREE /* calling free_all_mem() here causes problems. Ignore valgrind * reporting possibly leaked memory. */ -#endif +# endif _exit(EXEC_FAILED); /* exec failed, return failure code */ } diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -57,6 +57,7 @@ int mch_report_winsize(int fd, int rows, void mch_set_shellsize(void); void mch_new_shellsize(void); int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc); +void may_send_sigint(int c, pid_t pid, pid_t wpid); int mch_call_shell(char_u *cmd, int options); void mch_job_start(char **argv, job_T *job, jobopt_T *options); char *mch_job_status(job_T *job); diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -39,8 +39,6 @@ * - don't allow exiting Vim when a terminal is still running a job * - in bash mouse clicks are inserting characters. * - mouse scroll: when over other window, scroll that window. - * - typing CTRL-C is not sent to the terminal. need to setup controlling tty? - * #1910 * - For the scrollback buffer store lines in the buffer, only attributes in * tl_scrollback. * - When the job ends: @@ -962,6 +960,17 @@ terminal_loop(void) /* job finished while waiting for a character */ break; +#ifdef UNIX + may_send_sigint(c, curbuf->b_term->tl_job->jv_pid, 0); +#endif +#ifdef WIN3264 + if (c == Ctrl_C) + /* We don't know if the job can handle CTRL-C itself or not, this + * may kill the shell instead of killing the command running in the + * shell. */ + mch_stop_job(curbuf->b_term->tl_job, "quit") +#endif + if (c == (termkey == 0 ? Ctrl_W : termkey)) { int prev_c = c; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 839, +/**/ 838, /**/ 837,