Skip to content

GH-16889: stream_select() timeout useless for pipes on Windows #16917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions ext/standard/tests/streams/bug49936_win32.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,10 @@ default_socket_timeout=2

$dir = 'ftp://your:self@localhost/';

var_dump(opendir($dir));
var_dump(opendir($dir));
var_dump(@opendir($dir));
var_dump(@opendir($dir));

?>
--EXPECTF--
Warning: opendir(): connect() failed: %s in %s on line %d

Warning: opendir(ftp://...@localhost/): Failed to open directory: operation failed in %s on line %d
bool(false)

Warning: opendir(): connect() failed: %s in %s on line %d

Warning: opendir(ftp://...@localhost/): Failed to open directory: operation failed in %s on line %d
bool(false)
5 changes: 3 additions & 2 deletions ext/standard/tests/streams/bug60602.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ if (is_resource($p)) {
$data = '';

while (1) {
$r = [$pipes[1]];
$w = $e = NULL;
$n = stream_select($pipes, $w, $e, 300);
$n = stream_select($r, $w, $e, 300);

if ($n === false) {
echo "no streams \n";
Expand All @@ -29,7 +30,7 @@ if (is_resource($p)) {
proc_terminate($p, 9);
break;
} else if ($n > 0) {
$line = fread($pipes[1], 8192);
$line = fread($r[0], 8192);
if (strlen($line) == 0) {
/* EOF */
break;
Expand Down
5 changes: 3 additions & 2 deletions ext/standard/tests/streams/bug64770.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ if (is_resource($p)) {
$data = '';

while (1) {
$r = [$pipes[1]];
$w = $e = NULL;
$n = stream_select($pipes, $w, $e, 300);
$n = stream_select($r, $w, $e, 300);

if ($n === false) {
echo "no streams \n";
Expand All @@ -29,7 +30,7 @@ if (is_resource($p)) {
proc_terminate($p, 9);
break;
} else if ($n > 0) {
$line = fread($pipes[1], 8192);
$line = fread($r[0], 8192);
if (strlen($line) == 0) {
/* EOF */
break;
Expand Down
26 changes: 26 additions & 0 deletions ext/standard/tests/streams/gh16889.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
GH-16889 (stream_select() timeout useless for pipes on Windows)
--FILE--
<?php
$desc = [
["pipe", "r"],
["pipe", "w"],
["pipe", "w"],
];
// open process which won't produce output for 10s
$proc = proc_open([PHP_BINARY, "-r", "sleep(10); echo 'finish';"], $desc, $pipes);
$read = [$pipes[1]];
$write = null;
$except = null;
$time0 = microtime(true);
// select STDOUT pipe of process for 1ms
if (stream_select($read, $write, $except, 0, 1000)) {
var_dump(fread($read[0], 1));
}
// avoid blocking of finishing the test process
proc_terminate($proc);
$time1 = microtime(true);
var_dump($time1 - $time0 < 1);
?>
--EXPECT--
bool(true)
14 changes: 11 additions & 3 deletions win32/select.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* - If you supply only sockets, this simply passes through to winsock select().
* - If you supply file handles, there is no way to distinguish between
* ready for read/write or OOB, so any set in which the handle is found will
* be marked as ready.
* be marked as ready. Pipes will be checked if they are ready for read, though.
* - If you supply a mixture of handles and sockets, the system will interleave
* calls between select() and WaitForMultipleObjects(). The time slicing may
* cause this function call to take up to 100 ms longer than you specified.
Expand Down Expand Up @@ -135,15 +135,23 @@ PHPAPI int php_select(php_socket_t max_fd, fd_set *rfds, fd_set *wfds, fd_set *e
for (i = 0; i < n_handles; i++) {
if (WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) {
if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {
FD_SET((uint32_t)handle_slot_to_fd[i], &aread);
DWORD avail_read = 0;
if (GetFileType(handles[i]) != FILE_TYPE_PIPE
|| !PeekNamedPipe(handles[i], NULL, 0, NULL, &avail_read, NULL)
|| avail_read > 0
) {
FD_SET((uint32_t)handle_slot_to_fd[i], &aread);
retcode++;
}
}
if (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) {
FD_SET((uint32_t)handle_slot_to_fd[i], &awrite);
retcode++;
}
if (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) {
FD_SET((uint32_t)handle_slot_to_fd[i], &aexcept);
retcode++;
}
retcode++;
}
}
}
Expand Down
Loading