]> andersk Git - openssh.git/blobdiff - sftp-client.c
- djm@cvs.openbsd.org 2004/05/19 12:17:33
[openssh.git] / sftp-client.c
index bf2eb43accd9667ef816e30b49f9b1b85e175a8f..6dcd5de74695ccbfa067d7d32c2ccfafb8a10062 100644 (file)
@@ -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 "openbsd-compat/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;
                                }
                        }
@@ -1036,10 +1053,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));
 
This page took 0.123226 seconds and 4 git commands to generate.