test: retry raw socket reads interrupted by EINTR
- commit
- cdc6474b9ccffe66a243f538aa4d01c084ba6700
- author
- brice · · 2026-09-26 16:40 UTC
- parent
- a4a3f87
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +15 -2
M internal/adapters/wayland/clipboard_test.go +9 -1
| @@ -1,6 +1,7 @@ | |||
| 1 | 1 | package wayland | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | + | "errors" | |
| 4 | 5 | "testing" | |
| 5 | 6 | "time" | |
| 6 | 7 | ||
| @@ -180,7 +181,14 @@ func TestClipboardFollowsFocus(t *testing.T) { | |||
| 180 | 181 | } | |
| 181 | 182 | } | |
| 182 | 183 | buf := make([]byte, 16) | |
| 183 | - | n, _ := unix.Read(fds[0], buf) | |
| 184 | + | // Go runtime signals (preemption) can interrupt the raw read: retry. | |
| 185 | + | n, err := unix.Read(fds[0], buf) | |
| 186 | + | for errors.Is(err, unix.EINTR) { | |
| 187 | + | n, err = unix.Read(fds[0], buf) | |
| 188 | + | } | |
| 189 | + | if err != nil { | |
| 190 | + | t.Fatal(err) | |
| 191 | + | } | |
| 184 | 192 | if string(buf[:n]) != "pasted" { | |
| 185 | 193 | t.Fatalf("pasted %q", buf[:n]) | |
| 186 | 194 | } | |
| @@ -1,6 +1,7 @@ | |||||
| 1 | package wayland | 1 | package wayland | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | + | "errors" | |||
| 4 | "testing" | 5 | "testing" | ||
| 5 | "time" | 6 | "time" | ||
| 6 | 7 | ||||
| @@ -180,7 +181,14 @@ func TestClipboardFollowsFocus(t *testing.T) { | |||||
| 180 | } | 181 | } | ||
| 181 | } | 182 | } | ||
| 182 | buf := make([]byte, 16) | 183 | buf := make([]byte, 16) | ||
| 183 | - | n, _ := unix.Read(fds[0], buf) | 184 | + | // Go runtime signals (preemption) can interrupt the raw read: retry. |
| 185 | + | n, err := unix.Read(fds[0], buf) | |||
| 186 | + | for errors.Is(err, unix.EINTR) { | |||
| 187 | + | n, err = unix.Read(fds[0], buf) | |||
| 188 | + | } | |||
| 189 | + | if err != nil { | |||
| 190 | + | t.Fatal(err) | |||
| 191 | + | } | |||
| 184 | if string(buf[:n]) != "pasted" { | 192 | if string(buf[:n]) != "pasted" { | ||
| 185 | t.Fatalf("pasted %q", buf[:n]) | 193 | t.Fatalf("pasted %q", buf[:n]) | ||
| 186 | } | 194 | } | ||
M internal/adapters/xwayland/xwayland_test.go +6 -1
| @@ -80,7 +80,12 @@ func TestRunDropsClientsOfFailedSatellite(t *testing.T) { | |||
| 80 | 80 | if err := unix.SetsockoptTimeval(fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &unix.Timeval{Sec: 3}); err != nil { | |
| 81 | 81 | t.Fatal(err) | |
| 82 | 82 | } | |
| 83 | - | if n, err := unix.Read(fd, make([]byte, 1)); n != 0 || err != nil { | |
| 83 | + | // Go runtime signals (preemption) can interrupt the raw read: retry. | |
| 84 | + | n, err := unix.Read(fd, make([]byte, 1)) | |
| 85 | + | for errors.Is(err, unix.EINTR) { | |
| 86 | + | n, err = unix.Read(fd, make([]byte, 1)) | |
| 87 | + | } | |
| 88 | + | if n != 0 || err != nil { | |
| 84 | 89 | t.Fatalf("read %d %v, want EOF", n, err) | |
| 85 | 90 | } | |
| 86 | 91 | cancel() | |
| @@ -80,7 +80,12 @@ func TestRunDropsClientsOfFailedSatellite(t *testing.T) { | |||||
| 80 | if err := unix.SetsockoptTimeval(fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &unix.Timeval{Sec: 3}); err != nil { | 80 | if err := unix.SetsockoptTimeval(fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &unix.Timeval{Sec: 3}); err != nil { | ||
| 81 | t.Fatal(err) | 81 | t.Fatal(err) | ||
| 82 | } | 82 | } | ||
| 83 | - | if n, err := unix.Read(fd, make([]byte, 1)); n != 0 || err != nil { | 83 | + | // Go runtime signals (preemption) can interrupt the raw read: retry. |
| 84 | + | n, err := unix.Read(fd, make([]byte, 1)) | |||
| 85 | + | for errors.Is(err, unix.EINTR) { | |||
| 86 | + | n, err = unix.Read(fd, make([]byte, 1)) | |||
| 87 | + | } | |||
| 88 | + | if n != 0 || err != nil { | |||
| 84 | t.Fatalf("read %d %v, want EOF", n, err) | 89 | t.Fatalf("read %d %v, want EOF", n, err) | ||
| 85 | } | 90 | } | ||
| 86 | cancel() | 91 | cancel() | ||