Some checks failed
Release CLI / Pre-release build (push) Has been cancelled
Release CLI / Pre-release test (macos-12) (push) Has been cancelled
Release CLI / Pre-release test (ubuntu-22.04) (push) Has been cancelled
Release CLI / Pre-release test (windows-2022) (push) Has been cancelled
Release CLI / Release (push) Has been cancelled
The PR introduces the `platform.Select()` API, wrapping `select(2)` on POSIX and emulated in some cases on Windows. RATIONALE.md contains a full explanation of the approach followed in `poll_oneoff` to handle Stdin and the other types of file descriptors, and the clock subscriptions. It also introduces an abstraction (`StdioFilePoller`) to allow the simulation of different scenarios (waiting for input, input ready, timeout expired, etc.) when unit-testing interactive input. This closes #1317. Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
32 lines
899 B
Go
32 lines
899 B
Go
package platform
|
|
|
|
import (
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// wasiFdStdin is the constant value for stdin on Wasi.
|
|
// We need this constant because on Windows os.Stdin.Fd() != 0.
|
|
const wasiFdStdin = 0
|
|
|
|
// syscall_select emulates the select syscall on Windows for two, well-known cases, returns syscall.ENOSYS for all others.
|
|
// If r contains fd 0, then it immediately returns 1 (data ready on stdin) and r will have the fd 0 bit set.
|
|
// If n==0 it will wait for the given timeout duration, but it will return syscall.ENOSYS if timeout is nil,
|
|
// i.e. it won't block indefinitely.
|
|
func syscall_select(n int, r, w, e *FdSet, timeout *time.Duration) (int, error) {
|
|
if n == 0 {
|
|
// don't block indefinitely
|
|
if timeout == nil {
|
|
return -1, syscall.ENOSYS
|
|
}
|
|
time.Sleep(*timeout)
|
|
return 0, nil
|
|
}
|
|
if r.IsSet(wasiFdStdin) {
|
|
r.Zero()
|
|
r.Set(wasiFdStdin)
|
|
return 1, nil
|
|
}
|
|
return -1, syscall.ENOSYS
|
|
}
|