coreutils icon indicating copy to clipboard operation
coreutils copied to clipboard

cp: keep handling the rest of the paths if one does not exists

Open granquet opened this issue 1 year ago • 12 comments

Quick attempt at fixing issue https://github.com/uutils/coreutils/issues/6177

I'm implementing a custom type for the value parser so that I have the option to not fail early if the path does not exists and I let the operations continue "as if" everything is fine.

Not really happy with the solution as the "bad" path is still in the array of paths and is checked a second time... though I don't have a better idea yet.

granquet avatar Apr 09 '24 15:04 granquet

Interesting! I think you're on the right track by looking into the value parser, but I think the problematic part in the current code is the PathBuf value parser, which requires a non-empty value. We can use the OsString value parser instead to fix that. Then we can filter out the files later if we're still not compatible.

tertsdiepraam avatar Apr 09 '24 15:04 tertsdiepraam

GNU testsuite comparison:

GNU test failed: tests/cp/abuse. tests/cp/abuse is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/cp/fail-perm. tests/cp/fail-perm is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/cp/thru-dangling. tests/cp/thru-dangling is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/mv/trailing-slash. tests/mv/trailing-slash is passing on 'main'. Maybe you have to rebase?

github-actions[bot] avatar Apr 09 '24 15:04 github-actions[bot]

@tertsdiepraam : makes more sense to do it the way you describe it, will make the change ASAP.

btw, gnu cp accepts both empty strings and non existant files. both produces the same error and other files are handled.

granquet avatar Apr 09 '24 21:04 granquet

I've updated to use an OsString instead of a custom struct in the parsing and then filter out the non existant paths in the parse_path_args.

A quick test here with empty filepath and non existant files. Compared to cp (GNU coreutils) 9.4

➜  coreutils git:(d000b88d3) ✗ mkdir test_cp
➜  coreutils git:(d000b88d3) ✗ touch exists
➜  coreutils git:(d000b88d3) ✗ ls test_cp
exists
➜  coreutils git:(d000b88d3) ✗ cp "" noent exists noent2 test_cp
cp: cannot stat '': No such file or directory
cp: cannot stat 'noent': No such file or directory
cp: cannot stat 'noent2': No such file or directory
➜  coreutils git:(d000b88d3) ✗ echo $?
1


➜  coreutils git:(d000b88d3) ✗ rm test_cp/exists
➜  coreutils git:(d000b88d3) ✗ target/debug/coreutils cp "" noent exists noent2 test_cp
cp: cannot stat '': No such file or directory
cp: cannot stat 'noent': No such file or directory
cp: cannot stat 'noent2': No such file or directory
➜  coreutils git:(d000b88d3) ✗ echo $?
1
➜  coreutils git:(d000b88d3) ✗ ls test_cp
exists

granquet avatar Apr 10 '24 14:04 granquet

GNU testsuite comparison:

GNU test failed: tests/cp/abuse. tests/cp/abuse is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/cp/link-no-deref. tests/cp/link-no-deref is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/cp/r-vs-symlink. tests/cp/r-vs-symlink is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/cp/slink-2-slink. tests/cp/slink-2-slink is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/tail/inotify-dir-recreate (fails in this run but passes in the 'main' branch)
GNU test failed: tests/timeout/timeout. tests/timeout/timeout is passing on 'main'. Maybe you have to rebase?
GNU test error: tests/cp/preserve-slink-time. tests/cp/preserve-slink-time is passing on 'main'. Maybe you have to rebase?

github-actions[bot] avatar Apr 10 '24 15:04 github-actions[bot]

Just a few points, maybe you're already aware, but just in case:

  • The goal is compatibility with GNU coreutils 9.5 (typically "the newest version", although I'm sure there will be exceptions to that made-up rule). Can you compile GNU coreutils 9.5 and sanity-check that the behavior is as intended?
  • Are the GNU test errors related? Especially tests/cp/abuse sounds like a regression.

BenWiederhake avatar Apr 10 '24 20:04 BenWiederhake

@BenWiederhake : thanks for your feedback, I've updated to coreutils 9.5 and I'm seeing the same behaviour. For the tests/cp/abuse issue, yes this is a regression. I need to look into it.

Seems I'm catching some of the test cases in parse_path_arg instead of clap or later in the copy code which produces a different. i.e:

[2024-04-10 14:50:49] <cp: cannot stat 'nonexistent_file.txt': No such file or directory
[2024-04-10 14:50:49] >cp: cannot stat 'nonexistent_file.txt': No such file or directory (os error 2)

I'll double check and fix the regressions before removing the draft status.

granquet avatar Apr 11 '24 12:04 granquet

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Apr 19 '24 13:04 github-actions[bot]

@BenWiederhake : Thanks for the feedback. I've pushed a new version where I'm checking the existence of the path closer to its actual usage. It should reduce the TOCTOU-timespan significantly. what do you think?

granquet avatar Apr 22 '24 16:04 granquet

ping ? :)

sylvestre avatar Jun 04 '24 21:06 sylvestre

ping ? :)

Sorry, got sidetracked (had some vacations, broke a bone...), I will resume working on this next week probably :)

granquet avatar Jun 21 '24 12:06 granquet

Vacations sound good Breaking bones, way less. I hope you are doing better

sylvestre avatar Jun 21 '24 13:06 sylvestre