| package fileutils // import "github.com/docker/docker/pkg/fileutils" | |
| import ( | |
| "fmt" | |
| "io" | |
| "os" | |
| "path/filepath" | |
| ) | |
| // CopyFile copies from src to dst until either EOF is reached | |
| // on src or an error occurs. It verifies src exists and removes | |
| // the dst if it exists. | |
| func CopyFile(src, dst string) (int64, error) { | |
| cleanSrc := filepath.Clean(src) | |
| cleanDst := filepath.Clean(dst) | |
| if cleanSrc == cleanDst { | |
| return 0, nil | |
| } | |
| sf, err := os.Open(cleanSrc) | |
| if err != nil { | |
| return 0, err | |
| } | |
| defer sf.Close() | |
| if err := os.Remove(cleanDst); err != nil && !os.IsNotExist(err) { | |
| return 0, err | |
| } | |
| df, err := os.Create(cleanDst) | |
| if err != nil { | |
| return 0, err | |
| } | |
| defer df.Close() | |
| return io.Copy(df, sf) | |
| } | |
| // ReadSymlinkedDirectory returns the target directory of a symlink. | |
| // The target of the symbolic link may not be a file. | |
| func ReadSymlinkedDirectory(path string) (realPath string, err error) { | |
| if realPath, err = filepath.Abs(path); err != nil { | |
| return "", fmt.Errorf("unable to get absolute path for %s: %w", path, err) | |
| } | |
| if realPath, err = filepath.EvalSymlinks(realPath); err != nil { | |
| return "", fmt.Errorf("failed to canonicalise path for %s: %w", path, err) | |
| } | |
| realPathInfo, err := os.Stat(realPath) | |
| if err != nil { | |
| return "", fmt.Errorf("failed to stat target '%s' of '%s': %w", realPath, path, err) | |
| } | |
| if !realPathInfo.Mode().IsDir() { | |
| return "", fmt.Errorf("canonical path points to a file '%s'", realPath) | |
| } | |
| return realPath, nil | |
| } | |
| // CreateIfNotExists creates a file or a directory only if it does not already exist. | |
| func CreateIfNotExists(path string, isDir bool) error { | |
| if _, err := os.Stat(path); err != nil { | |
| if os.IsNotExist(err) { | |
| if isDir { | |
| return os.MkdirAll(path, 0755) | |
| } | |
| if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { | |
| return err | |
| } | |
| f, err := os.OpenFile(path, os.O_CREATE, 0755) | |
| if err != nil { | |
| return err | |
| } | |
| f.Close() | |
| } | |
| } | |
| return nil | |
| } |