aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/os
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-07-30 14:28:58 -0700
committerIan Lance Taylor <iant@golang.org>2021-08-12 20:23:07 -0700
commitc5b21c3f4c17b0649155035d2f9aa97b2da8a813 (patch)
treec6d3a68b503ba5b16182acbb958e3e5dbc95a43b /libgo/go/os
parent72be20e20299ec57b4bc9ba03d5b7d6bf10e97cc (diff)
downloadgcc-c5b21c3f4c17b0649155035d2f9aa97b2da8a813.zip
gcc-c5b21c3f4c17b0649155035d2f9aa97b2da8a813.tar.gz
gcc-c5b21c3f4c17b0649155035d2f9aa97b2da8a813.tar.bz2
libgo: update to Go1.17rc2
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/341629
Diffstat (limited to 'libgo/go/os')
-rw-r--r--libgo/go/os/env_unix_test.go1
-rw-r--r--libgo/go/os/error.go6
-rw-r--r--libgo/go/os/error_errno.go1
-rw-r--r--libgo/go/os/error_posix.go1
-rw-r--r--libgo/go/os/error_test.go24
-rw-r--r--libgo/go/os/error_unix_test.go1
-rw-r--r--libgo/go/os/error_windows_test.go1
-rw-r--r--libgo/go/os/example_test.go5
-rw-r--r--libgo/go/os/exec.go3
-rw-r--r--libgo/go/os/exec/exec_linux_test.go1
-rw-r--r--libgo/go/os/exec/exec_posix_test.go1
-rw-r--r--libgo/go/os/exec/exec_test.go52
-rw-r--r--libgo/go/os/exec/exec_unix.go1
-rw-r--r--libgo/go/os/exec/exec_windows_test.go43
-rw-r--r--libgo/go/os/exec/lp_js.go1
-rw-r--r--libgo/go/os/exec/lp_unix.go1
-rw-r--r--libgo/go/os/exec/lp_unix_test.go9
-rw-r--r--libgo/go/os/exec/read3.go1
-rw-r--r--libgo/go/os/exec_plan9.go3
-rw-r--r--libgo/go/os/exec_posix.go11
-rw-r--r--libgo/go/os/exec_unix.go1
-rw-r--r--libgo/go/os/exec_unix_test.go1
-rw-r--r--libgo/go/os/exec_windows.go23
-rw-r--r--libgo/go/os/executable_path.go1
-rw-r--r--libgo/go/os/executable_plan9.go8
-rw-r--r--libgo/go/os/executable_procfs.go22
-rw-r--r--libgo/go/os/executable_sysctl.go1
-rw-r--r--libgo/go/os/executable_test.go65
-rw-r--r--libgo/go/os/export_unix_test.go1
-rw-r--r--libgo/go/os/export_windows_test.go1
-rw-r--r--libgo/go/os/fifo_test.go11
-rw-r--r--libgo/go/os/file.go20
-rw-r--r--libgo/go/os/file_plan9.go2
-rw-r--r--libgo/go/os/file_posix.go1
-rw-r--r--libgo/go/os/file_unix.go6
-rw-r--r--libgo/go/os/os_test.go56
-rw-r--r--libgo/go/os/os_unix_test.go1
-rw-r--r--libgo/go/os/os_windows_test.go101
-rw-r--r--libgo/go/os/path_test.go17
-rw-r--r--libgo/go/os/path_unix.go1
-rw-r--r--libgo/go/os/path_windows.go7
-rw-r--r--libgo/go/os/path_windows_test.go29
-rw-r--r--libgo/go/os/pipe2_bsd.go3
-rw-r--r--libgo/go/os/pipe2_illumos.go1
-rw-r--r--libgo/go/os/pipe_bsd.go3
-rw-r--r--libgo/go/os/pipe_test.go12
-rw-r--r--libgo/go/os/rawconn.go1
-rw-r--r--libgo/go/os/rawconn_test.go1
-rw-r--r--libgo/go/os/readfrom_linux_test.go6
-rw-r--r--libgo/go/os/readfrom_stub.go1
-rw-r--r--libgo/go/os/removeall_at.go1
-rw-r--r--libgo/go/os/removeall_noat.go1
-rw-r--r--libgo/go/os/removeall_test.go53
-rw-r--r--libgo/go/os/signal/doc.go8
-rw-r--r--libgo/go/os/signal/example_unix_test.go1
-rw-r--r--libgo/go/os/signal/internal/pty/pty.go1
-rw-r--r--libgo/go/os/signal/signal_cgo_test.go1
-rw-r--r--libgo/go/os/signal/signal_linux_test.go1
-rw-r--r--libgo/go/os/signal/signal_plan9_test.go18
-rw-r--r--libgo/go/os/signal/signal_test.go18
-rw-r--r--libgo/go/os/signal/signal_unix.go1
-rw-r--r--libgo/go/os/stat_js.go1
-rw-r--r--libgo/go/os/stat_test.go45
-rw-r--r--libgo/go/os/stat_unix.go1
-rw-r--r--libgo/go/os/sticky_bsd.go1
-rw-r--r--libgo/go/os/sticky_notbsd.go1
-rw-r--r--libgo/go/os/str.go32
-rw-r--r--libgo/go/os/sys_bsd.go1
-rw-r--r--libgo/go/os/sys_js.go1
-rw-r--r--libgo/go/os/sys_unix.go1
-rw-r--r--libgo/go/os/tempfile.go7
-rw-r--r--libgo/go/os/timeout_test.go5
-rw-r--r--libgo/go/os/types_unix.go4
-rw-r--r--libgo/go/os/user/cgo_lookup_unix.go4
-rw-r--r--libgo/go/os/user/cgo_unix_test.go4
-rw-r--r--libgo/go/os/user/listgroups_aix.go3
-rw-r--r--libgo/go/os/user/listgroups_illumos.go (renamed from libgo/go/os/user/listgroups_solaris.go)7
-rw-r--r--libgo/go/os/user/listgroups_unix.go6
-rw-r--r--libgo/go/os/user/lookup_android.go1
-rw-r--r--libgo/go/os/user/lookup_stubs.go1
-rw-r--r--libgo/go/os/user/lookup_unix.go74
-rw-r--r--libgo/go/os/user/lookup_unix_test.go17
-rw-r--r--libgo/go/os/user/user_test.go2
-rw-r--r--libgo/go/os/wait_unimp.go3
-rw-r--r--libgo/go/os/wait_wait6.go11
-rw-r--r--libgo/go/os/wait_waitid.go3
86 files changed, 533 insertions, 378 deletions
diff --git a/libgo/go/os/env_unix_test.go b/libgo/go/os/env_unix_test.go
index fd21ddd..0336323 100644
--- a/libgo/go/os/env_unix_test.go
+++ b/libgo/go/os/env_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package os_test
diff --git a/libgo/go/os/error.go b/libgo/go/os/error.go
index 704a6fb..fe8f2a8 100644
--- a/libgo/go/os/error.go
+++ b/libgo/go/os/error.go
@@ -78,7 +78,7 @@ func NewSyscallError(syscall string, err error) error {
// well as some syscall errors.
//
// This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, os.ErrExist).
+// the os package. New code should use errors.Is(err, fs.ErrExist).
func IsExist(err error) bool {
return underlyingErrorIs(err, ErrExist)
}
@@ -88,7 +88,7 @@ func IsExist(err error) bool {
// ErrNotExist as well as some syscall errors.
//
// This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, os.ErrNotExist).
+// the os package. New code should use errors.Is(err, fs.ErrNotExist).
func IsNotExist(err error) bool {
return underlyingErrorIs(err, ErrNotExist)
}
@@ -98,7 +98,7 @@ func IsNotExist(err error) bool {
// as some syscall errors.
//
// This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, os.ErrPermission).
+// the os package. New code should use errors.Is(err, fs.ErrPermission).
func IsPermission(err error) bool {
return underlyingErrorIs(err, ErrPermission)
}
diff --git a/libgo/go/os/error_errno.go b/libgo/go/os/error_errno.go
index 31ae05a..580e915 100644
--- a/libgo/go/os/error_errno.go
+++ b/libgo/go/os/error_errno.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !plan9
// +build !plan9
package os
diff --git a/libgo/go/os/error_posix.go b/libgo/go/os/error_posix.go
index 7d5a19c..7a7c860 100644
--- a/libgo/go/os/error_posix.go
+++ b/libgo/go/os/error_posix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows
package os
diff --git a/libgo/go/os/error_test.go b/libgo/go/os/error_test.go
index 6264ccc..4ab6246 100644
--- a/libgo/go/os/error_test.go
+++ b/libgo/go/os/error_test.go
@@ -33,7 +33,12 @@ func TestErrIsExist(t *testing.T) {
}
}
-func testErrNotExist(name string) string {
+func testErrNotExist(t *testing.T, name string) string {
+ originalWD, err := os.Getwd()
+ if err != nil {
+ t.Fatal(err)
+ }
+
f, err := os.Open(name)
if err == nil {
f.Close()
@@ -45,7 +50,10 @@ func testErrNotExist(name string) string {
err = os.Chdir(name)
if err == nil {
- return "Chdir should have failed"
+ if err := os.Chdir(originalWD); err != nil {
+ t.Fatalf("Chdir should have failed, failed to restore original working directory: %v", err)
+ }
+ return "Chdir should have failed, restored original working directory"
}
if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err, fs.ErrNotExist); s != "" {
return s
@@ -54,21 +62,15 @@ func testErrNotExist(name string) string {
}
func TestErrIsNotExist(t *testing.T) {
- tmpDir, err := os.MkdirTemp("", "_Go_ErrIsNotExist")
- if err != nil {
- t.Fatalf("create ErrIsNotExist tempdir: %s", err)
- return
- }
- defer os.RemoveAll(tmpDir)
-
+ tmpDir := t.TempDir()
name := filepath.Join(tmpDir, "NotExists")
- if s := testErrNotExist(name); s != "" {
+ if s := testErrNotExist(t, name); s != "" {
t.Fatal(s)
return
}
name = filepath.Join(name, "NotExists2")
- if s := testErrNotExist(name); s != "" {
+ if s := testErrNotExist(t, name); s != "" {
t.Fatal(s)
return
}
diff --git a/libgo/go/os/error_unix_test.go b/libgo/go/os/error_unix_test.go
index dd9f317..3f419d5 100644
--- a/libgo/go/os/error_unix_test.go
+++ b/libgo/go/os/error_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os_test
diff --git a/libgo/go/os/error_windows_test.go b/libgo/go/os/error_windows_test.go
index b8191c5..aa0c14b 100644
--- a/libgo/go/os/error_windows_test.go
+++ b/libgo/go/os/error_windows_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build windows
// +build windows
package os_test
diff --git a/libgo/go/os/example_test.go b/libgo/go/os/example_test.go
index 3adce51..e8554b0 100644
--- a/libgo/go/os/example_test.go
+++ b/libgo/go/os/example_test.go
@@ -5,6 +5,7 @@
package os_test
import (
+ "errors"
"fmt"
"io/fs"
"log"
@@ -71,9 +72,9 @@ func ExampleFileMode() {
}
}
-func ExampleIsNotExist() {
+func ExampleErrNotExist() {
filename := "a-nonexistent-file"
- if _, err := os.Stat(filename); os.IsNotExist(err) {
+ if _, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) {
fmt.Println("file does not exist")
}
// Output:
diff --git a/libgo/go/os/exec.go b/libgo/go/os/exec.go
index edb773a..bc75d4d 100644
--- a/libgo/go/os/exec.go
+++ b/libgo/go/os/exec.go
@@ -54,6 +54,9 @@ type ProcAttr struct {
// standard error. An implementation may support additional entries,
// depending on the underlying operating system. A nil entry corresponds
// to that file being closed when the process starts.
+ // On Unix systems, StartProcess will change these File values
+ // to blocking mode, which means that SetDeadline will stop working
+ // and calling Close will not interrupt a Read or Write.
Files []*File
// Operating system-specific process creation attributes.
diff --git a/libgo/go/os/exec/exec_linux_test.go b/libgo/go/os/exec/exec_linux_test.go
index 6f85020..3cfa30e 100644
--- a/libgo/go/os/exec/exec_linux_test.go
+++ b/libgo/go/os/exec/exec_linux_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux && cgo
// +build linux,cgo
// On systems that use glibc, calling malloc can create a new arena,
diff --git a/libgo/go/os/exec/exec_posix_test.go b/libgo/go/os/exec/exec_posix_test.go
index d4d67ac..7b2c0c0 100644
--- a/libgo/go/os/exec/exec_posix_test.go
+++ b/libgo/go/os/exec/exec_posix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package exec_test
diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go
index 8b0c93f..d854e0d 100644
--- a/libgo/go/os/exec/exec_test.go
+++ b/libgo/go/os/exec/exec_test.go
@@ -488,7 +488,7 @@ func numOpenFDsAndroid(t *testing.T) (n int, lsof []byte) {
}
func TestExtraFilesFDShuffle(t *testing.T) {
- t.Skip("flaky test; see https://golang.org/issue/5780")
+ testenv.SkipFlaky(t, 5780)
switch runtime.GOOS {
case "windows":
t.Skip("no operating system support; skipping")
@@ -915,6 +915,16 @@ func TestHelperProcess(*testing.T) {
case "sleep":
time.Sleep(3 * time.Second)
os.Exit(0)
+ case "pipehandle":
+ handle, _ := strconv.ParseUint(args[0], 16, 64)
+ pipe := os.NewFile(uintptr(handle), "")
+ _, err := fmt.Fprint(pipe, args[1])
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "writing to pipe failed: %v\n", err)
+ os.Exit(1)
+ }
+ pipe.Close()
+ os.Exit(0)
default:
fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
os.Exit(2)
@@ -1042,41 +1052,18 @@ func TestContextCancel(t *testing.T) {
defer cancel()
c := helperCommandContext(t, ctx, "cat")
- r, w, err := os.Pipe()
- if err != nil {
- t.Fatal(err)
- }
- c.Stdin = r
-
- stdout, err := c.StdoutPipe()
+ stdin, err := c.StdinPipe()
if err != nil {
t.Fatal(err)
}
- readDone := make(chan struct{})
- go func() {
- defer close(readDone)
- var a [1024]byte
- for {
- n, err := stdout.Read(a[:])
- if err != nil {
- if err != io.EOF {
- t.Errorf("unexpected read error: %v", err)
- }
- return
- }
- t.Logf("%s", a[:n])
- }
- }()
+ defer stdin.Close()
if err := c.Start(); err != nil {
t.Fatal(err)
}
- if err := r.Close(); err != nil {
- t.Fatal(err)
- }
-
- if _, err := io.WriteString(w, "echo"); err != nil {
+ // At this point the process is alive. Ensure it by sending data to stdin.
+ if _, err := io.WriteString(stdin, "echo"); err != nil {
t.Fatal(err)
}
@@ -1086,20 +1073,15 @@ func TestContextCancel(t *testing.T) {
// should now fail. Give the process a little while to die.
start := time.Now()
for {
- if _, err := io.WriteString(w, "echo"); err != nil {
+ if _, err := io.WriteString(stdin, "echo"); err != nil {
break
}
- if time.Since(start) > time.Second {
+ if time.Since(start) > time.Minute {
t.Fatal("canceling context did not stop program")
}
time.Sleep(time.Millisecond)
}
- if err := w.Close(); err != nil {
- t.Errorf("error closing write end of pipe: %v", err)
- }
- <-readDone
-
if err := c.Wait(); err == nil {
t.Error("program unexpectedly exited successfully")
} else {
diff --git a/libgo/go/os/exec/exec_unix.go b/libgo/go/os/exec/exec_unix.go
index 51c5242..467c069 100644
--- a/libgo/go/os/exec/exec_unix.go
+++ b/libgo/go/os/exec/exec_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !plan9 && !windows
// +build !plan9,!windows
package exec
diff --git a/libgo/go/os/exec/exec_windows_test.go b/libgo/go/os/exec/exec_windows_test.go
new file mode 100644
index 0000000..fbccffe
--- /dev/null
+++ b/libgo/go/os/exec/exec_windows_test.go
@@ -0,0 +1,43 @@
+// Copyright 2021 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 windows
+// +build windows
+
+package exec_test
+
+import (
+ "io"
+ "os"
+ "strconv"
+ "syscall"
+ "testing"
+)
+
+func TestPipePassing(t *testing.T) {
+ r, w, err := os.Pipe()
+ if err != nil {
+ t.Error(err)
+ }
+ const marker = "arrakis, dune, desert planet"
+ childProc := helperCommand(t, "pipehandle", strconv.FormatUint(uint64(w.Fd()), 16), marker)
+ childProc.SysProcAttr = &syscall.SysProcAttr{AdditionalInheritedHandles: []syscall.Handle{syscall.Handle(w.Fd())}}
+ err = childProc.Start()
+ if err != nil {
+ t.Error(err)
+ }
+ w.Close()
+ response, err := io.ReadAll(r)
+ if err != nil {
+ t.Error(err)
+ }
+ r.Close()
+ if string(response) != marker {
+ t.Errorf("got %q; want %q", string(response), marker)
+ }
+ err = childProc.Wait()
+ if err != nil {
+ t.Error(err)
+ }
+}
diff --git a/libgo/go/os/exec/lp_js.go b/libgo/go/os/exec/lp_js.go
index 6750fb9..4eac25f 100644
--- a/libgo/go/os/exec/lp_js.go
+++ b/libgo/go/os/exec/lp_js.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build js && wasm
// +build js,wasm
package exec
diff --git a/libgo/go/os/exec/lp_unix.go b/libgo/go/os/exec/lp_unix.go
index bb5a3ec..ebecc74 100644
--- a/libgo/go/os/exec/lp_unix.go
+++ b/libgo/go/os/exec/lp_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package exec
diff --git a/libgo/go/os/exec/lp_unix_test.go b/libgo/go/os/exec/lp_unix_test.go
index 23d1506..fe4df1a 100644
--- a/libgo/go/os/exec/lp_unix_test.go
+++ b/libgo/go/os/exec/lp_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package exec
@@ -36,13 +37,7 @@ func TestLookPathUnixEmptyPath(t *testing.T) {
t.Fatal("Close failed: ", err)
}
- pathenv := os.Getenv("PATH")
- defer os.Setenv("PATH", pathenv)
-
- err = os.Setenv("PATH", "")
- if err != nil {
- t.Fatal("Setenv failed: ", err)
- }
+ t.Setenv("PATH", "")
path, err := LookPath("exec_me")
if err == nil {
diff --git a/libgo/go/os/exec/read3.go b/libgo/go/os/exec/read3.go
index 8cc24da..a8c7183 100644
--- a/libgo/go/os/exec/read3.go
+++ b/libgo/go/os/exec/read3.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build ignore
// +build ignore
// This is a test program that verifies that it can read from
diff --git a/libgo/go/os/exec_plan9.go b/libgo/go/os/exec_plan9.go
index 8580153..cc84f97 100644
--- a/libgo/go/os/exec_plan9.go
+++ b/libgo/go/os/exec_plan9.go
@@ -5,6 +5,7 @@
package os
import (
+ "internal/itoa"
"runtime"
"syscall"
"time"
@@ -40,7 +41,7 @@ func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
}
func (p *Process) writeProcFile(file string, data string) error {
- f, e := OpenFile("/proc/"+itoa(p.Pid)+"/"+file, O_WRONLY, 0)
+ f, e := OpenFile("/proc/"+itoa.Itoa(p.Pid)+"/"+file, O_WRONLY, 0)
if e != nil {
return e
}
diff --git a/libgo/go/os/exec_posix.go b/libgo/go/os/exec_posix.go
index aa8dfe0..eb5cbc8 100644
--- a/libgo/go/os/exec_posix.go
+++ b/libgo/go/os/exec_posix.go
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows
package os
import (
+ "internal/itoa"
"internal/syscall/execenv"
"runtime"
"syscall"
@@ -102,13 +104,18 @@ func (p *ProcessState) String() string {
res := ""
switch {
case status.Exited():
- res = "exit status " + itoa(status.ExitStatus())
+ code := status.ExitStatus()
+ if runtime.GOOS == "windows" && uint(code) >= 1<<16 { // windows uses large hex numbers
+ res = "exit status " + uitox(uint(code))
+ } else { // unix systems use small decimal integers
+ res = "exit status " + itoa.Itoa(code) // unix
+ }
case status.Signaled():
res = "signal: " + status.Signal().String()
case status.Stopped():
res = "stop signal: " + status.StopSignal().String()
if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
- res += " (trap " + itoa(status.TrapCause()) + ")"
+ res += " (trap " + itoa.Itoa(status.TrapCause()) + ")"
}
case status.Continued():
res = "continued"
diff --git a/libgo/go/os/exec_unix.go b/libgo/go/os/exec_unix.go
index 69eb615..4ada050 100644
--- a/libgo/go/os/exec_unix.go
+++ b/libgo/go/os/exec_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os
diff --git a/libgo/go/os/exec_unix_test.go b/libgo/go/os/exec_unix_test.go
index d942cdb..f14b351 100644
--- a/libgo/go/os/exec_unix_test.go
+++ b/libgo/go/os/exec_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package os_test
diff --git a/libgo/go/os/exec_windows.go b/libgo/go/os/exec_windows.go
index 5710401..239bed1 100644
--- a/libgo/go/os/exec_windows.go
+++ b/libgo/go/os/exec_windows.go
@@ -45,16 +45,6 @@ func (p *Process) wait() (ps *ProcessState, err error) {
return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
}
-func terminateProcess(pid, exitcode int) error {
- h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid))
- if e != nil {
- return NewSyscallError("OpenProcess", e)
- }
- defer syscall.CloseHandle(h)
- e = syscall.TerminateProcess(h, uint32(exitcode))
- return NewSyscallError("TerminateProcess", e)
-}
-
func (p *Process) signal(sig Signal) error {
handle := atomic.LoadUintptr(&p.handle)
if handle == uintptr(syscall.InvalidHandle) {
@@ -64,16 +54,22 @@ func (p *Process) signal(sig Signal) error {
return ErrProcessDone
}
if sig == Kill {
- err := terminateProcess(p.Pid, 1)
+ var terminationHandle syscall.Handle
+ e := syscall.DuplicateHandle(^syscall.Handle(0), syscall.Handle(handle), ^syscall.Handle(0), &terminationHandle, syscall.PROCESS_TERMINATE, false, 0)
+ if e != nil {
+ return NewSyscallError("DuplicateHandle", e)
+ }
runtime.KeepAlive(p)
- return err
+ defer syscall.CloseHandle(terminationHandle)
+ e = syscall.TerminateProcess(syscall.Handle(terminationHandle), 1)
+ return NewSyscallError("TerminateProcess", e)
}
// TODO(rsc): Handle Interrupt too?
return syscall.Errno(syscall.EWINDOWS)
}
func (p *Process) release() error {
- handle := atomic.LoadUintptr(&p.handle)
+ handle := atomic.SwapUintptr(&p.handle, uintptr(syscall.InvalidHandle))
if handle == uintptr(syscall.InvalidHandle) {
return syscall.EINVAL
}
@@ -81,7 +77,6 @@ func (p *Process) release() error {
if e != nil {
return NewSyscallError("CloseHandle", e)
}
- atomic.StoreUintptr(&p.handle, uintptr(syscall.InvalidHandle))
// no need for a finalizer anymore
runtime.SetFinalizer(p, nil)
return nil
diff --git a/libgo/go/os/executable_path.go b/libgo/go/os/executable_path.go
index 7b8b836..625430e 100644
--- a/libgo/go/os/executable_path.go
+++ b/libgo/go/os/executable_path.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || openbsd
// +build aix openbsd
package os
diff --git a/libgo/go/os/executable_plan9.go b/libgo/go/os/executable_plan9.go
index a5947ea..ad7a441 100644
--- a/libgo/go/os/executable_plan9.go
+++ b/libgo/go/os/executable_plan9.go
@@ -2,14 +2,18 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build plan9
// +build plan9
package os
-import "syscall"
+import (
+ "internal/itoa"
+ "syscall"
+)
func executable() (string, error) {
- fn := "/proc/" + itoa(Getpid()) + "/text"
+ fn := "/proc/" + itoa.Itoa(Getpid()) + "/text"
f, err := Open(fn)
if err != nil {
return "", err
diff --git a/libgo/go/os/executable_procfs.go b/libgo/go/os/executable_procfs.go
index 989a220..fdb2394 100644
--- a/libgo/go/os/executable_procfs.go
+++ b/libgo/go/os/executable_procfs.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build hurd || linux || netbsd || (js && wasm)
// +build hurd linux netbsd js,wasm
package os
@@ -11,10 +12,7 @@ import (
"runtime"
)
-// We query the executable path at init time to avoid the problem of
-// readlink returns a path appended with " (deleted)" when the original
-// binary gets deleted.
-var executablePath, executablePathErr = func() (string, error) {
+func executable() (string, error) {
var procfn string
switch runtime.GOOS {
default:
@@ -24,9 +22,17 @@ var executablePath, executablePathErr = func() (string, error) {
case "netbsd":
procfn = "/proc/curproc/exe"
}
- return Readlink(procfn)
-}()
+ path, err := Readlink(procfn)
-func executable() (string, error) {
- return executablePath, executablePathErr
+ // When the executable has been deleted then Readlink returns a
+ // path appended with " (deleted)".
+ return stringsTrimSuffix(path, " (deleted)"), err
+}
+
+// stringsTrimSuffix is the same as strings.TrimSuffix.
+func stringsTrimSuffix(s, suffix string) string {
+ if len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix {
+ return s[:len(s)-len(suffix)]
+ }
+ return s
}
diff --git a/libgo/go/os/executable_sysctl.go b/libgo/go/os/executable_sysctl.go
index f9a4b18..039448b 100644
--- a/libgo/go/os/executable_sysctl.go
+++ b/libgo/go/os/executable_sysctl.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build freebsd || dragonfly
// +build freebsd dragonfly
package os
diff --git a/libgo/go/os/executable_test.go b/libgo/go/os/executable_test.go
index f25ee0c..719d6a6 100644
--- a/libgo/go/os/executable_test.go
+++ b/libgo/go/os/executable_test.go
@@ -86,3 +86,68 @@ func init() {
os.Exit(0)
}
}
+
+func TestExecutableDeleted(t *testing.T) {
+ testenv.MustHaveExec(t)
+ switch runtime.GOOS {
+ case "windows", "plan9":
+ t.Skipf("%v does not support deleting running binary", runtime.GOOS)
+ case "openbsd", "freebsd", "aix":
+ t.Skipf("%v does not support reading deleted binary name", runtime.GOOS)
+ }
+
+ dir := t.TempDir()
+
+ src := filepath.Join(dir, "testdel.go")
+ exe := filepath.Join(dir, "testdel.exe")
+
+ err := os.WriteFile(src, []byte(testExecutableDeletion), 0666)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ out, err := osexec.Command(testenv.GoToolPath(t), "build", "-o", exe, src).CombinedOutput()
+ t.Logf("build output:\n%s", out)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ out, err = osexec.Command(exe).CombinedOutput()
+ t.Logf("exec output:\n%s", out)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+const testExecutableDeletion = `package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ before, err := os.Executable()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to read executable name before deletion: %v\n", err)
+ os.Exit(1)
+ }
+
+ err = os.Remove(before)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to remove executable: %v\n", err)
+ os.Exit(1)
+ }
+
+ after, err := os.Executable()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to read executable name after deletion: %v\n", err)
+ os.Exit(1)
+ }
+
+ if before != after {
+ fmt.Fprintf(os.Stderr, "before and after do not match: %v != %v\n", before, after)
+ os.Exit(1)
+ }
+}
+`
diff --git a/libgo/go/os/export_unix_test.go b/libgo/go/os/export_unix_test.go
index f4d399d..dd2f8ec 100644
--- a/libgo/go/os/export_unix_test.go
+++ b/libgo/go/os/export_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os
diff --git a/libgo/go/os/export_windows_test.go b/libgo/go/os/export_windows_test.go
index f36fadb..ff4f899 100644
--- a/libgo/go/os/export_windows_test.go
+++ b/libgo/go/os/export_windows_test.go
@@ -8,6 +8,7 @@ package os
var (
FixLongPath = fixLongPath
+ CanUseLongPaths = canUseLongPaths
NewConsoleFile = newConsoleFile
CommandLineToArgv = commandLineToArgv
)
diff --git a/libgo/go/os/fifo_test.go b/libgo/go/os/fifo_test.go
index 2439192..007ed29 100644
--- a/libgo/go/os/fifo_test.go
+++ b/libgo/go/os/fifo_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd
package os_test
@@ -25,17 +26,9 @@ func TestFifoEOF(t *testing.T) {
switch runtime.GOOS {
case "android":
t.Skip("skipping on Android; mkfifo syscall not available")
- case "openbsd":
- // On OpenBSD 6.2 this test just hangs for some reason.
- t.Skip("skipping on OpenBSD; issue 25877")
}
- dir, err := os.MkdirTemp("", "TestFifoEOF")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(dir)
-
+ dir := t.TempDir()
fifoName := filepath.Join(dir, "fifo")
if err := syscall.Mkfifo(fifoName, 0600); err != nil {
t.Fatal(err)
diff --git a/libgo/go/os/file.go b/libgo/go/os/file.go
index 52dd943..e717f17 100644
--- a/libgo/go/os/file.go
+++ b/libgo/go/os/file.go
@@ -44,11 +44,13 @@ import (
"errors"
"internal/poll"
"internal/testlog"
+ "internal/unsafeheader"
"io"
"io/fs"
"runtime"
"syscall"
"time"
+ "unsafe"
)
// Name returns the name of the file as presented to Open.
@@ -246,7 +248,12 @@ func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
// WriteString is like Write, but writes the contents of string s rather than
// a slice of bytes.
func (f *File) WriteString(s string) (n int, err error) {
- return f.Write([]byte(s))
+ var b []byte
+ hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
+ hdr.Data = (*unsafeheader.String)(unsafe.Pointer(&s)).Data
+ hdr.Cap = len(s)
+ hdr.Len = len(s)
+ return f.Write(b)
}
// Mkdir creates a new directory with the specified name and permission
@@ -644,6 +651,17 @@ func (dir dirFS) Open(name string) (fs.File, error) {
return f, nil
}
+func (dir dirFS) Stat(name string) (fs.FileInfo, error) {
+ if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
+ return nil, &PathError{Op: "stat", Path: name, Err: ErrInvalid}
+ }
+ f, err := Stat(string(dir) + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+ return f, nil
+}
+
// ReadFile reads the named file and returns the contents.
// A successful call returns err == nil, not err == EOF.
// Because ReadFile reads the whole file, it does not treat an EOF from Read
diff --git a/libgo/go/os/file_plan9.go b/libgo/go/os/file_plan9.go
index 4f384e9..604aea6 100644
--- a/libgo/go/os/file_plan9.go
+++ b/libgo/go/os/file_plan9.go
@@ -440,6 +440,8 @@ func Link(oldname, newname string) error {
}
// Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
// If there is an error, it will be of type *LinkError.
func Symlink(oldname, newname string) error {
return &LinkError{"symlink", oldname, newname, syscall.EPLAN9}
diff --git a/libgo/go/os/file_posix.go b/libgo/go/os/file_posix.go
index 95bf9e7..21831a7 100644
--- a/libgo/go/os/file_posix.go
+++ b/libgo/go/os/file_posix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows
package os
diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go
index 5888d48..a31800bd 100644
--- a/libgo/go/os/file_unix.go
+++ b/libgo/go/os/file_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os
@@ -173,7 +174,7 @@ func newFile(fd uintptr, name string, kind newFileKind) *File {
// with the netpoll system. That can happen for
// a file descriptor that is not supported by
// epoll/kqueue; for example, disk files on
- // GNU/Linux systems. We assume that any real error
+ // Linux systems. We assume that any real error
// will show up in later I/O.
} else if pollable {
// We successfully registered with netpoll, so put
@@ -261,6 +262,7 @@ func (file *file) close() error {
var err error
if file.dirinfo != nil {
file.dirinfo.close()
+ file.dirinfo = nil
}
if e := file.pfd.Close(); e != nil {
if e == poll.ErrFileClosing {
@@ -363,6 +365,8 @@ func Link(oldname, newname string) error {
}
// Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
// If there is an error, it will be of type *LinkError.
func Symlink(oldname, newname string) error {
e := ignoringEINTR(func() error {
diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go
index 734c655..0cde454 100644
--- a/libgo/go/os/os_test.go
+++ b/libgo/go/os/os_test.go
@@ -615,11 +615,7 @@ func TestReaddirNValues(t *testing.T) {
if testing.Short() {
t.Skip("test.short; skipping")
}
- dir, err := os.MkdirTemp("", "")
- if err != nil {
- t.Fatalf("TempDir: %v", err)
- }
- defer RemoveAll(dir)
+ dir := t.TempDir()
for i := 1; i <= 105; i++ {
f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
if err != nil {
@@ -714,11 +710,7 @@ func TestReaddirStatFailures(t *testing.T) {
// testing it wouldn't work.
t.Skipf("skipping test on %v", runtime.GOOS)
}
- dir, err := os.MkdirTemp("", "")
- if err != nil {
- t.Fatalf("TempDir: %v", err)
- }
- defer RemoveAll(dir)
+ dir := t.TempDir()
touch(t, filepath.Join(dir, "good1"))
touch(t, filepath.Join(dir, "x")) // will disappear or have an error
touch(t, filepath.Join(dir, "good2"))
@@ -1951,22 +1943,16 @@ func TestAppend(t *testing.T) {
func TestStatDirWithTrailingSlash(t *testing.T) {
// Create new temporary directory and arrange to clean it up.
- path, err := os.MkdirTemp("", "_TestStatDirWithSlash_")
- if err != nil {
- t.Fatalf("TempDir: %s", err)
- }
- defer RemoveAll(path)
+ path := t.TempDir()
// Stat of path should succeed.
- _, err = Stat(path)
- if err != nil {
+ if _, err := Stat(path); err != nil {
t.Fatalf("stat %s failed: %s", path, err)
}
// Stat of path+"/" should succeed too.
path += "/"
- _, err = Stat(path)
- if err != nil {
+ if _, err := Stat(path); err != nil {
t.Fatalf("stat %s failed: %s", path, err)
}
}
@@ -2093,12 +2079,7 @@ func TestLargeWriteToConsole(t *testing.T) {
func TestStatDirModeExec(t *testing.T) {
const mode = 0111
- path, err := os.MkdirTemp("", "go-build")
- if err != nil {
- t.Fatalf("Failed to create temp directory: %v", err)
- }
- defer RemoveAll(path)
-
+ path := t.TempDir()
if err := Chmod(path, 0777); err != nil {
t.Fatalf("Chmod %q 0777: %v", path, err)
}
@@ -2162,12 +2143,7 @@ func TestStatStdin(t *testing.T) {
func TestStatRelativeSymlink(t *testing.T) {
testenv.MustHaveSymlink(t)
- tmpdir, err := os.MkdirTemp("", "TestStatRelativeSymlink")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tmpdir)
-
+ tmpdir := t.TempDir()
target := filepath.Join(tmpdir, "target")
f, err := Create(target)
if err != nil {
@@ -2775,3 +2751,21 @@ func TestReadFileProc(t *testing.T) {
t.Fatalf("read %s: not newline-terminated: %q", name, data)
}
}
+
+func TestWriteStringAlloc(t *testing.T) {
+ if runtime.GOOS == "js" {
+ t.Skip("js allocates a lot during File.WriteString")
+ }
+ d := t.TempDir()
+ f, err := Create(filepath.Join(d, "whiteboard.txt"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer f.Close()
+ allocs := testing.AllocsPerRun(100, func() {
+ f.WriteString("I will not allocate when passed a string longer than 32 bytes.\n")
+ })
+ if allocs != 0 {
+ t.Errorf("expected 0 allocs for File.WriteString, got %v", allocs)
+ }
+}
diff --git a/libgo/go/os/os_unix_test.go b/libgo/go/os/os_unix_test.go
index 9a5d7bf..95ceb0d 100644
--- a/libgo/go/os/os_unix_test.go
+++ b/libgo/go/os/os_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os_test
diff --git a/libgo/go/os/os_windows_test.go b/libgo/go/os/os_windows_test.go
index b0929b4..195c30f 100644
--- a/libgo/go/os/os_windows_test.go
+++ b/libgo/go/os/os_windows_test.go
@@ -29,22 +29,32 @@ import (
// For TestRawConnReadWrite.
type syscallDescriptor = syscall.Handle
-func TestSameWindowsFile(t *testing.T) {
- temp, err := os.MkdirTemp("", "TestSameWindowsFile")
+// chdir changes the current working directory to the named directory,
+// and then restore the original working directory at the end of the test.
+func chdir(t *testing.T, dir string) {
+ olddir, err := os.Getwd()
if err != nil {
- t.Fatal(err)
+ t.Fatalf("chdir: %v", err)
}
- defer os.RemoveAll(temp)
-
- wd, err := os.Getwd()
- if err != nil {
- t.Fatal(err)
+ if err := os.Chdir(dir); err != nil {
+ t.Fatalf("chdir %s: %v", dir, err)
}
- err = os.Chdir(temp)
+
+ t.Cleanup(func() {
+ if err := os.Chdir(olddir); err != nil {
+ t.Errorf("chdir to original working directory %s: %v", olddir, err)
+ os.Exit(1)
+ }
+ })
+}
+
+func TestSameWindowsFile(t *testing.T) {
+ temp, err := os.MkdirTemp("", "TestSameWindowsFile")
if err != nil {
t.Fatal(err)
}
- defer os.Chdir(wd)
+ defer os.RemoveAll(temp)
+ chdir(t, temp)
f, err := os.Create("a")
if err != nil {
@@ -94,16 +104,7 @@ func testDirLinks(t *testing.T, tests []dirLinkTest) {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
-
- oldwd, err := os.Getwd()
- if err != nil {
- t.Fatal(err)
- }
- err = os.Chdir(tmpdir)
- if err != nil {
- t.Fatal(err)
- }
- defer os.Chdir(oldwd)
+ chdir(t, tmpdir)
dir := filepath.Join(tmpdir, "dir")
err = os.Mkdir(dir, 0777)
@@ -444,15 +445,7 @@ func TestNetworkSymbolicLink(t *testing.T) {
}
defer os.RemoveAll(dir)
- oldwd, err := os.Getwd()
- if err != nil {
- t.Fatal(err)
- }
- err = os.Chdir(dir)
- if err != nil {
- t.Fatal(err)
- }
- defer os.Chdir(oldwd)
+ chdir(t, dir)
shareName := "GoSymbolicLinkTestShare" // hope no conflictions
sharePath := filepath.Join(dir, shareName)
@@ -604,16 +597,7 @@ func TestOpenVolumeName(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
-
- wd, err := os.Getwd()
- if err != nil {
- t.Fatal(err)
- }
- err = os.Chdir(tmpdir)
- if err != nil {
- t.Fatal(err)
- }
- defer os.Chdir(wd)
+ chdir(t, tmpdir)
want := []string{"file1", "file2", "file3", "gopher.txt"}
sort.Strings(want)
@@ -642,11 +626,7 @@ func TestOpenVolumeName(t *testing.T) {
}
func TestDeleteReadOnly(t *testing.T) {
- tmpdir, err := os.MkdirTemp("", "TestDeleteReadOnly")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tmpdir)
+ tmpdir := t.TempDir()
p := filepath.Join(tmpdir, "a")
// This sets FILE_ATTRIBUTE_READONLY.
f, err := os.OpenFile(p, os.O_CREATE, 0400)
@@ -812,11 +792,7 @@ func compareCommandLineToArgvWithSyscall(t *testing.T, cmd string) {
}
func TestCmdArgs(t *testing.T) {
- tmpdir, err := os.MkdirTemp("", "TestCmdArgs")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tmpdir)
+ tmpdir := t.TempDir()
const prog = `
package main
@@ -831,8 +807,7 @@ func main() {
}
`
src := filepath.Join(tmpdir, "main.go")
- err = os.WriteFile(src, []byte(prog), 0666)
- if err != nil {
+ if err := os.WriteFile(src, []byte(prog), 0666); err != nil {
t.Fatal(err)
}
@@ -979,21 +954,14 @@ func TestSymlinkCreation(t *testing.T) {
}
t.Parallel()
- temp, err := os.MkdirTemp("", "TestSymlinkCreation")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(temp)
-
+ temp := t.TempDir()
dummyFile := filepath.Join(temp, "file")
- err = os.WriteFile(dummyFile, []byte(""), 0644)
- if err != nil {
+ if err := os.WriteFile(dummyFile, []byte(""), 0644); err != nil {
t.Fatal(err)
}
linkFile := filepath.Join(temp, "link")
- err = os.Symlink(dummyFile, linkFile)
- if err != nil {
+ if err := os.Symlink(dummyFile, linkFile); err != nil {
t.Fatal(err)
}
}
@@ -1226,16 +1194,7 @@ func TestWindowsReadlink(t *testing.T) {
if err != nil {
t.Fatal(err)
}
-
- wd, err := os.Getwd()
- if err != nil {
- t.Fatal(err)
- }
- err = os.Chdir(tmpdir)
- if err != nil {
- t.Fatal(err)
- }
- defer os.Chdir(wd)
+ chdir(t, tmpdir)
vol := filepath.VolumeName(tmpdir)
output, err := osexec.Command("cmd", "/c", "mountvol", vol, "/L").CombinedOutput()
diff --git a/libgo/go/os/path_test.go b/libgo/go/os/path_test.go
index b79d958..4535abb 100644
--- a/libgo/go/os/path_test.go
+++ b/libgo/go/os/path_test.go
@@ -6,7 +6,6 @@ package os_test
import (
"internal/testenv"
- "os"
. "os"
"path/filepath"
"runtime"
@@ -78,27 +77,19 @@ func TestMkdirAll(t *testing.T) {
func TestMkdirAllWithSymlink(t *testing.T) {
testenv.MustHaveSymlink(t)
- tmpDir, err := os.MkdirTemp("", "TestMkdirAllWithSymlink-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tmpDir)
-
+ tmpDir := t.TempDir()
dir := tmpDir + "/dir"
- err = Mkdir(dir, 0755)
- if err != nil {
+ if err := Mkdir(dir, 0755); err != nil {
t.Fatalf("Mkdir %s: %s", dir, err)
}
link := tmpDir + "/link"
- err = Symlink("dir", link)
- if err != nil {
+ if err := Symlink("dir", link); err != nil {
t.Fatalf("Symlink %s: %s", link, err)
}
path := link + "/foo"
- err = MkdirAll(path, 0755)
- if err != nil {
+ if err := MkdirAll(path, 0755); err != nil {
t.Errorf("MkdirAll %q: %s", path, err)
}
}
diff --git a/libgo/go/os/path_unix.go b/libgo/go/os/path_unix.go
index 6ef6560..bb0b0a0 100644
--- a/libgo/go/os/path_unix.go
+++ b/libgo/go/os/path_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os
diff --git a/libgo/go/os/path_windows.go b/libgo/go/os/path_windows.go
index 87b1cac..a96245f 100644
--- a/libgo/go/os/path_windows.go
+++ b/libgo/go/os/path_windows.go
@@ -128,6 +128,10 @@ func dirname(path string) string {
return vol + dir
}
+// This is set via go:linkname on runtime.canUseLongPaths, and is true when the OS
+// supports opting into proper long path handling without the need for fixups.
+var canUseLongPaths bool
+
// fixLongPath returns the extended-length (\\?\-prefixed) form of
// path when needed, in order to avoid the default 260 character file
// path limit imposed by Windows. If path is not easily converted to
@@ -137,6 +141,9 @@ func dirname(path string) string {
//
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
func fixLongPath(path string) string {
+ if canUseLongPaths {
+ return path
+ }
// Do nothing (and don't allocate) if the path is "short".
// Empirically (at least on the Windows Server 2013 builder),
// the kernel is arbitrarily okay with < 248 bytes. That
diff --git a/libgo/go/os/path_windows_test.go b/libgo/go/os/path_windows_test.go
index 869db8f..e960bcb 100644
--- a/libgo/go/os/path_windows_test.go
+++ b/libgo/go/os/path_windows_test.go
@@ -12,6 +12,9 @@ import (
)
func TestFixLongPath(t *testing.T) {
+ if os.CanUseLongPaths {
+ return
+ }
// 248 is long enough to trigger the longer-than-248 checks in
// fixLongPath, but short enough not to make a path component
// longer than 255, which is illegal on Windows. (which
@@ -46,12 +49,22 @@ func TestFixLongPath(t *testing.T) {
}
}
-func TestMkdirAllExtendedLength(t *testing.T) {
- tmpDir, err := os.MkdirTemp("", "TestMkdirAllExtendedLength")
- if err != nil {
- t.Fatal(err)
+func TestMkdirAllLongPath(t *testing.T) {
+ tmpDir := t.TempDir()
+ path := tmpDir
+ for i := 0; i < 100; i++ {
+ path += `\another-path-component`
+ }
+ if err := os.MkdirAll(path, 0777); err != nil {
+ t.Fatalf("MkdirAll(%q) failed; %v", path, err)
+ }
+ if err := os.RemoveAll(tmpDir); err != nil {
+ t.Fatalf("RemoveAll(%q) failed; %v", tmpDir, err)
}
- defer os.RemoveAll(tmpDir)
+}
+
+func TestMkdirAllExtendedLength(t *testing.T) {
+ tmpDir := t.TempDir()
const prefix = `\\?\`
if len(tmpDir) < 4 || tmpDir[:4] != prefix {
@@ -62,14 +75,12 @@ func TestMkdirAllExtendedLength(t *testing.T) {
tmpDir = prefix + fullPath
}
path := tmpDir + `\dir\`
- err = os.MkdirAll(path, 0777)
- if err != nil {
+ if err := os.MkdirAll(path, 0777); err != nil {
t.Fatalf("MkdirAll(%q) failed: %v", path, err)
}
path = path + `.\dir2`
- err = os.MkdirAll(path, 0777)
- if err == nil {
+ if err := os.MkdirAll(path, 0777); err == nil {
t.Fatalf("MkdirAll(%q) should have failed, but did not", path)
}
}
diff --git a/libgo/go/os/pipe2_bsd.go b/libgo/go/os/pipe2_bsd.go
index 0ef894b..bf6d081 100644
--- a/libgo/go/os/pipe2_bsd.go
+++ b/libgo/go/os/pipe2_bsd.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build freebsd netbsd openbsd
+//go:build dragonfly || freebsd || netbsd || openbsd
+// +build dragonfly freebsd netbsd openbsd
package os
diff --git a/libgo/go/os/pipe2_illumos.go b/libgo/go/os/pipe2_illumos.go
index 026ce62..71b8cb8 100644
--- a/libgo/go/os/pipe2_illumos.go
+++ b/libgo/go/os/pipe2_illumos.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build illumos
// +build illumos
package os
diff --git a/libgo/go/os/pipe_bsd.go b/libgo/go/os/pipe_bsd.go
index 115d6ba..097b32e 100644
--- a/libgo/go/os/pipe_bsd.go
+++ b/libgo/go/os/pipe_bsd.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly js,wasm solaris,!illumos
+//go:build aix || darwin || (js && wasm) || (solaris && !illumos)
+// +build aix darwin js,wasm solaris,!illumos
package os
diff --git a/libgo/go/os/pipe_test.go b/libgo/go/os/pipe_test.go
index b98e538..41a1e9c 100644
--- a/libgo/go/os/pipe_test.go
+++ b/libgo/go/os/pipe_test.go
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
// Test broken pipes on Unix systems.
+//go:build !plan9 && !js
// +build !plan9,!js
package os_test
@@ -441,12 +442,14 @@ func TestFdReadRace(t *testing.T) {
defer r.Close()
defer w.Close()
- c := make(chan bool)
+ const count = 10
+
+ c := make(chan bool, 1)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
- var buf [10]byte
+ var buf [count]byte
r.SetReadDeadline(time.Now().Add(time.Minute))
c <- true
if _, err := r.Read(buf[:]); os.IsTimeout(err) {
@@ -465,8 +468,9 @@ func TestFdReadRace(t *testing.T) {
r.Fd()
// The bug was that Fd would hang until Read timed out.
- // If the bug is fixed, then closing r here will cause
- // the Read to exit before the timeout expires.
+ // If the bug is fixed, then writing to w and closing r here
+ // will cause the Read to exit before the timeout expires.
+ w.Write(make([]byte, count))
r.Close()
}()
diff --git a/libgo/go/os/rawconn.go b/libgo/go/os/rawconn.go
index 9e11cda..ffc598b 100644
--- a/libgo/go/os/rawconn.go
+++ b/libgo/go/os/rawconn.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !plan9
// +build !plan9
package os
diff --git a/libgo/go/os/rawconn_test.go b/libgo/go/os/rawconn_test.go
index 2554f5b..8aebaf8 100644
--- a/libgo/go/os/rawconn_test.go
+++ b/libgo/go/os/rawconn_test.go
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
// Test use of raw connections.
+//go:build !plan9 && !js
// +build !plan9,!js
package os_test
diff --git a/libgo/go/os/readfrom_linux_test.go b/libgo/go/os/readfrom_linux_test.go
index 1d145da..cb6a59a 100644
--- a/libgo/go/os/readfrom_linux_test.go
+++ b/libgo/go/os/readfrom_linux_test.go
@@ -106,7 +106,7 @@ func TestCopyFileRange(t *testing.T) {
t.Fatal(err)
}
if n != int64(len(data)) {
- t.Fatalf("transfered %d, want %d", n, len(data))
+ t.Fatalf("transferred %d, want %d", n, len(data))
}
if !hook.called {
t.Fatalf("should have called poll.CopyFileRange")
@@ -130,7 +130,7 @@ func TestCopyFileRange(t *testing.T) {
t.Fatal(err)
}
if n != int64(len(data)) {
- t.Fatalf("transfered %d, want %d", n, len(data))
+ t.Fatalf("transferred %d, want %d", n, len(data))
}
if !hook.called {
t.Fatalf("should have called poll.CopyFileRange")
@@ -162,7 +162,7 @@ func TestCopyFileRange(t *testing.T) {
t.Fatal(err)
}
if n != int64(len(data)) {
- t.Fatalf("transfered %d, want %d", n, len(data))
+ t.Fatalf("transferred %d, want %d", n, len(data))
}
if !hook.called {
t.Fatalf("should have called poll.CopyFileRange")
diff --git a/libgo/go/os/readfrom_stub.go b/libgo/go/os/readfrom_stub.go
index 65429d0..826760f 100644
--- a/libgo/go/os/readfrom_stub.go
+++ b/libgo/go/os/readfrom_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !linux
// +build !linux
package os
diff --git a/libgo/go/os/removeall_at.go b/libgo/go/os/removeall_at.go
index f9eafa1..4e55577 100644
--- a/libgo/go/os/removeall_at.go
+++ b/libgo/go/os/removeall_at.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package os
diff --git a/libgo/go/os/removeall_noat.go b/libgo/go/os/removeall_noat.go
index a4cde5a..966f3f5 100644
--- a/libgo/go/os/removeall_noat.go
+++ b/libgo/go/os/removeall_noat.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !aix && !darwin && !dragonfly && !freebsd && !hurd && !linux && !netbsd && !openbsd && !solaris
// +build !aix,!darwin,!dragonfly,!freebsd,!hurd,!linux,!netbsd,!openbsd,!solaris
package os
diff --git a/libgo/go/os/removeall_test.go b/libgo/go/os/removeall_test.go
index 3a2f6e3..08dfdd8 100644
--- a/libgo/go/os/removeall_test.go
+++ b/libgo/go/os/removeall_test.go
@@ -15,12 +15,7 @@ import (
)
func TestRemoveAll(t *testing.T) {
- tmpDir, err := os.MkdirTemp("", "TestRemoveAll-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tmpDir)
-
+ tmpDir := t.TempDir()
if err := RemoveAll(""); err != nil {
t.Errorf("RemoveAll(\"\"): %v; want nil", err)
}
@@ -128,12 +123,7 @@ func TestRemoveAllLarge(t *testing.T) {
t.Skip("skipping in short mode")
}
- tmpDir, err := os.MkdirTemp("", "TestRemoveAll-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tmpDir)
-
+ tmpDir := t.TempDir()
path := filepath.Join(tmpDir, "_TestRemoveAllLarge_")
// Make directory with 1000 files and remove.
@@ -236,12 +226,7 @@ func TestRemoveAllDot(t *testing.T) {
func TestRemoveAllDotDot(t *testing.T) {
t.Parallel()
- tempDir, err := os.MkdirTemp("", "TestRemoveAllDotDot-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tempDir)
-
+ tempDir := t.TempDir()
subdir := filepath.Join(tempDir, "x")
subsubdir := filepath.Join(subdir, "y")
if err := MkdirAll(subsubdir, 0777); err != nil {
@@ -261,12 +246,7 @@ func TestRemoveAllDotDot(t *testing.T) {
func TestRemoveReadOnlyDir(t *testing.T) {
t.Parallel()
- tempDir, err := os.MkdirTemp("", "TestRemoveReadOnlyDir-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tempDir)
-
+ tempDir := t.TempDir()
subdir := filepath.Join(tempDir, "x")
if err := Mkdir(subdir, 0); err != nil {
t.Fatal(err)
@@ -298,12 +278,7 @@ func TestRemoveAllButReadOnlyAndPathError(t *testing.T) {
t.Parallel()
- tempDir, err := os.MkdirTemp("", "TestRemoveAllButReadOnly-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tempDir)
-
+ tempDir := t.TempDir()
dirs := []string{
"a",
"a/x",
@@ -347,7 +322,7 @@ func TestRemoveAllButReadOnlyAndPathError(t *testing.T) {
defer Chmod(d, 0777)
}
- err = RemoveAll(tempDir)
+ err := RemoveAll(tempDir)
if err == nil {
t.Fatal("RemoveAll succeeded unexpectedly")
}
@@ -389,12 +364,7 @@ func TestRemoveUnreadableDir(t *testing.T) {
t.Parallel()
- tempDir, err := os.MkdirTemp("", "TestRemoveAllButReadOnly-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tempDir)
-
+ tempDir := t.TempDir()
target := filepath.Join(tempDir, "d0", "d1", "d2")
if err := MkdirAll(target, 0755); err != nil {
t.Fatal(err)
@@ -413,12 +383,7 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) {
t.Skip("skipping in short mode")
}
- tmpDir, err := os.MkdirTemp("", "TestRemoveAll-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tmpDir)
-
+ tmpDir := t.TempDir()
path := filepath.Join(tmpDir, "_TestRemoveAllWithMoreErrorThanReqSize_")
// Make directory with 1025 read-only files.
@@ -443,7 +408,7 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) {
// This call should not hang, even on a platform that disallows file deletion
// from read-only directories.
- err = RemoveAll(path)
+ err := RemoveAll(path)
if Getuid() == 0 {
// On many platforms, root can remove files from read-only directories.
diff --git a/libgo/go/os/signal/doc.go b/libgo/go/os/signal/doc.go
index 2229d36..7af61d2 100644
--- a/libgo/go/os/signal/doc.go
+++ b/libgo/go/os/signal/doc.go
@@ -50,7 +50,7 @@ If the Go program is started with either SIGHUP or SIGINT ignored
If the Go program is started with a non-empty signal mask, that will
generally be honored. However, some signals are explicitly unblocked:
the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
-and, on GNU/Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
+and, on Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
(SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
started by os.Exec, or by the os/exec package, will inherit the
modified signal mask.
@@ -129,9 +129,7 @@ If the non-Go code installs any signal handlers, it must use the
SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
the program to crash if the signal is received. Go programs routinely
run with a limited stack, and therefore set up an alternate signal
-stack. Also, the Go standard library expects that any signal handlers
-will use the SA_RESTART flag. Failing to do so may cause some library
-calls to return "interrupted system call" errors.
+stack.
If the non-Go code installs a signal handler for any of the
synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
@@ -178,7 +176,7 @@ will initialize signals at global constructor time. For
shared library is loaded.
If the Go runtime sees an existing signal handler for the SIGCANCEL or
-SIGSETXID signals (which are used only on GNU/Linux), it will turn on
+SIGSETXID signals (which are used only on Linux), it will turn on
the SA_ONSTACK flag and otherwise keep the signal handler.
For the synchronous signals and SIGPIPE, the Go runtime will install a
diff --git a/libgo/go/os/signal/example_unix_test.go b/libgo/go/os/signal/example_unix_test.go
index a0af37a..3f7795b 100644
--- a/libgo/go/os/signal/example_unix_test.go
+++ b/libgo/go/os/signal/example_unix_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package signal_test
diff --git a/libgo/go/os/signal/internal/pty/pty.go b/libgo/go/os/signal/internal/pty/pty.go
index dd0aee1..4ed3eb4 100644
--- a/libgo/go/os/signal/internal/pty/pty.go
+++ b/libgo/go/os/signal/internal/pty/pty.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (aix || darwin || dragonfly || freebsd || hurd || (linux && !android) || netbsd || openbsd || solaris) && cgo
// +build aix darwin dragonfly freebsd hurd linux,!android netbsd openbsd solaris
// +build cgo
diff --git a/libgo/go/os/signal/signal_cgo_test.go b/libgo/go/os/signal/signal_cgo_test.go
index a8a4856..e1e4509 100644
--- a/libgo/go/os/signal/signal_cgo_test.go
+++ b/libgo/go/os/signal/signal_cgo_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd) && cgo
// +build darwin dragonfly freebsd linux,!android netbsd openbsd
// +build cgo
diff --git a/libgo/go/os/signal/signal_linux_test.go b/libgo/go/os/signal/signal_linux_test.go
index 2e553d0..7abe1ec 100644
--- a/libgo/go/os/signal/signal_linux_test.go
+++ b/libgo/go/os/signal/signal_linux_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux
// +build linux
package signal
diff --git a/libgo/go/os/signal/signal_plan9_test.go b/libgo/go/os/signal/signal_plan9_test.go
index 10bfdc3..8357199 100644
--- a/libgo/go/os/signal/signal_plan9_test.go
+++ b/libgo/go/os/signal/signal_plan9_test.go
@@ -5,6 +5,7 @@
package signal
import (
+ "internal/itoa"
"os"
"runtime"
"syscall"
@@ -155,23 +156,8 @@ func TestStop(t *testing.T) {
}
}
-func itoa(val int) string {
- if val < 0 {
- return "-" + itoa(-val)
- }
- var buf [32]byte // big enough for int64
- i := len(buf) - 1
- for val >= 10 {
- buf[i] = byte(val%10 + '0')
- i--
- val /= 10
- }
- buf[i] = byte(val + '0')
- return string(buf[i:])
-}
-
func postNote(pid int, note string) error {
- f, err := os.OpenFile("/proc/"+itoa(pid)+"/note", os.O_WRONLY, 0)
+ f, err := os.OpenFile("/proc/"+itoa.Itoa(pid)+"/note", os.O_WRONLY, 0)
if err != nil {
return err
}
diff --git a/libgo/go/os/signal/signal_test.go b/libgo/go/os/signal/signal_test.go
index 1f89780..c653c34 100644
--- a/libgo/go/os/signal/signal_test.go
+++ b/libgo/go/os/signal/signal_test.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package signal
@@ -17,6 +18,7 @@ import (
"runtime"
"runtime/trace"
"strconv"
+ "strings"
"sync"
"syscall"
"testing"
@@ -30,6 +32,11 @@ import (
// The current value is set based on flakes observed in the Go builders.
var settleTime = 100 * time.Millisecond
+// fatalWaitingTime is an absurdly long time to wait for signals to be
+// delivered but, using it, we (hopefully) eliminate test flakes on the
+// build servers. See #46736 for discussion.
+var fatalWaitingTime = 30 * time.Second
+
func init() {
if testenv.Builder() == "solaris-amd64-oraclerel" {
// The solaris-amd64-oraclerel builder has been observed to time out in
@@ -46,6 +53,13 @@ func init() {
//
// See https://golang.org/issue/33174.
settleTime = 11 * time.Second
+ } else if runtime.GOOS == "linux" && strings.HasPrefix(runtime.GOARCH, "ppc64") {
+ // Older linux kernels seem to have some hiccups delivering the signal
+ // in a timely manner on ppc64 and ppc64le. When running on a
+ // ppc64le/ubuntu 16.04/linux 4.4 host the time can vary quite
+ // substantially even on a idle system. 5 seconds is twice any value
+ // observed when running 10000 tests on such a system.
+ settleTime = 5 * time.Second
} else if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
if scale, err := strconv.Atoi(s); err == nil {
settleTime *= time.Duration(scale)
@@ -75,7 +89,7 @@ func waitSig1(t *testing.T, c <-chan os.Signal, sig os.Signal, all bool) {
// General user code should filter out all unexpected signals instead of just
// SIGURG, but since os/signal is tightly coupled to the runtime it seems
// appropriate to be stricter here.
- for time.Since(start) < settleTime {
+ for time.Since(start) < fatalWaitingTime {
select {
case s := <-c:
if s == sig {
@@ -88,7 +102,7 @@ func waitSig1(t *testing.T, c <-chan os.Signal, sig os.Signal, all bool) {
timer.Reset(settleTime / 10)
}
}
- t.Fatalf("timeout after %v waiting for %v", settleTime, sig)
+ t.Fatalf("timeout after %v waiting for %v", fatalWaitingTime, sig)
}
// quiesce waits until we can be reasonably confident that all pending signals
diff --git a/libgo/go/os/signal/signal_unix.go b/libgo/go/os/signal/signal_unix.go
index c18db0c..a0c7ffb 100644
--- a/libgo/go/os/signal/signal_unix.go
+++ b/libgo/go/os/signal/signal_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows
package signal
diff --git a/libgo/go/os/stat_js.go b/libgo/go/os/stat_js.go
index 8d20ccd..3badf5b 100644
--- a/libgo/go/os/stat_js.go
+++ b/libgo/go/os/stat_js.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build js && wasm
// +build js,wasm
package os
diff --git a/libgo/go/os/stat_test.go b/libgo/go/os/stat_test.go
index c409f0f..8d99f64 100644
--- a/libgo/go/os/stat_test.go
+++ b/libgo/go/os/stat_test.go
@@ -185,30 +185,22 @@ func testSymlinkSameFile(t *testing.T, path, link string) {
func TestDirAndSymlinkStats(t *testing.T) {
testenv.MustHaveSymlink(t)
- tmpdir, err := os.MkdirTemp("", "TestDirAndSymlinkStats")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tmpdir)
-
+ tmpdir := t.TempDir()
dir := filepath.Join(tmpdir, "dir")
- err = os.Mkdir(dir, 0777)
- if err != nil {
+ if err := os.Mkdir(dir, 0777); err != nil {
t.Fatal(err)
}
testDirStats(t, dir)
dirlink := filepath.Join(tmpdir, "link")
- err = os.Symlink(dir, dirlink)
- if err != nil {
+ if err := os.Symlink(dir, dirlink); err != nil {
t.Fatal(err)
}
testSymlinkStats(t, dirlink, true)
testSymlinkSameFile(t, dir, dirlink)
linklink := filepath.Join(tmpdir, "linklink")
- err = os.Symlink(dirlink, linklink)
- if err != nil {
+ if err := os.Symlink(dirlink, linklink); err != nil {
t.Fatal(err)
}
testSymlinkStats(t, linklink, true)
@@ -218,30 +210,22 @@ func TestDirAndSymlinkStats(t *testing.T) {
func TestFileAndSymlinkStats(t *testing.T) {
testenv.MustHaveSymlink(t)
- tmpdir, err := os.MkdirTemp("", "TestFileAndSymlinkStats")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tmpdir)
-
+ tmpdir := t.TempDir()
file := filepath.Join(tmpdir, "file")
- err = os.WriteFile(file, []byte(""), 0644)
- if err != nil {
+ if err := os.WriteFile(file, []byte(""), 0644); err != nil {
t.Fatal(err)
}
testFileStats(t, file)
filelink := filepath.Join(tmpdir, "link")
- err = os.Symlink(file, filelink)
- if err != nil {
+ if err := os.Symlink(file, filelink); err != nil {
t.Fatal(err)
}
testSymlinkStats(t, filelink, false)
testSymlinkSameFile(t, file, filelink)
linklink := filepath.Join(tmpdir, "linklink")
- err = os.Symlink(filelink, linklink)
- if err != nil {
+ if err := os.Symlink(filelink, linklink); err != nil {
t.Fatal(err)
}
testSymlinkStats(t, linklink, false)
@@ -252,20 +236,13 @@ func TestFileAndSymlinkStats(t *testing.T) {
func TestSymlinkWithTrailingSlash(t *testing.T) {
testenv.MustHaveSymlink(t)
- tmpdir, err := os.MkdirTemp("", "TestSymlinkWithTrailingSlash")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tmpdir)
-
+ tmpdir := t.TempDir()
dir := filepath.Join(tmpdir, "dir")
- err = os.Mkdir(dir, 0777)
- if err != nil {
+ if err := os.Mkdir(dir, 0777); err != nil {
t.Fatal(err)
}
dirlink := filepath.Join(tmpdir, "link")
- err = os.Symlink(dir, dirlink)
- if err != nil {
+ if err := os.Symlink(dir, dirlink); err != nil {
t.Fatal(err)
}
dirlinkWithSlash := dirlink + string(os.PathSeparator)
diff --git a/libgo/go/os/stat_unix.go b/libgo/go/os/stat_unix.go
index 7873bf9..6ae26ad 100644
--- a/libgo/go/os/stat_unix.go
+++ b/libgo/go/os/stat_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package os
diff --git a/libgo/go/os/sticky_bsd.go b/libgo/go/os/sticky_bsd.go
index c09b1ac..ab23d81 100644
--- a/libgo/go/os/sticky_bsd.go
+++ b/libgo/go/os/sticky_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd js,wasm netbsd openbsd solaris
package os
diff --git a/libgo/go/os/sticky_notbsd.go b/libgo/go/os/sticky_notbsd.go
index c158506..9979b43 100644
--- a/libgo/go/os/sticky_notbsd.go
+++ b/libgo/go/os/sticky_notbsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !aix && !darwin && !dragonfly && !freebsd && (!js || !wasm) && !netbsd && !openbsd && !solaris
// +build !aix
// +build !darwin
// +build !dragonfly
diff --git a/libgo/go/os/str.go b/libgo/go/os/str.go
index cba9fa3..35643e0 100644
--- a/libgo/go/os/str.go
+++ b/libgo/go/os/str.go
@@ -6,28 +6,34 @@
package os
-// Convert integer to decimal string
-func itoa(val int) string {
+// itox converts val (an int) to a hexdecimal string.
+func itox(val int) string {
if val < 0 {
- return "-" + uitoa(uint(-val))
+ return "-" + uitox(uint(-val))
}
- return uitoa(uint(val))
+ return uitox(uint(val))
}
-// Convert unsigned integer to decimal string
-func uitoa(val uint) string {
+const hex = "0123456789abcdef"
+
+// uitox converts val (a uint) to a hexdecimal string.
+func uitox(val uint) string {
if val == 0 { // avoid string allocation
- return "0"
+ return "0x0"
}
- var buf [20]byte // big enough for 64bit value base 10
+ var buf [20]byte // big enough for 64bit value base 16 + 0x
i := len(buf) - 1
- for val >= 10 {
- q := val / 10
- buf[i] = byte('0' + val - q*10)
+ for val >= 16 {
+ q := val / 16
+ buf[i] = hex[val%16]
i--
val = q
}
- // val < 10
- buf[i] = byte('0' + val)
+ // val < 16
+ buf[i] = hex[val%16]
+ i--
+ buf[i] = 'x'
+ i--
+ buf[i] = '0'
return string(buf[i:])
}
diff --git a/libgo/go/os/sys_bsd.go b/libgo/go/os/sys_bsd.go
index b1698f5..1e245eb 100644
--- a/libgo/go/os/sys_bsd.go
+++ b/libgo/go/os/sys_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd
// +build darwin dragonfly freebsd js,wasm netbsd openbsd
package os
diff --git a/libgo/go/os/sys_js.go b/libgo/go/os/sys_js.go
index e860654..4d6a64e 100644
--- a/libgo/go/os/sys_js.go
+++ b/libgo/go/os/sys_js.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build js && wasm
// +build js,wasm
package os
diff --git a/libgo/go/os/sys_unix.go b/libgo/go/os/sys_unix.go
index 37b5a47..aab683e 100644
--- a/libgo/go/os/sys_unix.go
+++ b/libgo/go/os/sys_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package os
diff --git a/libgo/go/os/tempfile.go b/libgo/go/os/tempfile.go
index 1ad44f1..5b681fc 100644
--- a/libgo/go/os/tempfile.go
+++ b/libgo/go/os/tempfile.go
@@ -4,7 +4,10 @@
package os
-import "errors"
+import (
+ "errors"
+ "internal/itoa"
+)
// fastrand provided by runtime.
// We generate random temporary file names so that there's a good
@@ -13,7 +16,7 @@ import "errors"
func fastrand() uint32
func nextRandom() string {
- return uitoa(uint(fastrand()))
+ return itoa.Uitoa(uint(fastrand()))
}
// CreateTemp creates a new temporary file in the directory dir,
diff --git a/libgo/go/os/timeout_test.go b/libgo/go/os/timeout_test.go
index 0a39f46..6d65e42 100644
--- a/libgo/go/os/timeout_test.go
+++ b/libgo/go/os/timeout_test.go
@@ -2,9 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !js
-// +build !plan9
-// +build !windows
+//go:build !js && !plan9 && !windows
+// +build !js,!plan9,!windows
package os_test
diff --git a/libgo/go/os/types_unix.go b/libgo/go/os/types_unix.go
index c0259ae..e9b8b8b 100644
--- a/libgo/go/os/types_unix.go
+++ b/libgo/go/os/types_unix.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !windows
-// +build !plan9
+//go:build !windows && !plan9
+// +build !windows,!plan9
package os
diff --git a/libgo/go/os/user/cgo_lookup_unix.go b/libgo/go/os/user/cgo_lookup_unix.go
index eb6ab50..3f4014c 100644
--- a/libgo/go/os/user/cgo_lookup_unix.go
+++ b/libgo/go/os/user/cgo_lookup_unix.go
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (aix || darwin || dragonfly || freebsd || hurd || (!android && linux) || netbsd || openbsd || solaris) && cgo && !osusergo
// +build aix darwin dragonfly freebsd hurd !android,linux netbsd openbsd solaris
-// +build cgo,!osusergo
+// +build cgo
+// +build !osusergo
package user
diff --git a/libgo/go/os/user/cgo_unix_test.go b/libgo/go/os/user/cgo_unix_test.go
index 1d341aa..9ec32b3 100644
--- a/libgo/go/os/user/cgo_unix_test.go
+++ b/libgo/go/os/user/cgo_unix_test.go
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (darwin || dragonfly || freebsd || (!android && linux) || netbsd || openbsd || solaris) && cgo && !osusergo
// +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris
-// +build cgo,!osusergo
+// +build cgo
+// +build !osusergo
package user
diff --git a/libgo/go/os/user/listgroups_aix.go b/libgo/go/os/user/listgroups_aix.go
index 5b9f3f9..93feb80 100644
--- a/libgo/go/os/user/listgroups_aix.go
+++ b/libgo/go/os/user/listgroups_aix.go
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build cgo && !osusergo
+// +build cgo,!osusergo
+
package user
import "fmt"
diff --git a/libgo/go/os/user/listgroups_solaris.go b/libgo/go/os/user/listgroups_illumos.go
index f3cbf6c..d25e033 100644
--- a/libgo/go/os/user/listgroups_solaris.go
+++ b/libgo/go/os/user/listgroups_illumos.go
@@ -1,11 +1,12 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright 2021 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 cgo && !osusergo
// +build cgo,!osusergo
// Even though this file requires no C, it is used to provide a
-// listGroup stub because all the other Solaris calls work. Otherwise,
+// listGroup stub because all the other illumos calls work. Otherwise,
// this stub will conflict with the lookup_stubs.go fallback.
package user
@@ -13,5 +14,5 @@ package user
import "fmt"
func listGroups(u *User) ([]string, error) {
- return nil, fmt.Errorf("user: list groups for %s: not supported on Solaris", u.Username)
+ return nil, fmt.Errorf("user: list groups for %s: not supported on illumos", u.Username)
}
diff --git a/libgo/go/os/user/listgroups_unix.go b/libgo/go/os/user/listgroups_unix.go
index af04c05..38bf807 100644
--- a/libgo/go/os/user/listgroups_unix.go
+++ b/libgo/go/os/user/listgroups_unix.go
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build dragonfly darwin freebsd hurd !android,linux netbsd openbsd
-// +build cgo,!osusergo
+//go:build (dragonfly || darwin || freebsd || hurd || (!android && linux) || netbsd || openbsd || (solaris && !illumos)) && cgo && !osusergo
+// +build dragonfly darwin freebsd hurd !android,linux netbsd openbsd solaris,!illumos
+// +build cgo
+// +build !osusergo
package user
diff --git a/libgo/go/os/user/lookup_android.go b/libgo/go/os/user/lookup_android.go
index 8ca30b8..151aab4 100644
--- a/libgo/go/os/user/lookup_android.go
+++ b/libgo/go/os/user/lookup_android.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build android
// +build android
package user
diff --git a/libgo/go/os/user/lookup_stubs.go b/libgo/go/os/user/lookup_stubs.go
index 178d814..c975a11 100644
--- a/libgo/go/os/user/lookup_stubs.go
+++ b/libgo/go/os/user/lookup_stubs.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (!cgo && !windows && !plan9) || android || (osusergo && !windows && !plan9)
// +build !cgo,!windows,!plan9 android osusergo,!windows,!plan9
package user
diff --git a/libgo/go/os/user/lookup_unix.go b/libgo/go/os/user/lookup_unix.go
index 0f5e82d..28b9634 100644
--- a/libgo/go/os/user/lookup_unix.go
+++ b/libgo/go/os/user/lookup_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || (!android && linux) || netbsd || openbsd || solaris) && (!cgo || osusergo)
// +build aix darwin dragonfly freebsd hurd js,wasm !android,linux netbsd openbsd solaris
// +build !cgo osusergo
@@ -32,23 +33,72 @@ type lineFunc func(line []byte) (v interface{}, err error)
// readColonFile parses r as an /etc/group or /etc/passwd style file, running
// fn for each row. readColonFile returns a value, an error, or (nil, nil) if
// the end of the file is reached without a match.
-func readColonFile(r io.Reader, fn lineFunc) (v interface{}, err error) {
- bs := bufio.NewScanner(r)
- for bs.Scan() {
- line := bs.Bytes()
+//
+// readCols is the minimum number of colon-separated fields that will be passed
+// to fn; in a long line additional fields may be silently discarded.
+func readColonFile(r io.Reader, fn lineFunc, readCols int) (v interface{}, err error) {
+ rd := bufio.NewReader(r)
+
+ // Read the file line-by-line.
+ for {
+ var isPrefix bool
+ var wholeLine []byte
+
+ // Read the next line. We do so in chunks (as much as reader's
+ // buffer is able to keep), check if we read enough columns
+ // already on each step and store final result in wholeLine.
+ for {
+ var line []byte
+ line, isPrefix, err = rd.ReadLine()
+
+ if err != nil {
+ // We should return (nil, nil) if EOF is reached
+ // without a match.
+ if err == io.EOF {
+ err = nil
+ }
+ return nil, err
+ }
+
+ // Simple common case: line is short enough to fit in a
+ // single reader's buffer.
+ if !isPrefix && len(wholeLine) == 0 {
+ wholeLine = line
+ break
+ }
+
+ wholeLine = append(wholeLine, line...)
+
+ // Check if we read the whole line (or enough columns)
+ // already.
+ if !isPrefix || bytes.Count(wholeLine, []byte{':'}) >= readCols {
+ break
+ }
+ }
+
// There's no spec for /etc/passwd or /etc/group, but we try to follow
// the same rules as the glibc parser, which allows comments and blank
// space at the beginning of a line.
- line = bytes.TrimSpace(line)
- if len(line) == 0 || line[0] == '#' {
+ wholeLine = bytes.TrimSpace(wholeLine)
+ if len(wholeLine) == 0 || wholeLine[0] == '#' {
continue
}
- v, err = fn(line)
+ v, err = fn(wholeLine)
if v != nil || err != nil {
return
}
+
+ // If necessary, skip the rest of the line
+ for ; isPrefix; _, isPrefix, err = rd.ReadLine() {
+ if err != nil {
+ // We should return (nil, nil) if EOF is reached without a match.
+ if err == io.EOF {
+ err = nil
+ }
+ return nil, err
+ }
+ }
}
- return nil, bs.Err()
}
func matchGroupIndexValue(value string, idx int) lineFunc {
@@ -79,7 +129,7 @@ func matchGroupIndexValue(value string, idx int) lineFunc {
}
func findGroupId(id string, r io.Reader) (*Group, error) {
- if v, err := readColonFile(r, matchGroupIndexValue(id, 2)); err != nil {
+ if v, err := readColonFile(r, matchGroupIndexValue(id, 2), 3); err != nil {
return nil, err
} else if v != nil {
return v.(*Group), nil
@@ -88,7 +138,7 @@ func findGroupId(id string, r io.Reader) (*Group, error) {
}
func findGroupName(name string, r io.Reader) (*Group, error) {
- if v, err := readColonFile(r, matchGroupIndexValue(name, 0)); err != nil {
+ if v, err := readColonFile(r, matchGroupIndexValue(name, 0), 3); err != nil {
return nil, err
} else if v != nil {
return v.(*Group), nil
@@ -143,7 +193,7 @@ func findUserId(uid string, r io.Reader) (*User, error) {
if e != nil {
return nil, errors.New("user: invalid userid " + uid)
}
- if v, err := readColonFile(r, matchUserIndexValue(uid, 2)); err != nil {
+ if v, err := readColonFile(r, matchUserIndexValue(uid, 2), 6); err != nil {
return nil, err
} else if v != nil {
return v.(*User), nil
@@ -152,7 +202,7 @@ func findUserId(uid string, r io.Reader) (*User, error) {
}
func findUsername(name string, r io.Reader) (*User, error) {
- if v, err := readColonFile(r, matchUserIndexValue(name, 0)); err != nil {
+ if v, err := readColonFile(r, matchUserIndexValue(name, 0), 6); err != nil {
return nil, err
} else if v != nil {
return v.(*User), nil
diff --git a/libgo/go/os/user/lookup_unix_test.go b/libgo/go/os/user/lookup_unix_test.go
index 72d3b47..060cfe1 100644
--- a/libgo/go/os/user/lookup_unix_test.go
+++ b/libgo/go/os/user/lookup_unix_test.go
@@ -2,18 +2,20 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (aix || darwin || dragonfly || freebsd || (!android && linux) || netbsd || openbsd || solaris) && !cgo
// +build aix darwin dragonfly freebsd !android,linux netbsd openbsd solaris
// +build !cgo
package user
import (
+ "fmt"
"reflect"
"strings"
"testing"
)
-const testGroupFile = `# See the opendirectoryd(8) man page for additional
+var testGroupFile = `# See the opendirectoryd(8) man page for additional
# information about Open Directory.
##
nobody:*:-2:
@@ -29,7 +31,7 @@ daemon:*:1:root
# comment:*:4:found
# comment:*:4:found
kmem:*:2:root
-`
+` + largeGroup()
var groupTests = []struct {
in string
@@ -48,9 +50,20 @@ var groupTests = []struct {
{testGroupFile, "invalidgid", ""},
{testGroupFile, "indented", "7"},
{testGroupFile, "# comment", ""},
+ {testGroupFile, "largegroup", "1000"},
{"", "emptyfile", ""},
}
+// Generate a proper "largegroup" entry for testGroupFile string
+func largeGroup() (res string) {
+ var b strings.Builder
+ b.WriteString("largegroup:x:1000:user1")
+ for i := 2; i <= 7500; i++ {
+ fmt.Fprintf(&b, ",user%d", i)
+ }
+ return b.String()
+}
+
func TestFindGroupName(t *testing.T) {
for _, tt := range groupTests {
got, err := findGroupName(tt.name, strings.NewReader(tt.in))
diff --git a/libgo/go/os/user/user_test.go b/libgo/go/os/user/user_test.go
index 8c4c817..4992031 100644
--- a/libgo/go/os/user/user_test.go
+++ b/libgo/go/os/user/user_test.go
@@ -132,7 +132,7 @@ func TestGroupIds(t *testing.T) {
if runtime.GOOS == "aix" {
t.Skip("skipping GroupIds, see golang.org/issue/30563")
}
- if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+ if runtime.GOOS == "illumos" {
t.Skip("skipping GroupIds, see golang.org/issue/14709")
}
user, err := Current()
diff --git a/libgo/go/os/wait_unimp.go b/libgo/go/os/wait_unimp.go
index cb875ab..783a66f 100644
--- a/libgo/go/os/wait_unimp.go
+++ b/libgo/go/os/wait_unimp.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly hurd js,wasm netbsd openbsd solaris
+//go:build aix || darwin || hurd || (js && wasm) || openbsd || solaris
+// +build aix darwin hurd js,wasm openbsd solaris
package os
diff --git a/libgo/go/os/wait_wait6.go b/libgo/go/os/wait_wait6.go
index 5420b2d..45b370a 100644
--- a/libgo/go/os/wait_wait6.go
+++ b/libgo/go/os/wait_wait6.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build freebsd
+//go:build dragonfly || freebsd || netbsd
+// +build dragonfly freebsd netbsd
package os
@@ -22,9 +23,9 @@ func (p *Process) blockUntilWaitable() (bool, error) {
// The arguments on 32-bit FreeBSD look like the following:
// - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or
// - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC
- if runtime.GOARCH == "386" {
+ if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0)
- } else if runtime.GOARCH == "arm" {
+ } else if runtime.GOOS == "freebsd" && runtime.GOARCH == "arm" {
_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0)
} else {
_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0)
@@ -34,7 +35,9 @@ func (p *Process) blockUntilWaitable() (bool, error) {
}
}
runtime.KeepAlive(p)
- if errno != 0 {
+ if errno == syscall.ENOSYS {
+ return false, nil
+ } else if errno != 0 {
return false, NewSyscallError("wait6", errno)
}
return true, nil
diff --git a/libgo/go/os/wait_waitid.go b/libgo/go/os/wait_waitid.go
index 2c39f9b..d7c9751 100644
--- a/libgo/go/os/wait_waitid.go
+++ b/libgo/go/os/wait_waitid.go
@@ -5,6 +5,7 @@
// We used to used this code for Darwin, but according to issue #19314
// waitid returns if the process is stopped, even when using WEXITED.
+//go:build linux
// +build linux
package os
@@ -22,7 +23,7 @@ const _P_PID = 1
// It does not actually call p.Wait.
func (p *Process) blockUntilWaitable() (bool, error) {
// The waitid system call expects a pointer to a siginfo_t,
- // which is 128 bytes on all GNU/Linux systems.
+ // which is 128 bytes on all Linux systems.
// On darwin/amd64, it requires 104 bytes.
// We don't care about the values it returns.
var siginfo [16]uint64