diff options
-rw-r--r-- | patch/README.md | 2 | ||||
-rw-r--r-- | src/file.c | 29 | ||||
-rw-r--r-- | src/file.h | 3 | ||||
-rw-r--r-- | src/platform.c | 5 | ||||
-rw-r--r-- | test/test_e2e.py | 8 |
5 files changed, 40 insertions, 7 deletions
diff --git a/patch/README.md b/patch/README.md index 473acda..e549a86 100644 --- a/patch/README.md +++ b/patch/README.md @@ -1,5 +1,5 @@ -Patch(es) included in this directory addes `sftp_async_write()` and +Patch(es) in this directory introduces `sftp_async_write()` and `sftp_async_write_end()` to libssh. Those implementations are derived from https://github.com/limes-datentechnik-gmbh/libssh. See [Re: SFTP Write async](https://archive.libssh.org/libssh/2020-06/0000004.html). @@ -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/src/platform.c b/src/platform.c index 81dcfdf..4c5266e 100644 --- a/src/platform.c +++ b/src/platform.c @@ -27,9 +27,8 @@ int nr_cpus() int set_thread_affinity(pthread_t tid, int core) { - errno = ENOTSUP; - pr_err("setting thread afinity is not implemented on apple\n"); - return -1; + pr_warn("setting thread afinity is not implemented on apple\n"); + return 0; } #endif 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() |