aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/cp.c
diff options
context:
space:
mode:
authorAndy Chu <andychu@google.com>2016-03-19 00:34:42 -0700
committerRob Landley <rob@landley.net>2016-03-30 03:11:55 -0500
commit7a0186cc2abf6ef9af3f26416dba7e920d100b42 (patch)
treeab6df6eff64ef7952bf985f2e83bda7f58aa3a95 /toys/posix/cp.c
parent9fcaca8434ece1afcc9982c18a86cf12ac9af508 (diff)
downloadtoybox-7a0186cc2abf6ef9af3f26416dba7e920d100b42.tar.gz
Implement mv -n / cp -n (no clobber).
This fixes a failing test case in mv.test. Test changes: - Add coverage for -i (interactive). - Better descriptions, better formatting, and removed some redundant cases.
Diffstat (limited to 'toys/posix/cp.c')
-rw-r--r--toys/posix/cp.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index d822b1e2..8bcb81e6 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -395,20 +395,21 @@ void cp_main(void)
errno = EXDEV;
if (CFG_MV && toys.which->name[0] == 'm') {
- if (!(toys.optflags & FLAG_f)) {
+ int force = toys.optflags & FLAG_f, no_clobber = toys.optflags & FLAG_n;
+ if (!force || no_clobber) {
struct stat st;
-
- // Technically "is writeable" is more complicated (022 is not writeable
- // by the owner, just everybody _else_) but I don't care.
- if (!stat(TT.destname, &st)
- && ((toys.optflags & FLAG_i) || !(st.st_mode & 0222)))
- {
+ int exists = !stat(TT.destname, &st);
+ // Prompt if -i or file isn't writable. Technically "is writable" is
+ // more complicated (022 is not writeable by the owner, just everybody
+ // _else_) but I don't care.
+ if (exists && ((toys.optflags & FLAG_i) || !(st.st_mode & 0222))) {
fprintf(stderr, "%s: overwrite '%s'", toys.which->name, TT.destname);
if (!yesno(1)) rc = 0;
else unlink(TT.destname);
}
+ // if -n and dest exists, don't try to rename() or copy
+ if (exists && no_clobber) rc = 0;
}
-
if (rc) rc = rename(src, TT.destname);
}