Skip to content

Commit 338d43f

Browse files
committed
Fix GH-23879: Do not report AcceptFailed on non-blocking accept timeout
1 parent 931d8ea commit 338d43f

7 files changed

Lines changed: 56 additions & 5 deletions

File tree

‎NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.6.0RC3
44

5+
- Streams:
6+
. Fixed bug GH-23879 (stream_socket_accept() reports AcceptFailed when a
7+
non-blocking listener has no pending connection). (Lazizbek Ergashev)
58

69
24 Sep 2026, PHP 8.6.0RC2
710

‎ext/openssl/xp_ssl.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3556,6 +3556,10 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
35563556
}
35573557
}
35583558
}
3559+
} else if (!sock->s.is_blocked && (xparam->outputs.error_code == PHP_TIMEOUT_ERROR_VALUE
3560+
|| PHP_IS_TRANSIENT_ERROR(xparam->outputs.error_code))) {
3561+
/* No pending connection is not an error for a non-blocking listener. */
3562+
return 0;
35593563
}
35603564

35613565
return xparam->outputs.client == NULL ? -1 : 0;

‎ext/standard/streamsfuncs.c‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,13 @@ PHP_FUNCTION(stream_socket_accept)
314314

315315
php_stream_error_operation_begin();
316316

317-
if (0 == php_stream_xport_accept(stream, &clistream,
317+
int ret = php_stream_xport_accept(stream, &clistream,
318318
zpeername ? &peername : NULL,
319319
NULL, NULL,
320320
tv_pointer, &errstr
321-
) && clistream) {
321+
);
322+
323+
if (0 == ret && clistream) {
322324

323325
if (peername) {
324326
ZEND_TRY_ASSIGN_REF_STR(zpeername, peername);
@@ -328,7 +330,9 @@ PHP_FUNCTION(stream_socket_accept)
328330
if (peername) {
329331
zend_string_release(peername);
330332
}
331-
php_stream_warn(stream, AcceptFailed, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error");
333+
if (0 != ret) {
334+
php_stream_warn(stream, AcceptFailed, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error");
335+
}
332336
RETVAL_FALSE;
333337
}
334338

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
GH-23879 (stream_socket_accept() reports AcceptFailed when a non-blocking listener has no pending connection)
3+
--FILE--
4+
<?php
5+
$server = stream_socket_server(
6+
'tcp://127.0.0.1:0',
7+
context: stream_context_create([
8+
'stream' => [
9+
'error_mode' => StreamErrorMode::Exception,
10+
'error_store' => StreamErrorStore::All,
11+
],
12+
]),
13+
);
14+
stream_set_blocking($server, false);
15+
16+
var_dump(stream_socket_accept($server, 0));
17+
var_dump(stream_last_errors());
18+
19+
$client = stream_socket_client('tcp://' . stream_socket_get_name($server, false));
20+
var_dump(is_resource(stream_socket_accept($server, 1)));
21+
var_dump(stream_socket_accept($server, 0));
22+
23+
stream_set_blocking($server, true);
24+
try {
25+
stream_socket_accept($server, 0);
26+
} catch (StreamException $e) {
27+
var_dump($e->getErrors()[0]->code);
28+
}
29+
?>
30+
--EXPECT--
31+
bool(false)
32+
array(0) {
33+
}
34+
bool(true)
35+
bool(false)
36+
enum(StreamErrorCode::AcceptFailed)

‎main/network.c‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
# include "win32/time.h"
7070
# define SOCK_ERR INVALID_SOCKET
7171
# define SOCK_CONN_ERR SOCKET_ERROR
72-
# define PHP_TIMEOUT_ERROR_VALUE WSAETIMEDOUT
7372

7473
#ifdef HAVE_IPV6
7574
const struct in6_addr in6addr_any = {0}; /* IN6ADDR_ANY_INIT; */
@@ -78,7 +77,6 @@ const struct in6_addr in6addr_any = {0}; /* IN6ADDR_ANY_INIT; */
7877
#else
7978
# define SOCK_ERR -1
8079
# define SOCK_CONN_ERR -1
81-
# define PHP_TIMEOUT_ERROR_VALUE ETIMEDOUT
8280
#endif
8381

8482
#ifdef HAVE_GETADDRINFO

‎main/php_network.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ typedef int php_socket_t;
109109
# define SOCK_ERR INVALID_SOCKET
110110
# define SOCK_CONN_ERR SOCKET_ERROR
111111
# define SOCK_RECV_ERR SOCKET_ERROR
112+
# define PHP_TIMEOUT_ERROR_VALUE WSAETIMEDOUT
112113
#else
113114
# define SOCK_ERR -1
114115
# define SOCK_CONN_ERR -1
115116
# define SOCK_RECV_ERR -1
117+
# define PHP_TIMEOUT_ERROR_VALUE ETIMEDOUT
116118
#endif
117119

118120
#define STREAM_SOCKOP_NONE (1 << 0)

‎main/streams/xp_socket.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,10 @@ static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t
10861086
GC_ADDREF(stream->ctx);
10871087
}
10881088
}
1089+
} else if (!sock->is_blocked && (xparam->outputs.error_code == PHP_TIMEOUT_ERROR_VALUE
1090+
|| PHP_IS_TRANSIENT_ERROR(xparam->outputs.error_code))) {
1091+
/* No pending connection is not an error for a non-blocking listener. */
1092+
return 0;
10891093
}
10901094

10911095
return xparam->outputs.client == NULL ? -1 : 0;

0 commit comments

Comments
 (0)