dotcloud/docker

View on GitHub
pkg/fileutils/fileutils.go

Summary

Maintainability
A
0 mins
Test Coverage
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
}