github.com/searKing/golang/go@v1.2.117/io/copy_linux.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package io 6 7 import ( 8 "fmt" 9 "os" 10 ) 11 12 func copyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { 13 return 0, ErrNotImplemented 14 } 15 16 func copyPath(srcPath, dstPath string, f os.FileInfo, copyMode Mode) error { 17 isHardlink := false 18 19 switch mode := f.Mode(); { 20 case mode.IsRegular(): 21 // the type is 32bit on mips 22 if copyMode == Hardlink { 23 isHardlink = true 24 if err := os.Link(srcPath, dstPath); err != nil { 25 return err 26 } 27 } else { 28 if err := CopyRegular(srcPath, dstPath, f); err != nil { 29 return err 30 } 31 } 32 33 case mode.IsDir(): 34 if err := os.Mkdir(dstPath, f.Mode()); err != nil && !os.IsExist(err) { 35 return err 36 } 37 38 case mode&os.ModeSymlink != 0: 39 link, err := os.Readlink(srcPath) 40 if err != nil { 41 return err 42 } 43 44 if err := os.Symlink(link, dstPath); err != nil { 45 return err 46 } 47 48 default: 49 return fmt.Errorf("unknown file type (%d / %s) for %s", f.Mode(), f.Mode().String(), srcPath) 50 } 51 52 // Everything below is copying metadata from src to dst. All this metadata 53 // already shares an inode for hardlinks. 54 if isHardlink { 55 return nil 56 } 57 58 isSymlink := f.Mode()&os.ModeSymlink != 0 59 60 // There is no LChmod, so ignore mode for symlink. Also, this 61 // must happen after chown, as that can modify the file mode 62 if !isSymlink { 63 if err := os.Chmod(dstPath, f.Mode()); err != nil { 64 return err 65 } 66 } 67 68 return nil 69 }