os: pull in os.Rename and some of its tests from upstream
Skip part of the test on Windows because of https://github.com/tinygo-org/tinygo/issues/2480 TODO: fix 2480 and unskip test TODO: pull in rest of upstream tests, fix problems they find Requested in https://github.com/tinygo-org/tinygo/issues/2109
Этот коммит содержится в:
родитель
72e15af1fa
коммит
29f7ebc63e
5 изменённых файлов: 127 добавлений и 1 удалений
|
@ -40,6 +40,14 @@ func Chdir(dir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Rename renames (moves) oldpath to newpath.
|
||||
// If newpath already exists and is not a directory, Rename replaces it.
|
||||
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
|
||||
// If there is an error, it will be of type *LinkError.
|
||||
func Rename(oldpath, newpath string) error {
|
||||
return rename(oldpath, newpath)
|
||||
}
|
||||
|
||||
// unixFilesystem is an empty handle for a Unix/Linux filesystem. All operations
|
||||
// are relative to the current working directory.
|
||||
type unixFilesystem struct {
|
||||
|
|
|
@ -18,6 +18,15 @@ func fixLongPath(path string) string {
|
|||
return path
|
||||
}
|
||||
|
||||
func rename(oldname, newname string) error {
|
||||
// TODO: import rest of upstream tests, handle fancy cases
|
||||
err := syscall.Rename(oldname, newname)
|
||||
if err != nil {
|
||||
return &LinkError{"rename", oldname, newname, err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Pipe() (r *File, w *File, err error) {
|
||||
var p [2]int
|
||||
err = handleSyscallError(syscall.Pipe2(p[:], syscall.O_CLOEXEC))
|
||||
|
|
|
@ -8,12 +8,21 @@
|
|||
package os
|
||||
|
||||
import (
|
||||
"internal/syscall/windows"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
||||
type syscallFd = syscall.Handle
|
||||
|
||||
func rename(oldname, newname string) error {
|
||||
e := windows.Rename(fixLongPath(oldname), fixLongPath(newname))
|
||||
if e != nil {
|
||||
return &LinkError{"rename", oldname, newname, e}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Pipe() (r *File, w *File, err error) {
|
||||
var p [2]syscall.Handle
|
||||
e := handleSyscallError(syscall.Pipe(p[:]))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
package os_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
. "os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
@ -35,7 +36,7 @@ func TestMkdir(t *testing.T) {
|
|||
|
||||
func TestStatBadDir(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Log("TODO: TestStatBadDir fails on Windows, skipping")
|
||||
t.Log("TODO: TestStatBadDir: IsNotExist fails on Windows, skipping")
|
||||
return
|
||||
}
|
||||
dir := TempDir()
|
||||
|
@ -94,3 +95,88 @@ func TestRemove(t *testing.T) {
|
|||
t.Fatalf("Remove: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRename(t *testing.T) {
|
||||
// TODO: use t.TempDir()
|
||||
from, to := TempDir()+"/"+"TestRename-from", TempDir()+"/"+"TestRename-to"
|
||||
|
||||
file, err := Create(from)
|
||||
defer Remove(from) // TODO: switch to t.Tempdir, remove this line
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", from, err)
|
||||
}
|
||||
defer Remove(to) // TODO: switch to t.Tempdir, remove this line
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", from, err)
|
||||
}
|
||||
err = Rename(from, to)
|
||||
if err != nil {
|
||||
t.Fatalf("rename %q, %q failed: %v", to, from, err)
|
||||
}
|
||||
_, err = Stat(to)
|
||||
if err != nil {
|
||||
t.Errorf("stat %q failed: %v", to, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameOverwriteDest(t *testing.T) {
|
||||
from, to := TempDir()+"/"+"TestRenameOverwrite-from", TempDir()+"/"+"TestRenameOverwrite-to"
|
||||
|
||||
toData := []byte("to")
|
||||
fromData := []byte("from")
|
||||
|
||||
err := ioutil.WriteFile(to, toData, 0777)
|
||||
defer Remove(to) // TODO: switch to t.Tempdir, remove this line
|
||||
if err != nil {
|
||||
t.Fatalf("write file %q failed: %v", to, err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(from, fromData, 0777)
|
||||
defer Remove(from) // TODO: switch to t.Tempdir, remove this line
|
||||
if err != nil {
|
||||
t.Fatalf("write file %q failed: %v", from, err)
|
||||
}
|
||||
err = Rename(from, to)
|
||||
if err != nil {
|
||||
t.Fatalf("rename %q, %q failed: %v", to, from, err)
|
||||
}
|
||||
|
||||
_, err = Stat(from)
|
||||
if err == nil {
|
||||
t.Errorf("from file %q still exists", from)
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Log("TODO: TestRenameOverwriteDest: IsNotExist fails on Windows, skipping")
|
||||
} else if err != nil && !IsNotExist(err) {
|
||||
t.Fatalf("stat from: %v", err)
|
||||
}
|
||||
toFi, err := Stat(to)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", to, err)
|
||||
}
|
||||
if toFi.Size() != int64(len(fromData)) {
|
||||
t.Errorf(`"to" size = %d; want %d (old "from" size)`, toFi.Size(), len(fromData))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameFailed(t *testing.T) {
|
||||
from, to := TempDir()+"/"+"RenameFailed-from", TempDir()+"/"+"RenameFailed-to"
|
||||
|
||||
err := Rename(from, to)
|
||||
switch err := err.(type) {
|
||||
case *LinkError:
|
||||
if err.Op != "rename" {
|
||||
t.Errorf("rename %q, %q: err.Op: want %q, got %q", from, to, "rename", err.Op)
|
||||
}
|
||||
if err.Old != from {
|
||||
t.Errorf("rename %q, %q: err.Old: want %q, got %q", from, to, from, err.Old)
|
||||
}
|
||||
if err.New != to {
|
||||
t.Errorf("rename %q, %q: err.New: want %q, got %q", from, to, to, err.New)
|
||||
}
|
||||
case nil:
|
||||
t.Errorf("rename %q, %q: expected error, got nil", from, to)
|
||||
default:
|
||||
t.Errorf("rename %q, %q: expected %T, got %T %v", from, to, new(LinkError), err, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,16 @@ func Rmdir(path string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func Rename(from, to string) (err error) {
|
||||
fromdata := cstring(from)
|
||||
todata := cstring(to)
|
||||
fail := int(libc_rename(&fromdata[0], &todata[0]))
|
||||
if fail < 0 {
|
||||
err = getErrno()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Unlink(path string) (err error) {
|
||||
data := cstring(path)
|
||||
fail := int(libc_unlink(&data[0]))
|
||||
|
@ -270,6 +280,10 @@ func libc_mkdir(pathname *byte, mode uint32) int32
|
|||
//export rmdir
|
||||
func libc_rmdir(pathname *byte) int32
|
||||
|
||||
// int rename(const char *from, *to);
|
||||
//export rename
|
||||
func libc_rename(from, too *byte) int32
|
||||
|
||||
// int unlink(const char *pathname);
|
||||
//export unlink
|
||||
func libc_unlink(pathname *byte) int32
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче