aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/posix/cp.c')
-rw-r--r--toys/posix/cp.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index 7b9889a2..c11da163 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -16,8 +16,8 @@
// for FLAG macros to work out right in shared infrastructure.
USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]", TOYFLAG_BIN))
-USE_MV(NEWTOY(mv, "<1vnF(remove-destination)fit:T[-ni]", TOYFLAG_BIN))
-USE_INSTALL(NEWTOY(install, "<1cdDpsvt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_MV(NEWTOY(mv, "<1v(verbose)nF(remove-destination)fit:T[-ni]", TOYFLAG_BIN))
+USE_INSTALL(NEWTOY(install, "<1cdDp(preserve-timestamps)svt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
config CP
bool "cp"
@@ -148,10 +148,8 @@ static int cp_node(struct dirtree *try)
// Detect recursive copies via repeated top node (cp -R .. .) or
// identical source/target (fun with hardlinks).
- if ((TT.top.st_dev == try->st.st_dev && TT.top.st_ino == try->st.st_ino
- && (catch = TT.destname))
- || (!fstatat(cfd, catch, &cst, 0) && cst.st_dev == try->st.st_dev
- && cst.st_ino == try->st.st_ino))
+ if ((same_file(&TT.top, &try->st) && (catch = TT.destname))
+ || (!fstatat(cfd, catch, &cst, 0) && same_file(&cst, &try->st)))
{
error_msg("'%s' is '%s'", catch, err = dirtree_path(try, 0));
free(err);
@@ -206,7 +204,7 @@ static int cp_node(struct dirtree *try)
if (!mkdirat(cfd, catch, try->st.st_mode | 0200) || errno == EEXIST)
if (-1 != (try->extra = openat(cfd, catch, O_NOFOLLOW)))
if (!fstat(try->extra, &st2) && S_ISDIR(st2.st_mode))
- return DIRTREE_COMEAGAIN | (DIRTREE_SYMFOLLOW*!!FLAG(L));
+ return DIRTREE_COMEAGAIN | DIRTREE_SYMFOLLOW*FLAG(L);
// Hardlink
@@ -432,9 +430,7 @@ void cp_main(void)
// "mv across devices" triggers cp fallback path, so set that as default
errno = EXDEV;
if (CFG_MV && toys.which->name[0] == 'm') {
- int force = FLAG(f), no_clobber = FLAG(n);
-
- if (!force || no_clobber) {
+ if (!FLAG(f) || FLAG(n)) {
struct stat st;
int exists = !stat(TT.destname, &st);
@@ -447,7 +443,7 @@ void cp_main(void)
else unlink(TT.destname);
}
// if -n and dest exists, don't try to rename() or copy
- if (exists && no_clobber) send = 0;
+ if (exists && FLAG(n)) send = 0;
}
if (send) send = rename(src, TT.destname);
if (trail) trail[1] = '/';
@@ -456,7 +452,7 @@ void cp_main(void)
// Copy if we didn't mv or hit an error, skipping nonexistent sources
if (send) {
if (errno!=EXDEV || dirtree_flagread(src, DIRTREE_SHUTUP+
- DIRTREE_SYMFOLLOW*!!(FLAG(H)||FLAG(L)), TT.callback))
+ DIRTREE_SYMFOLLOW*(FLAG(H)|FLAG(L)), TT.callback))
perror_msg("bad '%s'", src);
}
if (destdir) free(TT.destname);
@@ -472,9 +468,9 @@ void mv_main(void)
// Export cp flags into install's flag context.
-static inline int cp_flag_F(void) { return FLAG_F; };
-static inline int cp_flag_p(void) { return FLAG_p; };
-static inline int cp_flag_v(void) { return FLAG_v; };
+static inline int cp_flag_F(void) { return FLAG_F; }
+static inline int cp_flag_p(void) { return FLAG_p; }
+static inline int cp_flag_v(void) { return FLAG_v; }
// Switch to install's flag context
#define FOR_install
@@ -516,15 +512,15 @@ void install_main(void)
}
if (FLAG(D)) {
- char *destname = FLAG(t) ? TT.i.t : (TT.destname = toys.optargs[toys.optc-1]);
- if (mkpathat(AT_FDCWD, destname, 0777, MKPATHAT_MAKE | (FLAG(t) ? MKPATHAT_MKLAST : 0)))
+ char *destname = TT.i.t ? : (TT.destname = toys.optargs[toys.optc-1]);
+ if (mkpathat(AT_FDCWD, destname, 0777, MKPATHAT_MAKE|MKPATHAT_MKLAST*FLAG(t)))
perror_exit("-D '%s'", destname);
if (toys.optc == !FLAG(t)) return;
}
// Translate flags from install to cp
- toys.optflags = cp_flag_F() + cp_flag_v()*!!FLAG(v)
- + cp_flag_p()*!!(FLAG(p)|FLAG(o)|FLAG(g));
+ toys.optflags = cp_flag_F() + cp_flag_v()*FLAG(v)
+ + cp_flag_p()*(FLAG(p)|FLAG(o)|FLAG(g));
TT.callback = install_node;
cp_main();