[git commit] cp: implement -n

Denys Vlasenko vda.linux at googlemail.com
Tue Jun 22 13:28:34 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=56bbbfae7df48f778362d1848d2a4afd2c293d76
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
.rodata                                           103681  103722     +41
packed_usage                                       33698   33717     +19
copy_file                                           1678    1696     +18
cp_main                                              500     492      -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 78/-8)              Total: 70 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/cp.c    | 19 +++++++++++--------
 include/libbb.h   | 29 +++++++++++++++--------------
 libbb/copy_file.c |  2 ++
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/coreutils/cp.c b/coreutils/cp.c
index 8b9e03c95..b7f0e290f 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -84,8 +84,8 @@
 //	(SELinux) set SELinux security context of copy to CONTEXT
 
 //usage:#define cp_trivial_usage
-//usage:       "[-arPLHpfilsTu] SOURCE DEST\n"
-//usage:       "or: cp [-arPLHpfilsu] SOURCE... { -t DIRECTORY | DIRECTORY }"
+//usage:       "[-arPLHpfinlsTu] SOURCE DEST\n"
+//usage:       "or: cp [-arPLHpfinlsu] SOURCE... { -t DIRECTORY | DIRECTORY }"
 //usage:#define cp_full_usage "\n\n"
 //usage:       "Copy SOURCEs to DEST\n"
 //usage:     "\n	-a	Same as -dpR"
@@ -99,6 +99,7 @@
 //usage:     "\n	-p	Preserve file attributes if possible"
 //usage:     "\n	-f	Overwrite"
 //usage:     "\n	-i	Prompt before overwrite"
+//usage:     "\n	-n	Don't overwrite"
 //usage:     "\n	-l,-s	Create (sym)links"
 //usage:     "\n	-T	Refuse to copy if DEST is a directory"
 //usage:     "\n	-t DIR	Copy all SOURCEs into DIR"
@@ -122,9 +123,9 @@ int cp_main(int argc, char **argv)
 	int status;
 	enum {
 #if ENABLE_FEATURE_CP_LONG_OPTIONS
-		/*OPT_rmdest  = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */
-		OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1),
-		OPT_reflink = 1 << (FILEUTILS_CP_OPTNUM+2),
+		/*OPT_rmdest  = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTBITS */
+		OPT_parents = 1 << (FILEUTILS_CP_OPTBITS+1),
+		OPT_reflink = 1 << (FILEUTILS_CP_OPTBITS+2),
 #endif
 	};
 #if ENABLE_FEATURE_CP_LONG_OPTIONS
