Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Oct 1996 17:18:01 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-bugs@freefall.freebsd.org, zach@blizzard.gaffaneys.com
Subject:   Re: bin/1377
Message-ID:  <199610240718.RAA01442@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>Bruce> It seems about right.  I think it should avoid the magic
>Bruce> number 01777 as in cp.
>
>I couldn't find any #defined constants that don't mean something else.
>You could replace the (01777) with (~(S_ISGID | S_ISUID)) and get the
>same behavior, but those constants were really meant for something
>else, right?

They are precisely the attributes you want to give up :-).  The semantics
of st_mode is precise enough for it to be possible to see that masking
with 01777 doesn't clobber anything important that you don't know about,
but it's simpler not to change the other bits.

>Since you say mv should be more careful than 'cp -p' to preserve
>things (*), should the fchown() call be split up, so if mv (or cp -p)
>can only preserve one of the *id's, it really does get preserved?

I'd be happy for mv to fail if it can't preserve something, but many
people would not like that, and it isn't clear what to do when mv
fails in the middle of moving a whole tree.

>(*): They should be equally careful about preserving things, as mv
>calls cp -PRp to do its dirty work when the file is something other
>than a regular file.

This is a bug in mv :-).  cp -PRp doesn't have quite the right
semantics and is buggy.

My list of known bugs (other than ones in PRs):

cp:
- cp -PRp usually fails to preserve directory timestamps.
- cp -PRp snaps hard links.
- cp -fPRp fails to remove target symlinks - the target of the
  symlink is copied to, whether or not it already exists.  This
  isn't a problem for mv, except after a race, because the
  target tree doesn't exist when the mv begins.

mv:
- mv across file systems inhereis bugs from cp -PRp.
- `mv dir1 dir2' where dir1 and dir2 are existent directories
  should move dir2 to dir1/dir2.  Thus it should fail if
  dir1/dir2 exists, unless dir1/dir2 is a nonempty directory.
  It fails correctly if the directories are on the same file
  system.  If dir1/dir2 is a directory (nonempty or not) on
  another file system, then dir2 is moved to dir1/dir2/dir2
  (at least if that doesn't exist).  This is caused by the
  natural (wrong) translation of the mv to a cp -PRp:
  cp -PRp dir2 dir1/dir2 behaves differently depending on
  whether dir1/dir2 exists or not.  The translation should be:
  1) if dir1/dir2 exists and is not an empty directory, give
     up without invoking cp.
  2) if dir1/dir2 is an empty directory, remove it to reduce
     to case (3).
  3) if dir1/dir2 doesn't exist, invoke the above cp and pray
     that nothing creates dir1/dir2 before cp checks it.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610240718.RAA01442>