summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschwarze@openbsd.org <schwarze@openbsd.org>2021-08-12 09:59:00 +0000
committerDamien Miller <djm@mindrot.org>2021-08-12 23:05:33 +1000
commit090a82486e5d7a8f7f16613d67e66a673a40367f (patch)
treed818c761f613c1bced3e36ce3cf5c7a856214c00
parente1371e4f58404d6411d9f95eb774b444cea06a26 (diff)
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
-rw-r--r--sftp.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/sftp.c b/sftp.c
index 95b2e0b7..69f84cdc 100644
--- a/sftp.c
+++ b/sftp.c
@@ -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);