1package copy
 2
 3import (
 4	"os"
 5)
 6
 7const (
 8	// tmpPermissionForDirectory makes the destination directory writable,
 9	// so that stuff can be copied recursively even if any original directory is NOT writable.
10	// See https://github.com/otiai10/copy/pull/9 for more information.
11	tmpPermissionForDirectory = os.FileMode(0755)
12)
13
14type PermissionControlFunc func(srcinfo fileInfo, dest string) (chmodfunc func(*error), err error)
15
16var (
17	AddPermission = func(perm os.FileMode) PermissionControlFunc {
18		return func(srcinfo fileInfo, dest string) (func(*error), error) {
19			orig := srcinfo.Mode()
20			if srcinfo.IsDir() {
21				if err := os.MkdirAll(dest, tmpPermissionForDirectory); err != nil {
22					return func(*error) {}, err
23				}
24			}
25			return func(err *error) {
26				chmod(dest, orig|perm, err)
27			}, nil
28		}
29	}
30	PerservePermission PermissionControlFunc = AddPermission(0)
31	DoNothing          PermissionControlFunc = func(srcinfo fileInfo, dest string) (func(*error), error) {
32		if srcinfo.IsDir() {
33			if err := os.MkdirAll(dest, srcinfo.Mode()); err != nil {
34				return func(*error) {}, err
35			}
36		}
37		return func(*error) {}, nil
38	}
39)
40
41// chmod ANYHOW changes file mode,
42// with asiging error raised during Chmod,
43// BUT respecting the error already reported.
44func chmod(dir string, mode os.FileMode, reported *error) {
45	if err := os.Chmod(dir, mode); *reported == nil {
46		*reported = err
47	}
48}