summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/sftp-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/ssh/sftp-client.c')
-rw-r--r--usr.bin/ssh/sftp-client.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/usr.bin/ssh/sftp-client.c b/usr.bin/ssh/sftp-client.c
index fdb03d1f402..67c24b0cdba 100644
--- a/usr.bin/ssh/sftp-client.c
+++ b/usr.bin/ssh/sftp-client.c
@@ -20,7 +20,7 @@
/* XXX: copy between two remote sites */
#include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.48 2004/03/30 12:41:56 djm Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.49 2004/05/19 12:17:33 djm Exp $");
#include <sys/queue.h>
@@ -36,6 +36,7 @@ RCSID("$OpenBSD: sftp-client.c,v 1.48 2004/03/30 12:41:56 djm Exp $");
#include "sftp-common.h"
#include "sftp-client.h"
+extern volatile sig_atomic_t interrupted;
extern int showprogress;
/* Minimum amount of data to read at at time */
@@ -330,7 +331,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
(*dir)[0] = NULL;
}
- for (;;) {
+ for (; !interrupted;) {
int count;
id = expected_id = conn->msg_id++;
@@ -407,6 +408,13 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
do_close(conn, handle, handle_len);
xfree(handle);
+ /* Don't return partial matches on interrupt */
+ if (interrupted && dir != NULL && *dir != NULL) {
+ free_sftp_dirents(*dir);
+ *dir = xmalloc(sizeof(**dir));
+ **dir = NULL;
+ }
+
return(0);
}
@@ -812,6 +820,16 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
char *data;
u_int len;
+ /*
+ * Simulate EOF on interrupt: stop sending new requests and
+ * allow outstanding requests to drain gracefully
+ */
+ if (interrupted) {
+ if (num_req == 0) /* If we haven't started yet... */
+ break;
+ max_req = 0;
+ }
+
/* Send some more requests */
while (num_req < max_req) {
debug3("Request range %llu -> %llu (%d/%d)",
@@ -899,8 +917,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
(unsigned long long)offset,
num_req);
max_req = 1;
- }
- else if (max_req < conn->num_requests + 1) {
+ } else if (max_req <= conn->num_requests) {
++max_req;
}
}
@@ -1032,10 +1049,14 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
int len;
/*
- * Can't use atomicio here because it returns 0 on EOF, thus losing
- * the last block of the file
+ * Can't use atomicio here because it returns 0 on EOF,
+ * thus losing the last block of the file.
+ * Simulate an EOF on interrupt, allowing ACKs from the
+ * server to drain.
*/
- do
+ if (interrupted)
+ len = 0;
+ else do
len = read(local_fd, data, conn->transfer_buflen);
while ((len == -1) && (errno == EINTR || errno == EAGAIN));