diff options
author | jhb <jhb@FreeBSD.org> | 2012-08-31 14:35:01 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-08-31 14:35:01 +0000 |
commit | 55d653d5f9d103f38c4247ad282d34f3bce008dc (patch) | |
tree | a4d7515ca0e79ae9313694d57b632955e683f20c /bin/mv/mv.c | |
parent | 1829ce354683a94e219d2a4f5f6a0d8f3c0abaa6 (diff) | |
download | FreeBSD-src-55d653d5f9d103f38c4247ad282d34f3bce008dc.zip FreeBSD-src-55d653d5f9d103f38c4247ad282d34f3bce008dc.tar.gz |
Add a -h flag similar to the -h flag for ln to force mv(1) to treat a
symbolic link to a directory for the target as a symbolic link instead of
a directory. This makes it possible to atomically update a symbolic
link using rename().
Reviewed by: gj
MFC after: 2 weeks
Diffstat (limited to 'bin/mv/mv.c')
-rw-r--r-- | bin/mv/mv.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/bin/mv/mv.c b/bin/mv/mv.c index e4fe007..d33b28d 100644 --- a/bin/mv/mv.c +++ b/bin/mv/mv.c @@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$"); /* Exit code for a failed exec. */ #define EXEC_FAILED 127 -static int fflg, iflg, nflg, vflg; +static int fflg, hflg, iflg, nflg, vflg; static int copy(const char *, const char *); static int do_move(const char *, const char *); @@ -87,8 +87,11 @@ main(int argc, char *argv[]) int ch; char path[PATH_MAX]; - while ((ch = getopt(argc, argv, "finv")) != -1) + while ((ch = getopt(argc, argv, "fhinv")) != -1) switch (ch) { + case 'h': + hflg = 1; + break; case 'i': iflg = 1; fflg = nflg = 0; @@ -123,6 +126,17 @@ main(int argc, char *argv[]) exit(do_move(argv[0], argv[1])); } + /* + * If -h was specified, treat the target as a symlink instead of + * directory. + */ + if (hflg) { + if (argc > 2) + usage(); + if (lstat(argv[1], &sb) == 0 && S_ISLNK(sb.st_mode)) + exit(do_move(argv[0], argv[1])); + } + /* It's a directory, move each file into it. */ if (strlen(argv[argc - 1]) > sizeof(path) - 1) errx(1, "%s: destination pathname too long", *argv); @@ -483,7 +497,7 @@ usage(void) { (void)fprintf(stderr, "%s\n%s\n", - "usage: mv [-f | -i | -n] [-v] source target", + "usage: mv [-f | -i | -n] [-hv] source target", " mv [-f | -i | -n] [-v] source ... directory"); exit(EX_USAGE); } |