This is my first patch just after reviewing the code for a few minutes, so bear with me. It just works for me in all my tests, so I hope it gets reviewed
On 5/21/16, wdlkmpx <[email protected]> wrote: > This matches the behavior of GNU coreutils > --- > coreutils/cp.c | 14 +++++++++++--- > include/libbb.h | 2 ++ > libbb/copy_file.c | 22 ++++++++++++++++++++++ > 3 files changed, 35 insertions(+), 3 deletions(-) > > diff --git a/coreutils/cp.c b/coreutils/cp.c > index 247ed0f..cd947be 100644 > --- a/coreutils/cp.c > +++ b/coreutils/cp.c > @@ -31,6 +31,7 @@ > //usage: "\n -f Overwrite" > //usage: "\n -i Prompt before overwrite" > //usage: "\n -l,-s Create (sym)links" > +//usage: "\n -u Copy if SOURCE file is newer than the > destination" > > #include "libbb.h" > #include "libcoreutils/coreutils.h" > @@ -53,8 +54,10 @@ int cp_main(int argc, char **argv) > OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)), > OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1), > OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2), > + OPT_u = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), > #if ENABLE_FEATURE_CP_LONG_OPTIONS > - OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), > + OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+4), > + OPT_rmdest = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+5), > #endif > }; > > @@ -76,10 +79,12 @@ int cp_main(int argc, char **argv) > "recursive\0" No_argument "R" > "symbolic-link\0" No_argument "s" > "verbose\0" No_argument "v" > - "parents\0" No_argument "\xff" > + "update\0" No_argument "u" > + "parents\0" No_argument "\xfe" > + "remove-destination\0" No_argument "\xff" > ; > #endif > - flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPv"); > + flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPvu"); > /* Options of cp from GNU coreutils 6.10: > * -a, --archive > * -f, --force > @@ -161,6 +166,9 @@ int cp_main(int argc, char **argv) > bb_error_msg_and_die("with --parents, the > destination must be a > directory"); > } > } > + if (flags & OPT_rmdest) { > + flags |= FILEUTILS_RMDEST; > + } > #endif > > /* ...if neither is a directory... */ > diff --git a/include/libbb.h b/include/libbb.h > index fd40ef7..ece5f32 100644 > --- a/include/libbb.h > +++ b/include/libbb.h > @@ -368,6 +368,8 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, > install.c depend on them. */ > FILEUTILS_IGNORE_CHMOD_ERR = 1 << 11, > /* -v */ > FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE, > + FILEUTILS_UPDATE = 1 << 13, /* -u */ > + FILEUTILS_RMDEST = 1 << 14, /* cp --remove-destination */ > }; > #define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c") > extern int remove_file(const char *path, int flags) FAST_FUNC; > diff --git a/libbb/copy_file.c b/libbb/copy_file.c > index a4be875..44031f2 100644 > --- a/libbb/copy_file.c > +++ b/libbb/copy_file.c > @@ -208,6 +208,28 @@ int FAST_FUNC copy_file(const char *source, const char > *dest, int flags) > /* retval = -1; - WRONG! copy *WAS* made */ > } > goto preserve_mode_ugid_time; > + } else { > + /* Not a directory */ > + if (dest_exists) { > + if (flags & FILEUTILS_UPDATE) { > + if (source_stat.st_mtime <= dest_stat.st_mtime) > { > + return 0; /* source file must be newer > */ > + } > + } > + if (flags & FILEUTILS_RMDEST) { > + if (unlink(dest) < 0) { > + if (flags & FILEUTILS_VERBOSE) { > + printf("can't remove '%s'\n", > dest); > + } > + return -1; > + } else { > + if (flags & FILEUTILS_VERBOSE) { > + printf("removed '%s'\n", dest); > + } > + dest_exists = 0; > + } > + } > + } > } > > if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { > -- > 2.8.3 > > _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