@@ -134,23 +135,25 @@ int cp_main(int argc, char **argv)
 	flags = getopt32long(argv, "^"
 		FILEUTILS_CP_OPTSTR
 		"\0"
-		// Need at least two arguments
+		// Need at least one argument. (Usually two+, but -t DIR can have only one)
 		// Soft- and hardlinking doesn't mix
 		// -P and -d are the same (-P is POSIX, -d is GNU)
 		// -r and -R are the same
 		// -R (and therefore -r) turns on -d (coreutils does this)
 		// -a = -pdR
-	/* At least one argument. (Usually two+, but -t DIR can have only one) */
-		"-1:l--s:s--l:Pd:rRd:Rd:apdR",
+		// -i overrides -n and vice versa (last wins)
+		"-1:l--s:s--l:Pd:rRd:Rd:apdR:i-n:n-i",
 		"archive\0"        No_argument "a"
 		"force\0"          No_argument "f"
 		"interactive\0"    No_argument "i"
+		"no-clobber\0"     No_argument "n"
 		"link\0"           No_argument "l"
 		"dereference\0"    No_argument "L"
 		"no-dereference\0" No_argument "P"
 		"recursive\0"      No_argument "R"
 		"symbolic-link\0"  No_argument "s"
 		"no-target-directory\0" No_argument "T"
+		"target-directory\0" Required_argument "t"
 		"verbose\0"        No_argument "v"
 		"update\0"         No_argument "u"
 		"remove-destination\0" No_argument "\xff"
diff --git a/include/libbb.h b/include/libbb.h
index e38e97ac2..251d7231c 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -450,28 +450,29 @@ enum {	/* cp.c, mv.c, install.c depend on these values. CAREFUL when changing th
 	FILEUTILS_RECUR           = 1 << 2, /* -R */
 	FILEUTILS_FORCE           = 1 << 3, /* -f */
 	FILEUTILS_INTERACTIVE     = 1 << 4, /* -i */
-	FILEUTILS_MAKE_HARDLINK   = 1 << 5, /* -l */
-	FILEUTILS_MAKE_SOFTLINK   = 1 << 6, /* -s */
-	FILEUTILS_DEREF_SOFTLINK  = 1 << 7, /* -L */
-	FILEUTILS_DEREFERENCE_L0  = 1 << 8, /* -H */
+	FILEUTILS_NO_OVERWRITE    = 1 << 5, /* -n */
+	FILEUTILS_MAKE_HARDLINK   = 1 << 6, /* -l */
+	FILEUTILS_MAKE_SOFTLINK   = 1 << 7, /* -s */
+	FILEUTILS_DEREF_SOFTLINK  = 1 << 8, /* -L */
+	FILEUTILS_DEREFERENCE_L0  = 1 << 9, /* -H */
 	/* -a = -pdR (mapped in cp.c) */
 	/* -r = -dR  (mapped in cp.c) */
 	/* -P = -d   (mapped in cp.c) */
-	FILEUTILS_VERBOSE         = (1 << 12) * ENABLE_FEATURE_VERBOSE,	/* -v */
-	FILEUTILS_UPDATE          = 1 << 13, /* -u */
-	FILEUTILS_NO_TARGET_DIR	  = 1 << 14, /* -T */
-	FILEUTILS_TARGET_DIR	  = 1 << 15, /* -t DIR */
+	FILEUTILS_VERBOSE         = (1 << 13) * ENABLE_FEATURE_VERBOSE,	/* -v */
+	FILEUTILS_UPDATE          = 1 << 14, /* -u */
+	FILEUTILS_NO_TARGET_DIR	  = 1 << 15, /* -T */
+	FILEUTILS_TARGET_DIR	  = 1 << 16, /* -t DIR */
 #if ENABLE_SELINUX
-	FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 16, /* -c */
+	FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 17, /* -c */
 #endif
-#define FILEUTILS_CP_OPTSTR "pdRfilsLHarPvuTt:" IF_SELINUX("c")
+#define FILEUTILS_CP_OPTSTR "pdRfinlsLHarPvuTt:" IF_SELINUX("c")
 /* How many bits in FILEUTILS_CP_OPTSTR? */
-	FILEUTILS_CP_OPTNUM       = 17 - !ENABLE_SELINUX,
+	FILEUTILS_CP_OPTBITS      = 18 - !ENABLE_SELINUX,
 
-	FILEUTILS_RMDEST          = 1 << (17 - !ENABLE_SELINUX), /* --remove-destination */
+	FILEUTILS_RMDEST          = 1 << (19 - !ENABLE_SELINUX), /* cp --remove-destination */
 	/* bit 18 skipped for "cp --parents" */
-	FILEUTILS_REFLINK         = 1 << (19 - !ENABLE_SELINUX), /* cp --reflink=auto */
-	FILEUTILS_REFLINK_ALWAYS  = 1 << (20 - !ENABLE_SELINUX), /* cp --reflink[=always] */
+	FILEUTILS_REFLINK         = 1 << (20 - !ENABLE_SELINUX), /* cp --reflink=auto */
+	FILEUTILS_REFLINK_ALWAYS  = 1 << (21 - !ENABLE_SELINUX), /* cp --reflink[=always] */
 	/*
 	 * Hole. cp may have some bits set here,
 	 * they should not affect remove_file()/copy_file()
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 49d1ec9c6..044bc3c20 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -111,6 +111,8 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
 			bb_error_msg("'%s' and '%s' are the same file", source, dest);
 			return -1;
 		}
+		if (flags & FILEUTILS_NO_OVERWRITE) /* cp -n */
+			return 0;
 		dest_exists = 1;
 	}
 


More information about the busybox-cvs mailing list