From 5a7920ba602ef68d3413d7adbe7b23a145e1765d Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 25 May 2025 00:33:23 +0100 Subject: [PATCH] ext/sockets: socket_shutdown() having proper constants for mode. close GH-18648 --- NEWS | 2 ++ UPGRADING | 3 +++ ext/sockets/sockets.c | 5 +++++ ext/sockets/sockets.stub.php | 19 +++++++++++++++++++ ext/sockets/sockets_arginfo.h | 11 ++++++++++- ext/sockets/tests/socket_shutdown.phpt | 18 +++++++++++------- 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 966fbf97a1c..557fe0aea7f 100644 --- a/NEWS +++ b/NEWS @@ -214,6 +214,8 @@ PHP NEWS . Added SO_BUSY_POOL to reduce packets poll latency. (David Carlier) - Added UDP_SEGMENT support to optimise multiple large datagrams over UDP if the kernel and hardware supports it. (David Carlier) + - Added SHUT_RD, SHUT_WR and SHUT_RDWR constants for socket_shutdown(). + (David Carlier) - Sodium: . Fix overall theorical overflows on zend_string buffer allocations. diff --git a/UPGRADING b/UPGRADING index 2ecd8a5a4f9..a6aca3a7c4f 100644 --- a/UPGRADING +++ b/UPGRADING @@ -452,6 +452,9 @@ PHP 8.5 UPGRADE NOTES . IP_BINDANY (FreeBSD/NetBSD/OpenBSD only). . SO_BUSY_POLL (Linux only). . UDP_SEGMENT (Linux only). + - SHUT_RD. + - SHUT_WR. + - SHUT_RDWR. ======================================== 11. Changes to INI File Handling diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index e3d5dc6c296..2a5a5e975f4 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -2434,6 +2434,11 @@ PHP_FUNCTION(socket_shutdown) php_sock = Z_SOCKET_P(arg1); ENSURE_SOCKET_VALID(php_sock); + if (how_shutdown < SHUT_RD || how_shutdown > SHUT_RDWR) { + zend_argument_value_error(2, "must be one of SHUT_RD, SHUT_WR or SHUT_RDWR"); + RETURN_THROWS(); + } + if (shutdown(php_sock->bsd_socket, how_shutdown) != 0) { PHP_SOCKET_ERROR(php_sock, "Unable to shutdown socket", errno); RETURN_FALSE; diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index d94352e3628..6050a894145 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -2030,6 +2030,25 @@ const ETH_P_ALL = UNKNOWN; const UDP_SEGMENT = UNKNOWN; #endif +#ifdef SHUT_RDWR +/** + * @var int + * @cvalue SHUT_RD + */ +const SHUT_RD = UNKNOWN; +/** +/** + * @var int + * @cvalue SHUT_WR + */ +const SHUT_WR = UNKNOWN; +/** + * @var int + * @cvalue SHUT_RDWR + */ +const SHUT_RDWR = UNKNOWN; +#endif + /** * @strict-properties * @not-serializable diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index 78f2212a518..4be006bc7f0 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0ff66adfea41b603b9d58f1f0a82a950f4034cc4 */ + * Stub hash: 7b1baf47dce2fb08faa5616068238ea078d1609b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -1111,6 +1111,15 @@ static void register_sockets_symbols(int module_number) #if defined(UDP_SEGMENT) REGISTER_LONG_CONSTANT("UDP_SEGMENT", UDP_SEGMENT, CONST_PERSISTENT); #endif +#if defined(SHUT_RDWR) + REGISTER_LONG_CONSTANT("SHUT_RD", SHUT_RD, CONST_PERSISTENT); +#endif +#if defined(SHUT_RDWR) + REGISTER_LONG_CONSTANT("SHUT_WR", SHUT_WR, CONST_PERSISTENT); +#endif +#if defined(SHUT_RDWR) + REGISTER_LONG_CONSTANT("SHUT_RDWR", SHUT_RDWR, CONST_PERSISTENT); +#endif } static zend_class_entry *register_class_Socket(void) diff --git a/ext/sockets/tests/socket_shutdown.phpt b/ext/sockets/tests/socket_shutdown.phpt index 2e63445ada3..132e9254589 100644 --- a/ext/sockets/tests/socket_shutdown.phpt +++ b/ext/sockets/tests/socket_shutdown.phpt @@ -19,24 +19,29 @@ $port = 80; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $socketConn = socket_connect($socket, $host, $port); -var_dump(socket_shutdown($socket,0)); +var_dump(socket_shutdown($socket,SHUT_RD)); socket_close($socket); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $socketConn = socket_connect($socket, $host, $port); -var_dump(socket_shutdown($socket,1)); +var_dump(socket_shutdown($socket,SHUT_WR)); socket_close($socket); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $socketConn = socket_connect($socket, $host, $port); -var_dump(socket_shutdown($socket,2)); +var_dump(socket_shutdown($socket,SHUT_RDWR)); socket_close($socket); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); -var_dump(socket_shutdown($socket,0)); +var_dump(socket_shutdown($socket,SHUT_RD)); $socketConn = socket_connect($socket, $host, $port); -var_dump(socket_shutdown($socket,-1)); + +try { + socket_shutdown($socket,-1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} socket_close($socket); ?> --CLEAN-- @@ -54,5 +59,4 @@ bool(true) Warning: socket_shutdown(): Unable to shutdown socket [%d]: %s in %s on line %d bool(false) -Warning: socket_shutdown(): Unable to shutdown socket [%d]: Invalid argument in %s on line %d -bool(false) +must be one of SHUT_RD, SHUT_WR or SHUT_RDWR