| File src/io/iop.c changed (mode: 100644) (index 402f44f70..358679c42) |
| ... |
... |
iop_cp_internal(io_args_t *args) |
| 298 |
298 |
const char *const src = args->arg1.src; |
const char *const src = args->arg1.src; |
| 299 |
299 |
const char *const dst = args->arg2.dst; |
const char *const dst = args->arg2.dst; |
| 300 |
300 |
const IoCrs crs = args->arg3.crs; |
const IoCrs crs = args->arg3.crs; |
|
301 |
|
const int deep_copying = args->arg4.deep_copying; |
| 301 |
302 |
const io_confirm confirm = args->confirm; |
const io_confirm confirm = args->confirm; |
| 302 |
303 |
struct stat st; |
struct stat st; |
| 303 |
304 |
|
|
| |
| ... |
... |
iop_cp_internal(io_args_t *args) |
| 318 |
319 |
DWORD flags; |
DWORD flags; |
| 319 |
320 |
wchar_t *utf16_src, *utf16_dst; |
wchar_t *utf16_src, *utf16_dst; |
| 320 |
321 |
|
|
| 321 |
|
flags = COPY_FILE_COPY_SYMLINK; |
|
|
322 |
|
flags = (deep_copying ? 0 : COPY_FILE_COPY_SYMLINK); |
| 322 |
323 |
if(crs == IO_CRS_FAIL) |
if(crs == IO_CRS_FAIL) |
| 323 |
324 |
{ |
{ |
| 324 |
325 |
flags |= COPY_FILE_FAIL_IF_EXISTS; |
flags |= COPY_FILE_FAIL_IF_EXISTS; |
| |
| ... |
... |
iop_cp_internal(io_args_t *args) |
| 359 |
360 |
} |
} |
| 360 |
361 |
#endif |
#endif |
| 361 |
362 |
|
|
| 362 |
|
/* Create symbolic link rather than copying file it points to. This check |
|
| 363 |
|
* should go before directory check as is_dir() resolves symbolic links. */ |
|
| 364 |
|
if(is_symlink(src)) |
|
|
363 |
|
/* Optionally create a symbolic link rather than copying file it points to. A |
|
364 |
|
* broken symlink is always copied as a symlink. This check should go before |
|
365 |
|
* directory check as is_dir() resolves symbolic links. */ |
|
366 |
|
if((!deep_copying && is_symlink(src)) || |
|
367 |
|
(deep_copying && is_symlink(src) && !path_exists(src, DEREF))) |
| 365 |
368 |
{ |
{ |
| 366 |
369 |
char link_target[PATH_MAX + 1]; |
char link_target[PATH_MAX + 1]; |
| 367 |
370 |
|
|
| |
| ... |
... |
iop_cp_internal(io_args_t *args) |
| 630 |
633 |
error = 1; |
error = 1; |
| 631 |
634 |
} |
} |
| 632 |
635 |
|
|
| 633 |
|
if(error == 0 && os_lstat(src, &src_st) == 0) |
|
|
636 |
|
if(error == 0 && (deep_copying ? os_stat : os_lstat)(src, &src_st) == 0) |
| 634 |
637 |
{ |
{ |
| 635 |
638 |
error = os_chmod(dst, src_st.st_mode & 07777); |
error = os_chmod(dst, src_st.st_mode & 07777); |
| 636 |
639 |
if(error != 0) |
if(error != 0) |
| File tests/iop/cp.c changed (mode: 100644) (index 0ead9827a..2985555da) |
| 17 |
17 |
#include "../../src/compat/os.h" |
#include "../../src/compat/os.h" |
| 18 |
18 |
#include "../../src/io/iop.h" |
#include "../../src/io/iop.h" |
| 19 |
19 |
#include "../../src/utils/fs.h" |
#include "../../src/utils/fs.h" |
|
20 |
|
#include "../../src/utils/macros.h" |
| 20 |
21 |
|
|
| 21 |
22 |
#include "utils.h" |
#include "utils.h" |
| 22 |
23 |
|
|
| |
| ... |
... |
TEST(file_symlink_copy_is_symlink, IF(not_windows)) |
| 337 |
338 |
delete_test_file(SANDBOX_PATH "/sym-link-copy"); |
delete_test_file(SANDBOX_PATH "/sym-link-copy"); |
| 338 |
339 |
} |
} |
| 339 |
340 |
|
|
|
341 |
|
TEST(file_symlink_copy_is_a_file, IF(not_windows)) |
|
342 |
|
{ |
|
343 |
|
char file_contents[] = "file_symlink_copy_is_a_file"; |
|
344 |
|
const char *file_lines[] = { file_contents }; |
|
345 |
|
|
|
346 |
|
make_file(SANDBOX_PATH "/target", file_contents); |
|
347 |
|
|
|
348 |
|
/* This is to help verify that file mode is copied. */ |
|
349 |
|
assert_success(os_chmod(SANDBOX_PATH "/target", 0600)); |
|
350 |
|
|
|
351 |
|
{ |
|
352 |
|
char path[PATH_MAX + 1]; |
|
353 |
|
io_args_t args = { |
|
354 |
|
.arg1.path = path, |
|
355 |
|
.arg2.target = SANDBOX_PATH "/sym-link", |
|
356 |
|
}; |
|
357 |
|
ioe_errlst_init(&args.result.errors); |
|
358 |
|
|
|
359 |
|
make_abs_path(path, sizeof(path), SANDBOX_PATH, "target", NULL); |
|
360 |
|
assert_int_equal(IO_RES_SUCCEEDED, iop_ln(&args)); |
|
361 |
|
|
|
362 |
|
assert_int_equal(0, args.result.errors.error_count); |
|
363 |
|
} |
|
364 |
|
|
|
365 |
|
assert_true(is_symlink(SANDBOX_PATH "/sym-link")); |
|
366 |
|
|
|
367 |
|
{ |
|
368 |
|
io_args_t args = { |
|
369 |
|
.arg1.src = SANDBOX_PATH "/sym-link", |
|
370 |
|
.arg2.dst = SANDBOX_PATH "/sym-link-copy", |
|
371 |
|
.arg4.deep_copying = 1, |
|
372 |
|
}; |
|
373 |
|
ioe_errlst_init(&args.result.errors); |
|
374 |
|
|
|
375 |
|
assert_int_equal(IO_RES_SUCCEEDED, iop_cp(&args)); |
|
376 |
|
|
|
377 |
|
assert_int_equal(0, args.result.errors.error_count); |
|
378 |
|
} |
|
379 |
|
|
|
380 |
|
assert_true(is_symlink(SANDBOX_PATH "/sym-link")); |
|
381 |
|
assert_true(!is_symlink(SANDBOX_PATH "/sym-link-copy")); |
|
382 |
|
|
|
383 |
|
/* Check the contents is copied. */ |
|
384 |
|
file_is(SANDBOX_PATH "/sym-link-copy", file_lines, ARRAY_LEN(file_lines)); |
|
385 |
|
|
|
386 |
|
/* Check that file mode is copied. */ |
|
387 |
|
struct stat src, dst; |
|
388 |
|
assert_success(os_stat(SANDBOX_PATH "/sym-link", &src)); |
|
389 |
|
assert_success(os_lstat(SANDBOX_PATH "/sym-link-copy", &dst)); |
|
390 |
|
assert_int_equal(src.st_mode & 0777, dst.st_mode & 0777); |
|
391 |
|
|
|
392 |
|
delete_test_file(SANDBOX_PATH "/target"); |
|
393 |
|
delete_test_file(SANDBOX_PATH "/sym-link"); |
|
394 |
|
delete_test_file(SANDBOX_PATH "/sym-link-copy"); |
|
395 |
|
} |
|
396 |
|
|
| 340 |
397 |
TEST(timestamps_are_preserved) |
TEST(timestamps_are_preserved) |
| 341 |
398 |
{ |
{ |
| 342 |
399 |
struct stat src; |
struct stat src; |