]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: implement wasip1 Fcntl
authorChris O'Hara <cohara87@gmail.com>
Thu, 25 May 2023 02:07:07 +0000 (12:07 +1000)
committerGopher Robot <gobot@golang.org>
Fri, 26 May 2023 17:59:52 +0000 (17:59 +0000)
CL 494915 broke non-blocking I/O on wasip1 for files
opened with os.NewFile. This is fixed by providing an
implementation of fcntl(F_GETFL) for wasip1.

Change-Id: I78979076b95495fd4b94814552e5f5b043270cd0
Reviewed-on: https://go-review.googlesource.com/c/go/+/498195
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Achille Roussel <achille.roussel@gmail.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>

src/internal/syscall/unix/fcntl_js.go [moved from src/internal/syscall/unix/fcntl_wasm.go with 92% similarity]
src/internal/syscall/unix/fcntl_wasip1.go [new file with mode: 0644]
src/runtime/internal/wasitest/nonblock_test.go
src/runtime/internal/wasitest/testdata/nonblock.go

similarity index 92%
rename from src/internal/syscall/unix/fcntl_wasm.go
rename to src/internal/syscall/unix/fcntl_js.go
index c63027398f4b4dbc73ee2ca1decb45278a19a3e2..bdfb8e046d3ffe86ec26f7d9f347f73713da80cf 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build js && wasm
+
 package unix
 
 import "syscall"
diff --git a/src/internal/syscall/unix/fcntl_wasip1.go b/src/internal/syscall/unix/fcntl_wasip1.go
new file mode 100644 (file)
index 0000000..e70cd74
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build wasip1
+
+package unix
+
+import "syscall"
+
+func Fcntl(fd int, cmd int, arg int) (int, error) {
+       if cmd == syscall.F_GETFL {
+               flags, err := fd_fdstat_get_flags(fd)
+               return int(flags), err
+       }
+       return 0, syscall.ENOSYS
+}
index d873ef55fb77cd2e1d0da176a9e9d5ba0c99adee..8fb2860e4ba28105d4dde48db70d70dfbf5ff44e 100644 (file)
@@ -43,57 +43,61 @@ func TestNonblock(t *testing.T) {
                t.Skip("wasmer does not support non-blocking I/O")
        }
 
-       args := []string{"run", "./testdata/nonblock.go"}
-
-       fifos := make([]*fifo, 8)
-       for i := range fifos {
-               path := filepath.Join(t.TempDir(), fmt.Sprintf("wasip1-nonblock-fifo-%d-%d", rand.Uint32(), i))
-               if err := syscall.Mkfifo(path, 0666); err != nil {
-                       t.Fatal(err)
-               }
-
-               file, err := os.OpenFile(path, os.O_RDWR, 0)
-               if err != nil {
-                       t.Fatal(err)
-               }
-               defer file.Close()
-
-               args = append(args, path)
-               fifos[len(fifos)-i-1] = &fifo{file, path}
-       }
-
-       subProcess := exec.Command("go", args...)
-
-       subProcess.Env = append(os.Environ(), "GOOS=wasip1", "GOARCH=wasm")
-
-       pr, pw := io.Pipe()
-       defer pw.Close()
-
-       subProcess.Stderr = pw
-
-       if err := subProcess.Start(); err != nil {
-               t.Fatal(err)
-       }
-
-       scanner := bufio.NewScanner(pr)
-       if !scanner.Scan() {
-               t.Fatal("expected line:", scanner.Err())
-       } else if scanner.Text() != "waiting" {
-               t.Fatal("unexpected output:", scanner.Text())
-       }
-
-       for _, fifo := range fifos {
-               if _, err := fifo.file.WriteString(fifo.path + "\n"); err != nil {
-                       t.Fatal(err)
-               }
-               if !scanner.Scan() {
-                       t.Fatal("expected line:", scanner.Err())
-               } else if scanner.Text() != fifo.path {
-                       t.Fatal("unexpected line:", scanner.Text())
-               }
-       }
-
-       if err := subProcess.Wait(); err != nil {
-               t.Fatal(err)
+       for _, mode := range []string{"os.OpenFile", "os.NewFile"} {
+               t.Run(mode, func(t *testing.T) {
+                       args := []string{"run", "./testdata/nonblock.go", mode}
+
+                       fifos := make([]*fifo, 8)
+                       for i := range fifos {
+                               path := filepath.Join(t.TempDir(), fmt.Sprintf("wasip1-nonblock-fifo-%d-%d", rand.Uint32(), i))
+                               if err := syscall.Mkfifo(path, 0666); err != nil {
+                                       t.Fatal(err)
+                               }
+
+                               file, err := os.OpenFile(path, os.O_RDWR, 0)
+                               if err != nil {
+                                       t.Fatal(err)
+                               }
+                               defer file.Close()
+
+                               args = append(args, path)
+                               fifos[len(fifos)-i-1] = &fifo{file, path}
+                       }
+
+                       subProcess := exec.Command("go", args...)
+
+                       subProcess.Env = append(os.Environ(), "GOOS=wasip1", "GOARCH=wasm")
+
+                       pr, pw := io.Pipe()
+                       defer pw.Close()
+
+                       subProcess.Stderr = pw
+
+                       if err := subProcess.Start(); err != nil {
+                               t.Fatal(err)
+                       }
+
+                       scanner := bufio.NewScanner(pr)
+                       if !scanner.Scan() {
+                               t.Fatal("expected line:", scanner.Err())
+                       } else if scanner.Text() != "waiting" {
+                               t.Fatal("unexpected output:", scanner.Text())
+                       }
+
+                       for _, fifo := range fifos {
+                               if _, err := fifo.file.WriteString(fifo.path + "\n"); err != nil {
+                                       t.Fatal(err)
+                               }
+                               if !scanner.Scan() {
+                                       t.Fatal("expected line:", scanner.Err())
+                               } else if scanner.Text() != fifo.path {
+                                       t.Fatal("unexpected line:", scanner.Text())
+                               }
+                       }
+
+                       if err := subProcess.Wait(); err != nil {
+                               t.Fatal(err)
+                       }
+               })
        }
 }
index 947abe7fcf83ebd2cc0f40494f80803cbed10e5e..8cbf21b3a26d50cf62c90b129ee06d8a35934fab 100644 (file)
@@ -7,17 +7,34 @@ package main
 import (
        "os"
        "sync"
+       "syscall"
 )
 
 func main() {
+       if len(os.Args) < 2 {
+               panic("usage: nonblock <MODE> [PATH...]")
+       }
+       mode := os.Args[1]
+
        ready := make(chan struct{})
 
        var wg sync.WaitGroup
-       for _, path := range os.Args[1:] {
+       for _, path := range os.Args[2:] {
                f, err := os.Open(path)
                if err != nil {
                        panic(err)
                }
+               switch mode {
+               case "os.OpenFile":
+               case "os.NewFile":
+                       fd := f.Fd()
+                       if err := syscall.SetNonblock(int(fd), true); err != nil {
+                               panic(err)
+                       }
+                       f = os.NewFile(fd, path)
+               default:
+                       panic("invalid test mode")
+               }
 
                spawnWait := make(chan struct{})