diff options
-rw-r--r-- | src/file.c | 29 | ||||
-rw-r--r-- | src/file.h | 3 | ||||
-rw-r--r-- | test/test_e2e.py | 8 |
3 files changed, 37 insertions, 3 deletions
@@ -367,6 +367,7 @@ static int file_dst_prepare(struct file *f, sftp_session sftp) pr_debug("prepare for %s\n", path); + /* mkdir -p */ for (p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) { *p = '\0'; @@ -398,6 +399,30 @@ static int file_dst_prepare(struct file *f, sftp_session sftp) *p = '/'; } + /* open file with O_TRUNC to set file size 0 */ + mode = O_WRONLY|O_CREAT|O_TRUNC; + if (sftp) { + sftp_file sf; + if ((sf = sftp_open(sftp, f->dst_path, mode, S_IRUSR|S_IWUSR)) == NULL) { + pr_err("sftp_open: %s\n", sftp_get_ssh_error(sftp)); + return -1; + } + if (sftp_close(sf) < 0) { + pr_err("sftp_close: %s\n", sftp_get_ssh_error(sftp)); + return -1; + } + } else { + int fd; + if ((fd = open(f->dst_path, mode, S_IRUSR|S_IWUSR)) < 0) { + pr_err("open: %s\n", strerrno()); + return -1; + } + if (close(fd) < 0) { + pr_err("close: %s\n", strerrno()); + return -1; + } + } + return 0; } @@ -824,7 +849,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp, goto out; } - flags = O_WRONLY|O_CREAT; + flags = O_WRONLY; mode = S_IRUSR|S_IWUSR; if (!(sf = chunk_open_remote(f->dst_path, flags, mode, c->off, sftp))) { ret = -1; @@ -866,7 +891,7 @@ static int chunk_copy_remote_to_local(struct chunk *c, sftp_session sftp, int fd = 0; int ret = 0; - flags = O_WRONLY|O_CREAT; + flags = O_WRONLY; mode = S_IRUSR|S_IWUSR; if ((fd = chunk_open_local(f->dst_path, flags, mode, c->off)) < 0) { ret = -1; @@ -37,7 +37,8 @@ struct file { * if the file state of the chunk is INIT: * acquire the file lock * * if file state is INIT: - * create destination file and directory if necessary + * create directory if necessary + * open file with O_TRUNC and close. * set file state OPENED. * // only the first thread in the lock open the destination file * release the file lock diff --git a/test/test_e2e.py b/test/test_e2e.py index 61a3532..515717f 100644 --- a/test/test_e2e.py +++ b/test/test_e2e.py @@ -174,3 +174,11 @@ def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix): src.cleanup() dst.cleanup() +@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix) +def test_override_dst_having_larger_size(mscp, src_prefix, dst_prefix): + src = File("src", size = 1024 * 1024).make() + dst = File("dst", size = 1024 * 1024 * 2).make() + run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + "dst"]) + assert check_same_md5sum(src, dst) + src.cleanup() + dst.cleanup() |