Opened 5 years ago

Last modified 5 years ago

#1634 new defect

copy-file and move-file do not preserve permissions

Reported by: alicemaz Owned by:
Priority: minor Milestone: someday
Component: core libraries Version: 5.1.0
Keywords: Cc:
Estimated difficulty: easy


both procedures create a new output file using open, so permissions are always (assuming normal umask) 644. this patch sets the permissions to those of the input file after writing all bytes and before closing the ports. tested on PLATFORM=linux. I do not know the implications of this on windows; the fact that C_chmod and C_fchmod have definitions in posixwin.scm makes me assume this is safe, but I cannot be sure without a machine to test on

Attachments (1)

0001-Keep-file-permissions-in-copy-file-and-move-file.patch (917 bytes) - added by alicemaz 5 years ago.

Download all attachments as: .zip

Change History (4)

comment:1 Changed 5 years ago by evhan

This behaviour would be ideal, but we want to avoid introducing a dependency from file to file.posix -- those libraries are currently totally distinct, neither depends on the other.

I don't see an obvious way to do the same without the dependency apart from just pulling the code we need into file.scm (and potentially #ifdeffing it as necessary). This might not be too bad, though -- we do it for symbolic-link?, for example, and all we really need in there is chmod(2) and stat(2).

comment:2 Changed 5 years ago by alicemaz

that makes sense. though my next question is, if inlining posix functionality and ifdefing it out for windows is prefereable to using chicken's existing posix interface, is there any reason not to replace the move-file function with rename(2)? again I have no idea how this works on windows, but on linux moving a file should be basically cost-free

comment:3 Changed 5 years ago by evhan

It's supposed to match the behaviour of copy-file, which actually copies a file (as in, block-by-block). rename(2) has different semantics, for example when it comes to cross-filesystem operations. rename(2) is what you get with rename-file from the chicken.file module, which like you say offers the cost-free option.

#;1> (import (chicken file))
#;2> (rename-file "/mnt/foo.txt" "/tmp/foo.txt")

Error: (rename-file) cannot rename file - Invalid cross-device link

        Call history:

        <syntax>          (rename-file "/mnt/foo.txt" "/tmp/foo.txt")
        <eval>            (rename-file "/mnt/foo.txt" "/tmp/foo.txt")   <--

Note: See TracTickets for help on using tickets.