m90
m90

Reputation: 11822

How do I copy a file retaining the original permissions?

I would like to copy a file using pure Go, emulating the behavior of cp -p.

My copy function currently looks like:

// copy creates a copy of the file located at `dst` at `src`.
func copyFile(src, dst string) error {
    in, err := os.Open(src)
    if err != nil {
        return err
    }
    defer in.Close()

    out, err := os.Create(dst)
    if err != nil {
        return err
    }

    _, err = io.Copy(out, in)
    if err != nil {
        out.Close()
        return err
    }
    return out.Close()
}

which will create dst owned by whoever is running the process. Instead, I would like to keep the owner and permissions of src, i.e. what I get from:

// copy creates a copy of the file located at `dst` at `src`.
func copyFile(src, dst string) error {
    cmd := exec.Command("cp", "-p", src, dst)
    return cmd.Run()
}

but without having to call through to system commands (for portability). Everything I tried ended up calling through to something else. Is this possible to do in Go?

Upvotes: 2

Views: 1097

Answers (1)

kostix
kostix

Reputation: 55453

It's definitely possible in Go but not in a system-independent manner (because different OS kernels have different ideas about what "permissions" are, and how they are implemented).

Also consider that the identity used by the process copying the file might have insufficient permissions to set permissions on the target file (for instance, on Linux, a non-root user cannot change the owning group of a file to a group the user is not a member of, and it obviously cannot set the file owner to anyone other than theirselves — in other words, mere mortals cannot transfer ownerwhip, only share files within their own "circles" defined by group membership).

Basically, to do what you'r after, you have to Stat the source file and then os.Chmod (and os.Chown, if needed) the destination file after it is created.


Also please note that Linux-native filesystems support POSIX ACLs on files, and each file might or might not have them.
Whether you include this in what you define "permissions" are, is an open question.

Upvotes: 4

Related Questions