Files
wazero/internal/sysfs/rename_windows.go
Crypt Keeper 34324031cb extracts FS interfaces into fsapi package and consolidates impls (#1477)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Co-authored-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
2023-05-17 07:19:54 +03:00

48 lines
1.4 KiB
Go

package sysfs
import (
"errors"
"os"
"syscall"
"github.com/tetratelabs/wazero/internal/platform"
)
func Rename(from, to string) syscall.Errno {
if from == to {
return 0
}
fromStat, err := os.Stat(from)
if err != nil {
return syscall.ENOENT
}
if toStat, err := os.Stat(to); err == nil {
fromIsDir, toIsDir := fromStat.IsDir(), toStat.IsDir()
if fromIsDir && !toIsDir { // dir to file
return syscall.ENOTDIR
} else if !fromIsDir && toIsDir { // file to dir
return syscall.EISDIR
} else if !fromIsDir && !toIsDir { // file to file
// Use os.Rename instead of syscall.Rename in order to allow the overrides of the existing file.
// Underneath os.Rename, it uses MoveFileEx instead of MoveFile (used by syscall.Rename).
return platform.UnwrapOSError(os.Rename(from, to))
} else { // dir to dir
if dirs, _ := os.ReadDir(to); len(dirs) == 0 {
// On Windows, renaming to the empty dir will be rejected,
// so first we remove the empty dir, and then rename to it.
if err := os.Remove(to); err != nil {
return platform.UnwrapOSError(err)
}
return platform.UnwrapOSError(syscall.Rename(from, to))
}
return syscall.ENOTEMPTY
}
} else if !errors.Is(err, syscall.ENOENT) { // Failed to stat the destination.
return platform.UnwrapOSError(err)
} else { // Destination not-exist.
return platform.UnwrapOSError(syscall.Rename(from, to))
}
}