in oss/lib/cp.go [1912:1987]
func (cc *CopyCommand) getFileList(dpath string, chFiles chan<- fileInfoType) error {
if cc.cpOption.onlyCurrentDir {
return cc.getCurrentDirFileList(dpath, chFiles)
}
name := dpath
symlinkDiretorys := []string{dpath}
walkFunc := func(fpath string, f os.FileInfo, err error) error {
if f == nil {
return err
}
dpath = filepath.Clean(dpath)
fpath = filepath.Clean(fpath)
fileName, err := filepath.Rel(dpath, fpath)
if err != nil {
return fmt.Errorf("list file error: %s, info: %s", fpath, err.Error())
}
if f.IsDir() {
if fpath != dpath {
if strings.HasSuffix(fileName, "\\") || strings.HasSuffix(fileName, "/") {
chFiles <- fileInfoType{fileName, name}
} else {
chFiles <- fileInfoType{fileName + string(os.PathSeparator), name}
}
}
return nil
}
if cc.cpOption.disableAllSymlink && (f.Mode()&os.ModeSymlink) != 0 {
return nil
}
if cc.cpOption.enableSymlinkDir && (f.Mode()&os.ModeSymlink) != 0 {
// there is difference between os.Stat and os.Lstat in filepath.Walk
realInfo, err := os.Stat(fpath)
if err != nil {
return err
}
if realInfo.IsDir() {
// it's symlink dir
// if linkDir has suffix os.PathSeparator,os.Lstat determine it is a dir
if !strings.HasSuffix(name, string(os.PathSeparator)) {
name += string(os.PathSeparator)
}
linkDir := name + fileName + string(os.PathSeparator)
symlinkDiretorys = append(symlinkDiretorys, linkDir)
return nil
}
}
if doesSingleFileMatchPatterns(fileName, cc.cpOption.filters) {
chFiles <- fileInfoType{fileName, name}
}
return nil
}
var err error
for {
symlinks := symlinkDiretorys
symlinkDiretorys = []string{}
for _, v := range symlinks {
err = filepath.Walk(v, walkFunc)
if err != nil {
return err
}
}
if len(symlinkDiretorys) == 0 {
break
}
}
return err
}