Description of problem: $ umask 0002 $ touch a $ chmod 600 a $ cp a b $ cp --no-preserve=mode a c $ ls -l totale 0 -rw-------. 1 sandro sandro 0 21 nov 11.49 a -rw-------. 1 sandro sandro 0 21 nov 11.49 b -rw-------. 1 sandro sandro 0 21 nov 11.49 c c should be: -rw-rw-r--. 1 sandro sandro 0 21 nov 11.49 c Version-Release number of selected component (if applicable): coreutils-8.10-2.fc15.i686 How reproducible: Always reproducible Additional info: Already known as existing bug by debian on older versions (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=488024)
Well, if you read the debian report again (and upstream (Jim Meyering) reaction) you'll see that upstream thinks that this behaviour is not a bug ( http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=488024#15 ). Please provide additional information supporting your opinion that this behaviour buggy ... otherwise I'm going to close the bugzilla NOTABUG.
Well, if I've umask set to 0002 and I do the following commands: $ touch a $ touch b $ chmod 600 a $ cp --no-preserve=mode a b $ ls -l -rw------- 1 sandro sandro 0 21 nov 21.54 a -rw-rw-r-- 1 sandro sandro 0 21 nov 21.54 b $ cp --preserve=mode a b $ ls -l -rw------- 1 sandro sandro 0 21 nov 21.54 a -rw------- 1 sandro sandro 0 21 nov 21.55 b If I create a new file in a directory with an umask set, I assume that the new file respects the umask. If I want to preserve the mode bits of the original file I can set --preserve. If I don't want to preserve the mode bits of the original file I set --no-preserve. But --no-preserve preserve the mode bits if destination doesn't exists, just restricting the access if the umask is stricter while doesn't change the mode bits if destination already exists. I think that cp should behave always like touch + cp if --no-preserve is specified.
Info documentation of cp states in the section of --preserve option: "In the absence of this option, each destination file is created with the mode bits of the corresponding source file, minus the bits set in the umask and minus the set-user-ID and set-group-ID bits." So this behaviour is documented for creating new file is documented properly. However - for the case of already existing file, the behaviour differs from the documented one. Not preserving attributes(including mode) is the default behaviour for the cp, and people could rely on the current behaviour. Therefore such change would probably mean additional flag for forced --no-preserve=mode ... and has to be discussed with upstream. Adding Jim to CC here...
Thank you for the report, Sandro. This may be a bug, and there's even a vague TODO entry that mentions it, which I wrote long ago. Fixing it, however, may be tricky. One approach would involve changing the semantics of the preserve_mode member. Currently it is a boolean, yet to properly support --no-preserve=mode, it would have to be tri-state: default, explicit-preserve, explicit-no-preserve. Considering the number of uses in cp.c and copy.c, and that they are in code that is relatively sensitive, I felt that the (cost+risk)/benefit ratio was too high to work on fixing this. However, if someone finds a clean way to fix it so that cp does what you expect and the change does not induce significant failures in "make check", then I'd like to see the patch.
(In reply to comment #4) ... > Fixing it, however, may be tricky. > One approach would involve changing the semantics of the preserve_mode member. Note that actually fixing it might involve only a tiny change, but it's been a long time since I carefully considered that, and the above is merely what I remember thinking would be required, so take it with a big grain of salt.
(In reply to comment #4) > Thank you for the report, Sandro. Thank you for your work :-) > One approach would involve changing the semantics of the preserve_mode member. > Currently it is a boolean, yet to properly support --no-preserve=mode, it > would have to be tri-state: default, explicit-preserve, explicit-no-preserve. I think that this could be acceptable.
Created attachment 599791 [details] Proposed patch This is my proposition of a fix. Instead of creating any tristates, I added another boolean to the cp_options structutre as an explicit check, which shouldn't upset any working code depending on the original struct.
This change was accepted upstream by http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=24ebca61a3a0f10d6cd2800b188b3c034d1c4755 . Thanks Ondrej for working on that. This commit is part of coreutils-8.20, now available in Rawhide, closing RAWHIDE.