mirror of
https://github.com/upa/mscp.git
synced 2026-02-04 03:24:58 +08:00
add O_TRUNC when the first open() for a file
This commit is contained in:
29
src/file.c
29
src/file.c
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user