From e44cda3aa97ba0870806e65fc66641eb2cf6682a Mon Sep 17 00:00:00 2001 From: Richard Musiol Date: Sun, 1 Mar 2020 17:01:58 +0100 Subject: [PATCH] syscall: fix Fchdir on js/wasm NodeJS does not support fchdir so it has to be emulated with chdir by saving the path when opening a directory. However, if the path opened is relative, saving this path is not sufficient, because after changing the working directory the path does not resolve correctly any more, thus a subsequent fd.Chdir() fails. This change fixes the issue by resolving a relative path when opening the directory and saving the absolute path instead. Fixes #37448 Change-Id: Id6bc8c4232b0019fc11e850599a526336608ce54 Reviewed-on: https://go-review.googlesource.com/c/go/+/221717 Run-TryBot: Richard Musiol TryBot-Result: Gobot Gobot Reviewed-by: Emmanuel Odeke --- src/os/os_test.go | 35 +++++++++++++++++++++++++++++++++++ src/syscall/fs_js.go | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/src/os/os_test.go b/src/os/os_test.go index 1d8442d808..cc03b91d72 100644 --- a/src/os/os_test.go +++ b/src/os/os_test.go @@ -1242,6 +1242,41 @@ func testChtimes(t *testing.T, name string) { } } +func TestFileChdir(t *testing.T) { + // TODO(brainman): file.Chdir() is not implemented on windows. + if runtime.GOOS == "windows" { + return + } + + wd, err := Getwd() + if err != nil { + t.Fatalf("Getwd: %s", err) + } + defer Chdir(wd) + + fd, err := Open(".") + if err != nil { + t.Fatalf("Open .: %s", err) + } + defer fd.Close() + + if err := Chdir("/"); err != nil { + t.Fatalf("Chdir /: %s", err) + } + + if err := fd.Chdir(); err != nil { + t.Fatalf("fd.Chdir: %s", err) + } + + wdNew, err := Getwd() + if err != nil { + t.Fatalf("Getwd: %s", err) + } + if wdNew != wd { + t.Fatalf("fd.Chdir failed, got %s, want %s", wdNew, wd) + } +} + func TestChdirAndGetwd(t *testing.T) { // TODO(brainman): file.Chdir() is not implemented on windows. if runtime.GOOS == "windows" { diff --git a/src/syscall/fs_js.go b/src/syscall/fs_js.go index c1cac97d91..262ec28afd 100644 --- a/src/syscall/fs_js.go +++ b/src/syscall/fs_js.go @@ -102,6 +102,10 @@ func Open(path string, openmode int, perm uint32) (int, error) { } } + if path[0] != '/' { + cwd := jsProcess.Call("cwd").String() + path = cwd + "/" + path + } f := &jsFile{ path: path, entries: entries,