[PATCH] cp: add -u/--update and --remove-destination
shen long
wdlkmpx at gmail.com
Sun May 22 03:21:15 UTC 2016
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 <wdlkmpx at gmail.com> 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
>
>
More information about the busybox
mailing list