Skip to content

Commit d052d61

Browse files
committed
ext/sockets: adding SOCK_CLOEXEC/SOCK_NONBLOCK options.
targetted for socket_create_pair/socket_create, they re not considered as socket type but to be ORed with these (to avoid socketpair2/socket2 likely), set O_CLOEXEC/O_NONBLOCK respectively on the file descriptors. close GH-15322
1 parent afc5738 commit d052d61

7 files changed

+85
-8
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ PHP NEWS
7676
- Sockets:
7777
. Added IP_PORTRANGE* constants for BSD systems to control ephemeral port
7878
ranges. (David Carlier)
79+
. Added SOCK_NONBLOCK/SOCK_CLOEXEC constants for socket_create and
80+
socket_create_pair to apply O_NONBLOCK/O_CLOEXEC flags to the
81+
newly created sockets. (David Carlier)
7982

8083
- SPL:
8184
. The SplFixedArray::__wakeup() method has been deprecated as it implements

UPGRADING

+2
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,8 @@ PHP 8.4 UPGRADE NOTES
962962
. IP_PORTRANGE_DEFAULT (FreeBSD/NetBSD/OpenBSD only).
963963
. IP_PORTRANGE_HIGH (FreeBSD/NetBSD/OpenBSD only).
964964
. IP_PORTRANGE_LOW (FreeBSD/NetBSD/OpenBSD only).
965+
. SOCK_NONBLOCK.
966+
. SOCK_CLOEXEC.
965967

966968
- Sodium:
967969
. SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES

ext/sockets/sockets.c

+24-6
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,7 @@ PHP_FUNCTION(socket_getpeername)
10961096
/* {{{ Creates an endpoint for communication in the domain specified by domain, of type specified by type */
10971097
PHP_FUNCTION(socket_create)
10981098
{
1099-
zend_long domain, type, protocol;
1099+
zend_long domain, type, checktype, protocol;
11001100
php_socket *php_sock;
11011101

11021102
ZEND_PARSE_PARAMETERS_START(3, 3)
@@ -1114,9 +1114,18 @@ PHP_FUNCTION(socket_create)
11141114
RETURN_THROWS();
11151115
}
11161116

1117-
if (type > 10) {
1117+
checktype = type;
1118+
#ifdef SOCK_NONBLOCK
1119+
checktype &= ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1120+
#endif
1121+
1122+
if (checktype > 10) {
11181123
zend_argument_value_error(2, "must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET,"
1119-
" SOCK_RAW, or SOCK_RDM");
1124+
" SOCK_RAW, or SOCK_RDM"
1125+
#ifdef SOCK_NONBLOCK
1126+
" optionally OR'ed with SOCK_CLOEXEC, SOCK_NONBLOCK"
1127+
#endif
1128+
);
11201129
RETURN_THROWS();
11211130
}
11221131

@@ -2071,7 +2080,7 @@ PHP_FUNCTION(socket_create_pair)
20712080
zval retval[2], *fds_array_zval;
20722081
php_socket *php_sock[2];
20732082
PHP_SOCKET fds_array[2];
2074-
zend_long domain, type, protocol;
2083+
zend_long domain, type, checktype, protocol;
20752084

20762085
ZEND_PARSE_PARAMETERS_START(4, 4)
20772086
Z_PARAM_LONG(domain)
@@ -2089,9 +2098,18 @@ PHP_FUNCTION(socket_create_pair)
20892098
RETURN_THROWS();
20902099
}
20912100

2092-
if (type > 10) {
2101+
checktype = type;
2102+
#ifdef SOCK_NONBLOCK
2103+
checktype &= ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
2104+
#endif
2105+
2106+
if (checktype > 10) {
20932107
zend_argument_value_error(2, "must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET,"
2094-
" SOCK_RAW, or SOCK_RDM");
2108+
" SOCK_RAW, or SOCK_RDM"
2109+
#ifdef SOCK_NONBLOCK
2110+
" optionally OR'ed with SOCK_CLOEXEC, SOCK_NONBLOCK"
2111+
#endif
2112+
);
20952113
RETURN_THROWS();
20962114
}
20972115

ext/sockets/sockets.stub.php

+14
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,20 @@
6868
*/
6969
const SOCK_DCCP = UNKNOWN;
7070
#endif
71+
#ifdef SOCK_CLOEXEC
72+
/**
73+
* @var int
74+
* @cvalue SOCK_CLOEXEC
75+
*/
76+
const SOCK_CLOEXEC = UNKNOWN;
77+
#endif
78+
#ifdef SOCK_NONBLOCK
79+
/**
80+
* @var int
81+
* @cvalue SOCK_NONBLOCK
82+
*/
83+
const SOCK_NONBLOCK = UNKNOWN;
84+
#endif
7185

7286
/**
7387
* @var int

ext/sockets/sockets_arginfo.h

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/sockets/tests/socket_create_pair-wrongparams.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ try {
3030
Warning: socket_create_pair(): Unable to create socket pair [%d]: %s not supported in %s on line %d
3131
bool(false)
3232
socket_create_pair(): Argument #1 ($domain) must be one of AF_UNIX, AF_INET6, or AF_INET
33-
socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM
33+
socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A
3434
--CREDITS--
3535
Till Klampaeckel, [email protected]
3636
Berlin TestFest 2009
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Test for socket_create_pair() with SOCK_CLOEXEC/SOCK_NONBLOCK
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
if (!defined('SOCK_CLOEXEC')) die("skip SOCK_CLOEXEC");
8+
if (!defined('SOCK_NONBLOCK')) die("skip SOCK_NONBLOCK");
9+
?>
10+
--FILE--
11+
<?php
12+
$sockets = array();
13+
try {
14+
socket_create_pair(AF_UNIX, 11 | SOCK_CLOEXEC, 0, $sockets);
15+
} catch (\ValueError $e) {
16+
echo $e->getMessage() . PHP_EOL;
17+
}
18+
try {
19+
socket_create_pair(AF_UNIX, 11 | SOCK_NONBLOCK, 0, $sockets);
20+
} catch (\ValueError $e) {
21+
echo $e->getMessage() . PHP_EOL;
22+
}
23+
try {
24+
socket_create_pair(AF_UNIX, 11 | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, $sockets);
25+
} catch (\ValueError $e) {
26+
echo $e->getMessage() . PHP_EOL;
27+
}
28+
var_dump(socket_create_pair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, $sockets));
29+
?>
30+
--EXPECTF--
31+
socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A
32+
socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A
33+
socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A
34+
bool(true)

0 commit comments

Comments
 (0)