From aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 6 Sep 2019 18:12:46 +0000 Subject: libgo: update to Go 1.13beta1 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/193497 From-SVN: r275473 --- libgo/misc/cgo/testshared/overlaydir_test.go | 81 ++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 libgo/misc/cgo/testshared/overlaydir_test.go (limited to 'libgo/misc/cgo/testshared/overlaydir_test.go') diff --git a/libgo/misc/cgo/testshared/overlaydir_test.go b/libgo/misc/cgo/testshared/overlaydir_test.go new file mode 100644 index 0000000..68be056 --- /dev/null +++ b/libgo/misc/cgo/testshared/overlaydir_test.go @@ -0,0 +1,81 @@ +// 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 shared_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 + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, 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.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), 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 + }) +} -- cgit v1.1