mv: implement -n option
No binary (build failed)
—
(log yok)
| @@ -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; | |
| @@ -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" \ | |