Mercurial > hg > CbC > CbC_gcc
view libgo/misc/cgo/life/overlaydir_test.go @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
line wrap: on
line source
// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package life_test import ( "io" "os" "path/filepath" "strings" ) // overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. // // TODO: Once we no longer need to support the misc module in GOPATH mode, // factor this function out into a package to reduce duplication. func overlayDir(dstRoot, srcRoot string) error { dstRoot = filepath.Clean(dstRoot) if err := os.MkdirAll(dstRoot, 0777); err != nil { return err } srcRoot, err := filepath.Abs(srcRoot) if err != nil { return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { if err != nil || srcPath == srcRoot { return err } suffix := strings.TrimPrefix(srcPath, srcRoot) for len(suffix) > 0 && suffix[0] == filepath.Separator { suffix = suffix[1:] } dstPath := filepath.Join(dstRoot, suffix) perm := info.Mode() & os.ModePerm if info.Mode()&os.ModeSymlink != 0 { info, err = os.Stat(srcPath) if err != nil { return err } perm = info.Mode() & os.ModePerm } // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. if err := os.Symlink(srcPath, dstPath); err == nil { return nil } // Otherwise, copy the bytes. src, err := os.Open(srcPath) if err != nil { return err } defer src.Close() dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) if err != nil { return err } _, err = io.Copy(dst, src) if closeErr := dst.Close(); err == nil { err = closeErr } return err }) }