diff --git a/coreutils/mv.c b/coreutils/mv.c index 7f49d5bab..245639bd0 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c @@ -16,15 +16,30 @@ #include "libbb.h" #include "libcoreutils/coreutils.h" +//usage:#define mv_trivial_usage +//usage: "[-fin] SOURCE DEST\n" +//usage: "or: mv [-fin] SOURCE... DIRECTORY" +//usage:#define mv_full_usage "\n\n" +//usage: "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY\n" +//usage: "\nOptions:" +//usage: "\n -f Don't prompt before overwriting" +//usage: "\n -i Interactive, prompt before overwrite" +//usage: "\n -n Don't overwrite an existing file" +//usage: +//usage:#define mv_example_usage +//usage: "$ mv /tmp/foo /bin/bar\n" + #if ENABLE_FEATURE_MV_LONG_OPTIONS static const char mv_longopts[] ALIGN1 = "interactive\0" No_argument "i" "force\0" No_argument "f" + "no-clobber\0" No_argument "n" ; #endif #define OPT_FILEUTILS_FORCE 1 #define OPT_FILEUTILS_INTERACTIVE 2 +#define OPT_FILEUTILS_NOCLOBBER 4 int mv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int mv_main(int argc, char **argv) @@ -40,10 +55,11 @@ int mv_main(int argc, char **argv) #if ENABLE_FEATURE_MV_LONG_OPTIONS applet_long_options = mv_longopts; #endif - // Need at least two arguments - // -f unsets -i, -i unsets -f - opt_complementary = "-2:f-i:i-f"; - flags = getopt32(argv, "fi"); + /* Need at least two arguments. + * If more than one of -f, -i, -n is specified , only the final one + * takes effect (it unsets previous options). */ + opt_complementary = "-2:f-in:i-fn:n-fi"; + flags = getopt32(argv, "fin"); argc -= optind; argv += optind; last = argv[argc - 1]; @@ -68,18 +84,22 @@ int mv_main(int argc, char **argv) } DO_MOVE: - if (dest_exists - && !(flags & OPT_FILEUTILS_FORCE) - && ((access(dest, W_OK) < 0 && isatty(0)) - || (flags & OPT_FILEUTILS_INTERACTIVE)) - ) { - if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { - goto RET_1; /* Ouch! fprintf failed! */ - } - if (!bb_ask_confirmation()) { + if (dest_exists) { + if (flags & OPT_FILEUTILS_NOCLOBBER) goto RET_0; + if (!(flags & OPT_FILEUTILS_FORCE) + && ((access(dest, W_OK) < 0 && isatty(0)) + || (flags & OPT_FILEUTILS_INTERACTIVE)) + ) { + if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { + goto RET_1; /* Ouch! fprintf failed! */ + } + if (!bb_ask_confirmation()) { + goto RET_0; + } } } + if (rename(*argv, dest) < 0) { struct stat source_stat; int source_exists; diff --git a/include/usage.src.h b/include/usage.src.h index f5ddd7ba5..e1810c977 100644 --- a/include/usage.src.h +++ b/include/usage.src.h @@ -2695,18 +2695,6 @@ INSERT "ras3 reset retension rewind rewoffline seek setblk setdensity\n" \ "setpart tell unload unlock weof wset" \ -#define mv_trivial_usage \ - "[-fi] SOURCE DEST\n" \ - "or: mv [-fi] SOURCE... DIRECTORY" -#define mv_full_usage "\n\n" \ - "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY\n" \ - "\nOptions:" \ - "\n -f Don't prompt before overwriting" \ - "\n -i Interactive, prompt before overwrite" \ - -#define mv_example_usage \ - "$ mv /tmp/foo /bin/bar\n" - #define nameif_trivial_usage \ "[-s] [-c FILE] [{IFNAME MACADDR}]" #define nameif_full_usage "\n\n" \