os: implement Process.is_pending() on windows (fix #23990) (#23993)

This commit is contained in:
kbkpbot 2025-03-21 17:03:03 +08:00 committed by GitHub
parent 76ae040f71
commit a1304637c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 3 deletions

View file

@ -248,7 +248,7 @@ fn (mut p Process) _write_to(pkind ChildProcessPipeKind, s string) {
// _is_pending should be called only from is_pending() // _is_pending should be called only from is_pending()
fn (mut p Process) _is_pending(pkind ChildProcessPipeKind) bool { fn (mut p Process) _is_pending(pkind ChildProcessPipeKind) bool {
$if windows { $if windows {
// TODO return p.win_is_pending(int(pkind))
} $else { } $else {
return fd_is_pending(p.stdio_fd[pkind]) return fd_is_pending(p.stdio_fd[pkind])
} }

View file

@ -154,6 +154,10 @@ fn (mut p Process) win_read_string(_idx int, _maxbytes int) (string, int) {
return '', 0 return '', 0
} }
fn (mut p Process) win_is_pending(idx int) bool {
return false
}
fn (mut p Process) win_slurp(_idx int) string { fn (mut p Process) win_slurp(_idx int) string {
return '' return ''
} }

View file

@ -88,13 +88,13 @@ fn (mut p Process) win_spawn_process() int {
sa.n_length = sizeof(C.SECURITY_ATTRIBUTES) sa.n_length = sizeof(C.SECURITY_ATTRIBUTES)
sa.b_inherit_handle = true sa.b_inherit_handle = true
create_pipe_ok1 := C.CreatePipe(voidptr(&wdata.child_stdout_read), voidptr(&wdata.child_stdout_write), create_pipe_ok1 := C.CreatePipe(voidptr(&wdata.child_stdout_read), voidptr(&wdata.child_stdout_write),
voidptr(&sa), 0) voidptr(&sa), 65536)
failed_cfn_report_error(create_pipe_ok1, 'CreatePipe stdout') failed_cfn_report_error(create_pipe_ok1, 'CreatePipe stdout')
set_handle_info_ok1 := C.SetHandleInformation(wdata.child_stdout_read, C.HANDLE_FLAG_INHERIT, set_handle_info_ok1 := C.SetHandleInformation(wdata.child_stdout_read, C.HANDLE_FLAG_INHERIT,
0) 0)
failed_cfn_report_error(set_handle_info_ok1, 'SetHandleInformation') failed_cfn_report_error(set_handle_info_ok1, 'SetHandleInformation')
create_pipe_ok2 := C.CreatePipe(voidptr(&wdata.child_stderr_read), voidptr(&wdata.child_stderr_write), create_pipe_ok2 := C.CreatePipe(voidptr(&wdata.child_stderr_read), voidptr(&wdata.child_stderr_write),
voidptr(&sa), 0) voidptr(&sa), 65536)
failed_cfn_report_error(create_pipe_ok2, 'CreatePipe stderr') failed_cfn_report_error(create_pipe_ok2, 'CreatePipe stderr')
set_handle_info_ok2 := C.SetHandleInformation(wdata.child_stderr_read, C.HANDLE_FLAG_INHERIT, set_handle_info_ok2 := C.SetHandleInformation(wdata.child_stderr_read, C.HANDLE_FLAG_INHERIT,
0) 0)
@ -233,6 +233,28 @@ fn (mut p Process) win_read_string(idx int, _maxbytes int) (string, int) {
return buf[..bytes_read].bytestr(), bytes_read return buf[..bytes_read].bytestr(), bytes_read
} }
fn (mut p Process) win_is_pending(idx int) bool {
mut wdata := unsafe { &WProcess(p.wdata) }
if unsafe { wdata == 0 } {
return false
}
mut rhandle := &u32(0)
if idx == 1 {
rhandle = wdata.child_stdout_read
}
if idx == 2 {
rhandle = wdata.child_stderr_read
}
if rhandle == 0 {
return false
}
mut bytes_avail := int(0)
if C.PeekNamedPipe(rhandle, 0, 0, 0, &bytes_avail, 0) {
return bytes_avail > 0
}
return false
}
fn (mut p Process) win_slurp(idx int) string { fn (mut p Process) win_slurp(idx int) string {
mut wdata := unsafe { &WProcess(p.wdata) } mut wdata := unsafe { &WProcess(p.wdata) }
if unsafe { wdata == 0 } { if unsafe { wdata == 0 } {