bin/64430: Bug in mv(1)
Samuel Tardieu
sam at rfc1149.net
Thu Mar 18 11:00:36 PST 2004
>Number: 64430
>Category: bin
>Synopsis: Bug in mv(1)
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Mar 18 11:00:28 PST 2004
>Closed-Date:
>Last-Modified:
>Originator: Samuel Tardieu
>Release: FreeBSD 4.9-STABLE i386
>Organization:
Avian Carrier & Friends
>Environment:
System: FreeBSD beeblebrox 4.9-STABLE FreeBSD 4.9-STABLE #6: Mon Mar 15 21:54:41 CET 2004 root at willow:/usr/obj/usr/src/sys/BEEBLEBROX i386
>Description:
In some cases, mv is unable to move files. Four conditions must
be met to have it fail as far as I can see:
1) The source must be a symlink
2) The target must be a symlink
3) The target must point onto a mounting point
4) The source and target must not be on the same filesystem
In this case, mv will issue an inappropriate "cannot rename a
mounting point" error.
>How-To-Repeat:
If /tmp is a mounting point and you are not in the /tmp filesystem,
the following sequence reproduces the bug:
% ln -s /tmp bbb1
% ln -s /tmp bbb2
% mv bbb1 bbb2
mv: cannot rename a mount point
The expected behaviour would be to move the bbb1 symlink into /tmp,
target of the bbb2 symlink, as is done for any other kind of source
or destination.
>Fix:
The following patch fixes that.
--- mv-old/mv.c 2004-03-18 19:44:53.000000000 +0100
+++ mv-new/mv.c 2004-03-18 19:44:53.000000000 +0100
@@ -212,6 +212,30 @@
struct statfs sfs;
char path[PATH_MAX];
+ /* If the source is a symbolic link and is on another
+ * filesystem, it can be recreated at the destination.
+ */
+ if (lstat(from, &sb) == -1) {
+ warn("%s",from);
+ return (1);
+ }
+ if (S_ISLNK(sb.st_mode)) {
+ bzero(path, PATH_MAX);
+ if (readlink(from, path, PATH_MAX) == -1) {
+ warn("%s", from);
+ return (1);
+ }
+ if (symlink(path,to)==-1) {
+ warn("%s", to);
+ return (1);
+ }
+ if (unlink(from) == -1) {
+ warn("%s", from);
+ return (1);
+ }
+ return (0);
+ }
+
/* Can't mv(1) a mount point. */
if (realpath(from, path) == NULL) {
warnx("cannot resolve %s: %s", from, path);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list