github.com/tetratelabs/wazero@v1.2.1/internal/sysfs/rename_windows.go (about) 1 package sysfs 2 3 import ( 4 "errors" 5 "os" 6 "syscall" 7 8 "github.com/tetratelabs/wazero/internal/platform" 9 ) 10 11 func Rename(from, to string) syscall.Errno { 12 if from == to { 13 return 0 14 } 15 16 fromStat, err := os.Stat(from) 17 if err != nil { 18 return syscall.ENOENT 19 } 20 21 if toStat, err := os.Stat(to); err == nil { 22 fromIsDir, toIsDir := fromStat.IsDir(), toStat.IsDir() 23 if fromIsDir && !toIsDir { // dir to file 24 return syscall.ENOTDIR 25 } else if !fromIsDir && toIsDir { // file to dir 26 return syscall.EISDIR 27 } else if !fromIsDir && !toIsDir { // file to file 28 // Use os.Rename instead of syscall.Rename in order to allow the overrides of the existing file. 29 // Underneath os.Rename, it uses MoveFileEx instead of MoveFile (used by syscall.Rename). 30 return platform.UnwrapOSError(os.Rename(from, to)) 31 } else { // dir to dir 32 if dirs, _ := os.ReadDir(to); len(dirs) == 0 { 33 // On Windows, renaming to the empty dir will be rejected, 34 // so first we remove the empty dir, and then rename to it. 35 if err := os.Remove(to); err != nil { 36 return platform.UnwrapOSError(err) 37 } 38 return platform.UnwrapOSError(syscall.Rename(from, to)) 39 } 40 return syscall.ENOTEMPTY 41 } 42 } else if !errors.Is(err, syscall.ENOENT) { // Failed to stat the destination. 43 return platform.UnwrapOSError(err) 44 } else { // Destination not-exist. 45 return platform.UnwrapOSError(syscall.Rename(from, to)) 46 } 47 }