upstream: In the editline(3) branch of the sftp(1) event loop,

handle SIGINT rather than ignoring it, such that the user can use Ctrl-C to
discard the currently edited command line and get a fresh prompt, just like
in ftp(1), bc(1), and in shells.

It is critical to not use ssl_signal() for this particular case
because that function unconditionally sets SA_RESTART, but here we
need the signal to interrupt the read(2) in the el_gets(3) event loop.

OK dtucker@ deraadt@

OpenBSD-Commit-ID: 8025115a773f52e9bb562eaab37ea2e021cc7299
This commit is contained in:
schwarze@openbsd.org 2021-08-12 09:59:00 +00:00 committed by Damien Miller
parent e1371e4f58
commit 090a82486e
1 changed files with 19 additions and 3 deletions

22
sftp.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp.c,v 1.210 2021/08/07 00:12:09 djm Exp $ */
/* $OpenBSD: sftp.c,v 1.211 2021/08/12 09:59:00 schwarze Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -252,6 +252,13 @@ cmd_interrupt(int signo)
errno = olderrno;
}
/* ARGSUSED */
static void
read_interrupt(int signo)
{
interrupted = 1;
}
/*ARGSUSED*/
static void
sigchld_handler(int sig)
@ -2197,8 +2204,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) {
ssh_signal(SIGINT, SIG_IGN);
if (el == NULL) {
if (interactive)
printf("sftp> ");
@ -2211,10 +2216,21 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
#ifdef USE_LIBEDIT
const char *line;
int count = 0;
struct sigaction sa;
interrupted = 0;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = read_interrupt;
if (sigaction(SIGINT, &sa, NULL) == -1) {
debug3("sigaction(%s): %s",
strsignal(SIGINT), strerror(errno));
break;
}
if ((line = el_gets(el, &count)) == NULL ||
count <= 0) {
printf("\n");
if (interrupted)
continue;
break;
}
history(hl, &hev, H_ENTER, line);