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  }