95e99e629c
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
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, 0o755)
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return err
|
|
}
|
|
f, err := os.OpenFile(path, os.O_CREATE, 0o755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
f.Close()
|
|
}
|
|
}
|
|
return nil
|
|
}
|