diff options
Diffstat (limited to 'ext/sockets')
72 files changed, 1814 insertions, 1677 deletions
diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 927e16ff95..4eaa217b73 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -17,7 +17,7 @@ # include <sys/ioctl.h> # include <net/if.h> #else -# include <win32/php_stdint.h> +# include <stdint.h> #endif #include <limits.h> @@ -36,16 +36,6 @@ struct _WSAMSG { WSABUF Control; //void *msg_control, size_t msg_controllen DWORD dwFlags; //int msg_flags } -struct __WSABUF { - u_long len; //size_t iov_len (2nd member) - char FAR *buf; //void *iov_base (1st member) -} -struct _WSACMSGHDR { - UINT cmsg_len; //socklen_t cmsg_len - INT cmsg_level; //int cmsg_level - INT cmsg_type; //int cmsg_type; - followed by UCHAR cmsg_data[] -} */ # define msg_name name # define msg_namelen namelen @@ -57,7 +47,6 @@ struct _WSACMSGHDR { # define iov_base buf # define iov_len len -# define cmsghdr _WSACMSGHDR # ifdef CMSG_DATA # undef CMSG_DATA # endif @@ -1352,29 +1341,32 @@ static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, se { int *iarr = args[0]; - if (Z_TYPE_P(elem) == IS_RESOURCE) { - php_stream *stream; - php_socket *sock; - - sock = (php_socket *)zend_fetch_resource_ex(elem, NULL, php_sockets_le_socket()); - if (sock) { - iarr[i] = sock->bsd_socket; + if (Z_TYPE_P(elem) == IS_OBJECT && Z_OBJCE_P(elem) == socket_ce) { + php_socket *sock = Z_SOCKET_P(elem); + if (IS_INVALID_SOCKET(sock)) { + do_from_zval_err(ctx, "socket is already closed"); return; } + iarr[i] = sock->bsd_socket; + return; + } + + if (Z_TYPE_P(elem) == IS_RESOURCE) { + php_stream *stream; + stream = (php_stream *)zend_fetch_resource2_ex(elem, NULL, php_file_le_stream(), php_file_le_pstream()); if (stream == NULL) { - do_from_zval_err(ctx, "resource is not a stream or a socket"); + do_from_zval_err(ctx, "resource is not a stream"); return; } - if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1], - REPORT_ERRORS) == FAILURE) { + if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1], REPORT_ERRORS) == FAILURE) { do_from_zval_err(ctx, "cast stream to file descriptor failed"); return; } } else { - do_from_zval_err(ctx, "expected a resource variable"); + do_from_zval_err(ctx, "expected a Socket object or a stream resource"); } } void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx) @@ -1425,8 +1417,10 @@ void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx) return; } if (S_ISSOCK(statbuf.st_mode)) { - php_socket *sock = socket_import_file_descriptor(fd); - ZVAL_RES(&elem, zend_register_resource(sock, php_sockets_le_socket())); + object_init_ex(&elem, socket_ce); + php_socket *sock = Z_SOCKET_P(&elem); + + socket_import_file_descriptor(fd, sock); } else { php_stream *stream = php_stream_fopen_from_fd(fd, "rw", NULL); php_stream_to_zval(stream, &elem); diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index c6aa9f0c78..321efdc403 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -69,7 +67,7 @@ int php_string_to_if_index(const char *val, unsigned *out) ind = if_nametoindex(val); if (ind == 0) { php_error_docref(NULL, E_WARNING, - "no interface with name \"%s\" could be found", val); + "No interface with name \"%s\" could be found", val); return FAILURE; } else { *out = ind; @@ -77,7 +75,7 @@ int php_string_to_if_index(const char *val, unsigned *out) } #else php_error_docref(NULL, E_WARNING, - "this platform does not support looking up an interface by " + "This platform does not support looking up an interface by " "name, an integer interface index must be supplied instead"); return FAILURE; #endif @@ -89,14 +87,11 @@ static int php_get_if_index_from_zval(zval *val, unsigned *out) if (Z_TYPE_P(val) == IS_LONG) { if (Z_LVAL_P(val) < 0 || (zend_ulong)Z_LVAL_P(val) > UINT_MAX) { - php_error_docref(NULL, E_WARNING, - "the interface index cannot be negative or larger than %u;" - " given " ZEND_LONG_FMT, UINT_MAX, Z_LVAL_P(val)); - ret = FAILURE; - } else { - *out = Z_LVAL_P(val); - ret = SUCCESS; + zend_value_error("Index must be between 0 and %u", UINT_MAX); + return FAILURE; } + *out = Z_LVAL_P(val); + ret = SUCCESS; } else { zend_string *tmp_str; zend_string *str = zval_get_tmp_string(val, &tmp_str); @@ -129,7 +124,7 @@ static int php_get_address_from_array(const HashTable *ht, const char *key, zend_string *str, *tmp_str; if ((val = zend_hash_str_find(ht, key, strlen(key))) == NULL) { - php_error_docref(NULL, E_WARNING, "no key \"%s\" passed in optval", key); + zend_value_error("No key \"%s\" passed in optval", key); return FAILURE; } str = zval_get_tmp_string(val, &tmp_str); @@ -159,11 +154,11 @@ static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval * goto mcast_req_fun; case PHP_MCAST_LEAVE_GROUP: { + mcast_req_fun = &php_mcast_leave; +mcast_req_fun: ; php_sockaddr_storage group = {0}; socklen_t glen; - mcast_req_fun = &php_mcast_leave; -mcast_req_fun: convert_to_array_ex(arg4); opt_ht = Z_ARRVAL_P(arg4); @@ -193,13 +188,13 @@ mcast_req_fun: goto mcast_sreq_fun; case PHP_MCAST_LEAVE_SOURCE_GROUP: { + mcast_sreq_fun = &php_mcast_leave_source; + mcast_sreq_fun: ; php_sockaddr_storage group = {0}, source = {0}; socklen_t glen, slen; - mcast_sreq_fun = &php_mcast_leave_source; - mcast_sreq_fun: convert_to_array_ex(arg4); opt_ht = Z_ARRVAL_P(arg4); @@ -223,14 +218,14 @@ mcast_req_fun: #endif default: php_error_docref(NULL, E_WARNING, - "unexpected option in php_do_mcast_opt (level %d, option %d). " + "Unexpected option in php_do_mcast_opt (level %d, option %d). " "This is a bug.", level, optname); return FAILURE; } if (retval != 0) { if (retval != -2) { /* error, but message already emitted */ - PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); } return FAILURE; } @@ -284,8 +279,7 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock, case IP_MULTICAST_TTL: convert_to_long_ex(arg4); if (Z_LVAL_P(arg4) < 0L || Z_LVAL_P(arg4) > 255L) { - php_error_docref(NULL, E_WARNING, - "Expected a value between 0 and 255"); + zend_argument_value_error(4, "must be between 0 and 255"); return FAILURE; } ipv4_mcast_ttl_lback = (unsigned char) Z_LVAL_P(arg4); @@ -300,7 +294,7 @@ ipv4_loop_ttl: dosockopt: retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen); if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); return FAILURE; } @@ -349,8 +343,7 @@ int php_do_setsockopt_ipv6_mcast(php_socket *php_sock, case IPV6_MULTICAST_HOPS: convert_to_long_ex(arg4); if (Z_LVAL_P(arg4) < -1L || Z_LVAL_P(arg4) > 255L) { - php_error_docref(NULL, E_WARNING, - "Expected a value between -1 and 255"); + zend_argument_value_error(4, "must be between -1 and 255"); return FAILURE; } ov = (int) Z_LVAL_P(arg4); @@ -365,7 +358,7 @@ ipv6_loop_hops: dosockopt: retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen); if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); return FAILURE; } @@ -498,8 +491,7 @@ static int _php_mcast_join_leave( } #endif else { - php_error_docref(NULL, E_WARNING, - "Option %s is inapplicable to this socket type", + zend_value_error("Option %s is inapplicable to this socket type", join ? "MCAST_JOIN_GROUP" : "MCAST_LEAVE_GROUP"); return -2; } diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h index 256af0c66c..98a19ba54c 100644 --- a/ext/sockets/multicast.h +++ b/ext/sockets/multicast.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index c1aba9dc98..83d5bdd7c2 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -31,6 +29,8 @@ #include <php.h> #ifdef PHP_WIN32 # include "windows_common.h" +#else +# define IS_INVALID_SOCKET(a) (a->bsd_socket < 0) #endif #define PHP_SOCKETS_VERSION PHP_VERSION @@ -54,14 +54,32 @@ typedef int PHP_SOCKET; typedef SOCKET PHP_SOCKET; #endif +/* Socket class */ + typedef struct { PHP_SOCKET bsd_socket; int type; int error; int blocking; zval zstream; + zend_object std; } php_socket; +extern zend_class_entry *socket_ce; + +static inline php_socket *socket_from_obj(zend_object *obj) { + return (php_socket *)((char *)(obj) - XtOffsetOf(php_socket, std)); +} + +#define Z_SOCKET_P(zv) socket_from_obj(Z_OBJ_P(zv)) + +#define ENSURE_SOCKET_VALID(php_sock) do { \ + if (IS_INVALID_SOCKET(php_sock)) { \ + zend_argument_error(NULL, 1, "has already been closed"); \ + RETURN_THROWS(); \ + } \ +} while (0) + #ifdef PHP_WIN32 struct sockaddr_un { short sun_family; @@ -69,14 +87,6 @@ struct sockaddr_un { }; #endif -PHP_SOCKETS_API int php_sockets_le_socket(void); -PHP_SOCKETS_API php_socket *php_create_socket(void); -PHP_SOCKETS_API void php_destroy_socket(zend_resource *rsrc); -PHP_SOCKETS_API void php_destroy_sockaddr(zend_resource *rsrc); - -#define php_sockets_le_socket_name "Socket" -#define php_sockets_le_addrinfo_name "AddressInfo" - #define PHP_SOCKET_ERROR(socket, msg, errn) \ do { \ int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \ @@ -106,7 +116,7 @@ enum sockopt_return { }; char *sockets_strerror(int error); -php_socket *socket_import_file_descriptor(PHP_SOCKET sock); +int socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock); #else #define phpext_sockets_ptr NULL diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index b5f17a5ad4..f03fdb0c63 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -68,12 +66,11 @@ inline ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) } #endif -#define LONG_CHECK_VALID_INT(l) \ +#define LONG_CHECK_VALID_INT(l, arg_pos) \ do { \ if ((l) < INT_MIN && (l) > INT_MAX) { \ - php_error_docref(NULL, E_WARNING, "The value " ZEND_LONG_FMT " does not fit inside " \ - "the boundaries of a native integer", (l)); \ - return; \ + zend_argument_value_error((arg_pos), "must be between %d and %d", INT_MIN, INT_MAX); \ + RETURN_THROWS(); \ } \ } while (0) @@ -175,16 +172,14 @@ PHP_FUNCTION(socket_sendmsg) ssize_t res; /* zmsg should be passed by ref */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra|l", &zsocket, &zmsg, &flags) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa|l", &zsocket, socket_ce, &zmsg, &flags) == FAILURE) { + RETURN_THROWS(); } - LONG_CHECK_VALID_INT(flags); + LONG_CHECK_VALID_INT(flags, 3); - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(zsocket), - php_sockets_le_socket_name, php_sockets_le_socket())) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(zsocket); + ENSURE_SOCKET_VALID(php_sock); msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_send, sizeof(*msghdr), "msghdr", &allocations, &err); @@ -218,17 +213,14 @@ PHP_FUNCTION(socket_recvmsg) struct err_s err = {0}; //ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra|l", - &zsocket, &zmsg, &flags) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa|l", &zsocket, socket_ce, &zmsg, &flags) == FAILURE) { + RETURN_THROWS(); } - LONG_CHECK_VALID_INT(flags); + LONG_CHECK_VALID_INT(flags, 3); - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(zsocket), - php_sockets_le_socket_name, php_sockets_le_socket())) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(zsocket); + ENSURE_SOCKET_VALID(php_sock); msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_recv, sizeof(*msghdr), "msghdr", &allocations, &err); @@ -266,7 +258,7 @@ PHP_FUNCTION(socket_recvmsg) RETVAL_LONG((zend_long)res); } else { SOCKETS_G(last_error) = errno; - php_error_docref(NULL, E_WARNING, "error in recvmsg [%d]: %s", + php_error_docref(NULL, E_WARNING, "Error in recvmsg [%d]: %s", errno, sockets_strerror(errno)); RETVAL_FALSE; } @@ -283,32 +275,36 @@ PHP_FUNCTION(socket_cmsg_space) if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|l", &level, &type, &n) == FAILURE) { - return; + RETURN_THROWS(); } - LONG_CHECK_VALID_INT(level); - LONG_CHECK_VALID_INT(type); - LONG_CHECK_VALID_INT(n); + LONG_CHECK_VALID_INT(level, 1); + LONG_CHECK_VALID_INT(type, 2); + LONG_CHECK_VALID_INT(n, 3); if (n < 0) { - php_error_docref(NULL, E_WARNING, "The third argument " - "cannot be negative"); - return; + zend_argument_value_error(3, "must be greater than or equal to 0"); + RETURN_THROWS(); } entry = get_ancillary_reg_entry(level, type); if (entry == NULL) { - php_error_docref(NULL, E_WARNING, "The pair level " ZEND_LONG_FMT "/type " ZEND_LONG_FMT " is " - "not supported by PHP", level, type); - return; + zend_value_error("Pair level " ZEND_LONG_FMT " and/or type " ZEND_LONG_FMT " is not supported", + level, type); + RETURN_THROWS(); } - if (entry->var_el_size > 0 && n > (zend_long)((ZEND_LONG_MAX - entry->size - - CMSG_SPACE(0) - 15L) / entry->var_el_size)) { - /* the -15 is to account for any padding CMSG_SPACE may add after the data */ - php_error_docref(NULL, E_WARNING, "The value for the " - "third argument (" ZEND_LONG_FMT ") is too large", n); - return; + if (entry->var_el_size > 0) { + size_t rem_size = ZEND_LONG_MAX - entry->size; + size_t n_max = rem_size / entry->var_el_size; + size_t size = entry->size + n * entry->var_el_size; + size_t total_size = CMSG_SPACE(size); + if (n > n_max /* zend_long overflow */ + || total_size > ZEND_LONG_MAX + || total_size < size /* align overflow */) { + zend_argument_value_error(3, "is too large"); + RETURN_THROWS(); + } } RETURN_LONG((zend_long)CMSG_SPACE(entry->size + n * entry->var_el_size)); @@ -359,7 +355,7 @@ int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, dosockopt: retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen); if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); } allocations_dispose(&allocations); diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 4c9f403131..21c107adec 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -30,6 +28,7 @@ #include "ext/standard/file.h" #include "ext/standard/info.h" #include "php_ini.h" +#include "zend_interfaces.h" #ifdef PHP_WIN32 # include "windows_common.h" # include <win32/inet.h> @@ -52,7 +51,6 @@ # include <fcntl.h> # include <signal.h> # include <sys/uio.h> -# define IS_INVALID_SOCKET(a) (a->bsd_socket < 0) # define set_errno(a) (errno = a) # include "php_sockets.h" # if HAVE_IF_NAMETOINDEX @@ -65,6 +63,7 @@ #include "sockaddr_conv.h" #include "multicast.h" #include "sendrecvmsg.h" +#include "sockets_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(sockets) @@ -93,229 +92,6 @@ ZEND_DECLARE_MODULE_GLOBALS(sockets) #define PHP_NORMAL_READ 0x0001 #define PHP_BINARY_READ 0x0002 -static int le_socket; -#define le_socket_name php_sockets_le_socket_name - -static int le_addrinfo; -#define le_addrinfo_name php_sockets_le_addrinfo_name - -/* The AI_IDN_ALLOW_UNASSIGNED deprecations are implemented as a pragma GCC warning, - * using _Pragma() for macro support. As this warning is thrown without a warning - * category, it's also not possible to suppress it, because it is not part of - * -Wdeprecated-declarations or similar. We work around this by defining - * __glibc_macro_warning() to be empty. */ -#undef __glibc_macro_warning -#define __glibc_macro_warning(message) - -/* {{{ arginfo */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_select, 0, 0, 4) - ZEND_ARG_INFO(1, read_fds) - ZEND_ARG_INFO(1, write_fds) - ZEND_ARG_INFO(1, except_fds) - ZEND_ARG_INFO(0, tv_sec) - ZEND_ARG_INFO(0, tv_usec) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_create_listen, 0, 0, 1) - ZEND_ARG_INFO(0, port) - ZEND_ARG_INFO(0, backlog) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_accept, 0, 0, 1) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_set_nonblock, 0, 0, 1) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_set_block, 0, 0, 1) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_listen, 0, 0, 1) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, backlog) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_close, 0, 0, 1) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_write, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, buf) - ZEND_ARG_INFO(0, length) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_read, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, length) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_getsockname, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(1, addr) - ZEND_ARG_INFO(1, port) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_getpeername, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(1, addr) - ZEND_ARG_INFO(1, port) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_create, 0, 0, 3) - ZEND_ARG_INFO(0, domain) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, protocol) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_connect, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, addr) - ZEND_ARG_INFO(0, port) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_strerror, 0, 0, 1) - ZEND_ARG_INFO(0, errno) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_bind, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, addr) - ZEND_ARG_INFO(0, port) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_recv, 0, 0, 4) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(1, buf) - ZEND_ARG_INFO(0, len) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_send, 0, 0, 4) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, buf) - ZEND_ARG_INFO(0, len) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_recvfrom, 0, 0, 5) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(1, buf) - ZEND_ARG_INFO(0, len) - ZEND_ARG_INFO(0, flags) - ZEND_ARG_INFO(1, name) - ZEND_ARG_INFO(1, port) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_sendto, 0, 0, 5) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, buf) - ZEND_ARG_INFO(0, len) - ZEND_ARG_INFO(0, flags) - ZEND_ARG_INFO(0, addr) - ZEND_ARG_INFO(0, port) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_get_option, 0, 0, 3) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, level) - ZEND_ARG_INFO(0, optname) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_set_option, 0, 0, 4) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, level) - ZEND_ARG_INFO(0, optname) - ZEND_ARG_INFO(0, optval) -ZEND_END_ARG_INFO() - -#ifdef HAVE_SOCKETPAIR -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_create_pair, 0, 0, 4) - ZEND_ARG_INFO(0, domain) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, protocol) - ZEND_ARG_INFO(1, fd) -ZEND_END_ARG_INFO() -#endif - -#ifdef HAVE_SHUTDOWN -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_shutdown, 0, 0, 1) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, how) -ZEND_END_ARG_INFO() -#endif - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_last_error, 0, 0, 0) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_clear_error, 0, 0, 0) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_import_stream, 0, 0, 1) - ZEND_ARG_INFO(0, stream) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_export_stream, 0, 0, 1) - ZEND_ARG_INFO(0, socket) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_sendmsg, 0, 0, 3) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, msghdr) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_recvmsg, 0, 0, 3) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(1, msghdr) - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_cmsg_space, 0, 0, 2) - ZEND_ARG_INFO(0, level) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_lookup, 0, 0, 1) - ZEND_ARG_INFO(0, host) - ZEND_ARG_INFO(0, service) - ZEND_ARG_INFO(0, hints) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_connect, 0, 0, 1) - ZEND_ARG_INFO(0, addr) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_bind, 0, 0, 1) - ZEND_ARG_INFO(0, addr) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_explain, 0, 0, 1) - ZEND_ARG_INFO(0, addr) -ZEND_END_ARG_INFO() - -#ifdef PHP_WIN32 -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_wsaprotocol_info_export, 0, 0, 2) - ZEND_ARG_INFO(0, socket) - ZEND_ARG_INFO(0, target_pid) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_wsaprotocol_info_import, 0, 0, 1) - ZEND_ARG_INFO(0, info_id) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_wsaprotocol_info_release, 0, 0, 1) - ZEND_ARG_INFO(0, info_id) -ZEND_END_ARG_INFO() -#endif -/* }}} */ - static PHP_GINIT_FUNCTION(sockets); static PHP_GSHUTDOWN_FUNCTION(sockets); static PHP_MINIT_FUNCTION(sockets); @@ -323,107 +99,106 @@ static PHP_MSHUTDOWN_FUNCTION(sockets); static PHP_MINFO_FUNCTION(sockets); static PHP_RSHUTDOWN_FUNCTION(sockets); -PHP_FUNCTION(socket_select); -PHP_FUNCTION(socket_create_listen); -#ifdef HAVE_SOCKETPAIR -PHP_FUNCTION(socket_create_pair); -#endif -PHP_FUNCTION(socket_accept); -PHP_FUNCTION(socket_set_nonblock); -PHP_FUNCTION(socket_set_block); -PHP_FUNCTION(socket_listen); -PHP_FUNCTION(socket_close); -PHP_FUNCTION(socket_write); -PHP_FUNCTION(socket_read); -PHP_FUNCTION(socket_getsockname); -PHP_FUNCTION(socket_getpeername); -PHP_FUNCTION(socket_create); -PHP_FUNCTION(socket_connect); -PHP_FUNCTION(socket_strerror); -PHP_FUNCTION(socket_bind); -PHP_FUNCTION(socket_recv); -PHP_FUNCTION(socket_send); -PHP_FUNCTION(socket_recvfrom); -PHP_FUNCTION(socket_sendto); -PHP_FUNCTION(socket_get_option); -PHP_FUNCTION(socket_set_option); -#ifdef HAVE_SHUTDOWN -PHP_FUNCTION(socket_shutdown); -#endif -PHP_FUNCTION(socket_last_error); -PHP_FUNCTION(socket_clear_error); -PHP_FUNCTION(socket_import_stream); -PHP_FUNCTION(socket_export_stream); -PHP_FUNCTION(socket_addrinfo_lookup); -PHP_FUNCTION(socket_addrinfo_connect); -PHP_FUNCTION(socket_addrinfo_bind); -PHP_FUNCTION(socket_addrinfo_explain); -#ifdef PHP_WIN32 -PHP_FUNCTION(socket_wsaprotocol_info_export); -PHP_FUNCTION(socket_wsaprotocol_info_import); -PHP_FUNCTION(socket_wsaprotocol_info_release); -#endif +/* Socket class */ -/* {{{ sockets_functions[] - */ -static const zend_function_entry sockets_functions[] = { - PHP_FE(socket_select, arginfo_socket_select) - PHP_FE(socket_create, arginfo_socket_create) - PHP_FE(socket_create_listen, arginfo_socket_create_listen) -#ifdef HAVE_SOCKETPAIR - PHP_FE(socket_create_pair, arginfo_socket_create_pair) -#endif - PHP_FE(socket_accept, arginfo_socket_accept) - PHP_FE(socket_set_nonblock, arginfo_socket_set_nonblock) - PHP_FE(socket_set_block, arginfo_socket_set_block) - PHP_FE(socket_listen, arginfo_socket_listen) - PHP_FE(socket_close, arginfo_socket_close) - PHP_FE(socket_write, arginfo_socket_write) - PHP_FE(socket_read, arginfo_socket_read) - PHP_FE(socket_getsockname, arginfo_socket_getsockname) - PHP_FE(socket_getpeername, arginfo_socket_getpeername) - PHP_FE(socket_connect, arginfo_socket_connect) - PHP_FE(socket_strerror, arginfo_socket_strerror) - PHP_FE(socket_bind, arginfo_socket_bind) - PHP_FE(socket_recv, arginfo_socket_recv) - PHP_FE(socket_send, arginfo_socket_send) - PHP_FE(socket_recvfrom, arginfo_socket_recvfrom) - PHP_FE(socket_sendto, arginfo_socket_sendto) - PHP_FE(socket_get_option, arginfo_socket_get_option) - PHP_FE(socket_set_option, arginfo_socket_set_option) -#ifdef HAVE_SHUTDOWN - PHP_FE(socket_shutdown, arginfo_socket_shutdown) -#endif - PHP_FE(socket_last_error, arginfo_socket_last_error) - PHP_FE(socket_clear_error, arginfo_socket_clear_error) - PHP_FE(socket_import_stream, arginfo_socket_import_stream) - PHP_FE(socket_export_stream, arginfo_socket_export_stream) - PHP_FE(socket_sendmsg, arginfo_socket_sendmsg) - PHP_FE(socket_recvmsg, arginfo_socket_recvmsg) - PHP_FE(socket_cmsg_space, arginfo_socket_cmsg_space) - PHP_FE(socket_addrinfo_lookup, arginfo_socket_addrinfo_lookup) - PHP_FE(socket_addrinfo_connect, arginfo_socket_addrinfo_connect) - PHP_FE(socket_addrinfo_bind, arginfo_socket_addrinfo_bind) - PHP_FE(socket_addrinfo_explain, arginfo_socket_addrinfo_explain) - - /* for downwards compatibility */ - PHP_FALIAS(socket_getopt, socket_get_option, arginfo_socket_get_option) - PHP_FALIAS(socket_setopt, socket_set_option, arginfo_socket_set_option) +zend_class_entry *socket_ce; +static zend_object_handlers socket_object_handlers; -#ifdef PHP_WIN32 - PHP_FE(socket_wsaprotocol_info_export, arginfo_socket_wsaprotocol_info_export) - PHP_FE(socket_wsaprotocol_info_import, arginfo_socket_wsaprotocol_info_import) - PHP_FE(socket_wsaprotocol_info_release, arginfo_socket_wsaprotocol_info_release) -#endif +static zend_object *socket_create_object(zend_class_entry *class_type) { + php_socket *intern = zend_object_alloc(sizeof(php_socket), class_type); - PHP_FE_END -}; -/* }}} */ + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &socket_object_handlers; + + intern->bsd_socket = -1; /* invalid socket */ + intern->type = PF_UNSPEC; + intern->error = 0; + intern->blocking = 1; + ZVAL_UNDEF(&intern->zstream); + + return &intern->std; +} + +static zend_function *socket_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct Socket, use socket_create() instead"); + return NULL; +} + +static void socket_free_obj(zend_object *object) +{ + php_socket *socket = socket_from_obj(object); + + if (Z_ISUNDEF(socket->zstream)) { + if (!IS_INVALID_SOCKET(socket)) { + close(socket->bsd_socket); + } + } else { + zval_ptr_dtor(&socket->zstream); + } + + zend_object_std_dtor(&socket->std); +} + +static HashTable *socket_get_gc(zend_object *object, zval **table, int *n) +{ + php_socket *socket = socket_from_obj(object); + + *table = &socket->zstream; + *n = 1; + + return zend_std_get_properties(object); +} + +/* AddressInfo class */ + +typedef struct { + struct addrinfo addrinfo; + zend_object std; +} php_addrinfo; + +zend_class_entry *address_info_ce; +static zend_object_handlers address_info_object_handlers; + +static inline php_addrinfo *address_info_from_obj(zend_object *obj) { + return (php_addrinfo *)((char *)(obj) - XtOffsetOf(php_addrinfo, std)); +} + +#define Z_ADDRESS_INFO_P(zv) address_info_from_obj(Z_OBJ_P(zv)) + +static zend_object *address_info_create_object(zend_class_entry *class_type) { + php_addrinfo *intern = zend_object_alloc(sizeof(php_addrinfo), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &address_info_object_handlers; + + return &intern->std; +} + +static zend_function *address_info_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct AddressInfo, use socket_addrinfo_lookup() instead"); + return NULL; +} + +static void address_info_free_obj(zend_object *object) +{ + php_addrinfo *address_info = address_info_from_obj(object); + + if (address_info->addrinfo.ai_canonname != NULL) { + efree(address_info->addrinfo.ai_canonname); + } + efree(address_info->addrinfo.ai_addr); + + zend_object_std_dtor(&address_info->std); +} + +/* Module registration */ zend_module_entry sockets_module_entry = { STANDARD_MODULE_HEADER, "sockets", - sockets_functions, + ext_functions, PHP_MINIT(sockets), PHP_MSHUTDOWN(sockets), NULL, @@ -448,68 +223,16 @@ ZEND_GET_MODULE(sockets) /* inet_ntop should be used instead of inet_ntoa */ int inet_ntoa_lock = 0; -PHP_SOCKETS_API int php_sockets_le_socket(void) /* {{{ */ -{ - return le_socket; -} -/* }}} */ - -/* allocating function to make programming errors due to uninitialized fields - * less likely */ -PHP_SOCKETS_API php_socket *php_create_socket(void) /* {{{ */ -{ - php_socket *php_sock = emalloc(sizeof(php_socket)); - - php_sock->bsd_socket = -1; /* invalid socket */ - php_sock->type = PF_UNSPEC; - php_sock->error = 0; - php_sock->blocking = 1; - ZVAL_UNDEF(&php_sock->zstream); - - return php_sock; -} -/* }}} */ - -PHP_SOCKETS_API void php_destroy_socket(zend_resource *rsrc) /* {{{ */ -{ - php_socket *php_sock = rsrc->ptr; - - if (Z_ISUNDEF(php_sock->zstream)) { - if (!IS_INVALID_SOCKET(php_sock)) { - close(php_sock->bsd_socket); - } - } else { - zval_ptr_dtor(&php_sock->zstream); - } - efree(php_sock); -} -/* }}} */ - -PHP_SOCKETS_API void php_destroy_addrinfo(zend_resource *rsrc) /* {{{ */ -{ - struct addrinfo *addr = rsrc->ptr; - efree(addr->ai_addr); - if (addr->ai_canonname != NULL) { - efree(addr->ai_canonname); - } - efree(addr); -} -/* }}} */ - -static int php_open_listen_sock(php_socket **php_sock, int port, int backlog) /* {{{ */ +static int php_open_listen_sock(php_socket *sock, int port, int backlog) /* {{{ */ { struct sockaddr_in la; struct hostent *hp; - php_socket *sock = php_create_socket(); - - *php_sock = sock; #ifndef PHP_WIN32 if ((hp = php_network_gethostbyname("0.0.0.0")) == NULL) { #else if ((hp = php_network_gethostbyname("localhost")) == NULL) { #endif - efree(sock); return 0; } @@ -522,7 +245,6 @@ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog) /* if (IS_INVALID_SOCKET(sock)) { PHP_SOCKET_ERROR(sock, "unable to create listening socket", errno); - efree(sock); return 0; } @@ -531,14 +253,12 @@ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog) /* if (bind(sock->bsd_socket, (struct sockaddr *)&la, sizeof(la)) != 0) { PHP_SOCKET_ERROR(sock, "unable to bind to given address", errno); close(sock->bsd_socket); - efree(sock); return 0; } if (listen(sock->bsd_socket, backlog) != 0) { PHP_SOCKET_ERROR(sock, "unable to listen on socket", errno); close(sock->bsd_socket); - efree(sock); return 0; } @@ -546,12 +266,8 @@ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog) /* } /* }}} */ -static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct sockaddr *la, socklen_t *la_len) /* {{{ */ +static int php_accept_connect(php_socket *in_sock, php_socket *out_sock, struct sockaddr *la, socklen_t *la_len) /* {{{ */ { - php_socket *out_sock = php_create_socket(); - - *new_sock = out_sock; - out_sock->bsd_socket = accept(in_sock->bsd_socket, la, la_len); if (IS_INVALID_SOCKET(out_sock)) { @@ -710,15 +426,41 @@ static PHP_GSHUTDOWN_FUNCTION(sockets) } /* }}} */ -/* {{{ PHP_MINIT_FUNCTION - */ +/* {{{ PHP_MINIT_FUNCTION */ static PHP_MINIT_FUNCTION(sockets) { #if defined(COMPILE_DL_SOCKETS) && defined(ZTS) ZEND_TSRMLS_CACHE_UPDATE(); #endif - le_socket = zend_register_list_destructors_ex(php_destroy_socket, NULL, le_socket_name, module_number); - le_addrinfo = zend_register_list_destructors_ex(php_destroy_addrinfo, NULL, le_addrinfo_name, module_number); + + zend_class_entry ce_socket; + INIT_CLASS_ENTRY(ce_socket, "Socket", class_Socket_methods); + socket_ce = zend_register_internal_class(&ce_socket); + socket_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + socket_ce->create_object = socket_create_object; + socket_ce->serialize = zend_class_serialize_deny; + socket_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&socket_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + socket_object_handlers.offset = XtOffsetOf(php_socket, std); + socket_object_handlers.free_obj = socket_free_obj; + socket_object_handlers.get_constructor = socket_get_constructor; + socket_object_handlers.clone_obj = NULL; + socket_object_handlers.get_gc = socket_get_gc; + + zend_class_entry ce_address_info; + INIT_CLASS_ENTRY(ce_address_info, "AddressInfo", class_AddressInfo_methods); + address_info_ce = zend_register_internal_class(&ce_address_info); + address_info_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + address_info_ce->create_object = address_info_create_object; + address_info_ce->serialize = zend_class_serialize_deny; + address_info_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&address_info_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + address_info_object_handlers.offset = XtOffsetOf(php_addrinfo, std); + address_info_object_handlers.free_obj = address_info_free_obj; + address_info_object_handlers.get_constructor = address_info_get_constructor; + address_info_object_handlers.clone_obj = NULL; REGISTER_LONG_CONSTANT("AF_UNIX", AF_UNIX, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AF_INET", AF_INET, CONST_CS | CONST_PERSISTENT); @@ -858,8 +600,6 @@ static PHP_MINIT_FUNCTION(sockets) #if HAVE_AI_IDN REGISTER_LONG_CONSTANT("AI_IDN", AI_IDN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AI_CANONIDN", AI_CANONIDN, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("AI_IDN_ALLOW_UNASSIGNED", AI_IDN_ALLOW_UNASSIGNED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("AI_IDN_USE_STD3_ASCII_RULES", AI_IDN_USE_STD3_ASCII_RULES, CONST_CS | CONST_PERSISTENT); #endif #ifdef AI_NUMERICSERV REGISTER_LONG_CONSTANT("AI_NUMERICSERV", AI_NUMERICSERV, CONST_CS | CONST_PERSISTENT); @@ -871,8 +611,7 @@ static PHP_MINIT_FUNCTION(sockets) } /* }}} */ -/* {{{ PHP_MSHUTDOWN_FUNCTION - */ +/* {{{ PHP_MSHUTDOWN_FUNCTION */ static PHP_MSHUTDOWN_FUNCTION(sockets) { php_socket_sendrecvmsg_shutdown(SHUTDOWN_FUNC_ARGS_PASSTHRU); @@ -881,8 +620,7 @@ static PHP_MSHUTDOWN_FUNCTION(sockets) } /* }}} */ -/* {{{ PHP_MINFO_FUNCTION - */ +/* {{{ PHP_MINFO_FUNCTION */ static PHP_MINFO_FUNCTION(sockets) { php_info_print_table_start(); @@ -903,7 +641,7 @@ static PHP_RSHUTDOWN_FUNCTION(sockets) } /* }}} */ -static int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, PHP_SOCKET *max_fd) /* {{{ */ +static int php_sock_array_to_fd_set(uint32_t arg_num, zval *sock_array, fd_set *fds, PHP_SOCKET *max_fd) /* {{{ */ { zval *element; php_socket *php_sock; @@ -913,8 +651,17 @@ static int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, PHP_SOCKET *m ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(sock_array), element) { ZVAL_DEREF(element); - php_sock = (php_socket*) zend_fetch_resource_ex(element, le_socket_name, le_socket); - if (!php_sock) continue; /* If element is not a resource, skip it */ + + if (Z_TYPE_P(element) != IS_OBJECT || Z_OBJCE_P(element) != socket_ce) { + zend_argument_type_error(arg_num, "must only have elements of type Socket, %s given", zend_zval_type_name(element)); + return -1; + } + + php_sock = Z_SOCKET_P(element); + if (IS_INVALID_SOCKET(php_sock)) { + zend_argument_type_error(arg_num, "contains a closed socket"); + return -1; + } PHP_SAFE_FD_SET(php_sock->bsd_socket, fds); if (php_sock->bsd_socket > *max_fd) { @@ -937,13 +684,15 @@ static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds) /* {{{ */ zend_ulong num_key; zend_string *key; - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + ZEND_ASSERT(Z_TYPE_P(sock_array) == IS_ARRAY); array_init(&new_hash); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(sock_array), num_key, key, element) { ZVAL_DEREF(element); - php_sock = (php_socket*) zend_fetch_resource_ex(element, le_socket_name, le_socket); - if (!php_sock) continue; /* If element is not a resource, skip it */ + + php_sock = Z_SOCKET_P(element); + ZEND_ASSERT(php_sock); /* element is supposed to be Socket object */ + ZEND_ASSERT(!IS_INVALID_SOCKET(php_sock)); if (PHP_SAFE_FD_ISSET(php_sock->bsd_socket, fds)) { /* Add fd to new array */ @@ -968,47 +717,60 @@ static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds) /* {{{ */ } /* }}} */ -/* {{{ proto int socket_select(array &read_fds, array &write_fds, array &except_fds, int tv_sec[, int tv_usec]) - Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec */ +/* {{{ Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec */ PHP_FUNCTION(socket_select) { - zval *r_array, *w_array, *e_array, *sec; + zval *r_array, *w_array, *e_array; struct timeval tv; struct timeval *tv_p = NULL; fd_set rfds, wfds, efds; PHP_SOCKET max_fd = 0; int retval, sets = 0; - zend_long usec = 0; + zend_long sec, usec = 0; + zend_bool sec_is_null = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!a!z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!a!l!|l", &r_array, &w_array, &e_array, &sec, &sec_is_null, &usec) == FAILURE) { + RETURN_THROWS(); } FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); - if (r_array != NULL) sets += php_sock_array_to_fd_set(r_array, &rfds, &max_fd); - if (w_array != NULL) sets += php_sock_array_to_fd_set(w_array, &wfds, &max_fd); - if (e_array != NULL) sets += php_sock_array_to_fd_set(e_array, &efds, &max_fd); + if (r_array != NULL) { + sets += retval = php_sock_array_to_fd_set(1, r_array, &rfds, &max_fd); + if (retval == -1) { + RETURN_THROWS(); + } + } + if (w_array != NULL) { + sets += retval = php_sock_array_to_fd_set(2, w_array, &wfds, &max_fd); + if (retval == -1) { + RETURN_THROWS(); + } + } + if (e_array != NULL) { + sets += retval = php_sock_array_to_fd_set(3, e_array, &efds, &max_fd); + if (retval == -1) { + RETURN_THROWS(); + } + } if (!sets) { - php_error_docref(NULL, E_WARNING, "no resource arrays were passed to select"); - RETURN_FALSE; + zend_value_error("socket_select(): At least one array argument must be passed"); + RETURN_THROWS(); } PHP_SAFE_MAX_FD(max_fd, 0); /* someone needs to make this look more like stream_socket_select */ /* If seconds is not set to null, build the timeval, else we wait indefinitely */ - if (sec != NULL) { - zend_long s = zval_get_long(sec); - + if (!sec_is_null) { /* Solaris + BSD do not like microsecond values which are >= 1 sec */ if (usec > 999999) { - tv.tv_sec = s + (usec / 1000000); + tv.tv_sec = sec + (usec / 1000000); tv.tv_usec = usec % 1000000; } else { - tv.tv_sec = s; + tv.tv_sec = sec; tv.tv_usec = usec; } @@ -1019,7 +781,7 @@ PHP_FUNCTION(socket_select) if (retval == -1) { SOCKETS_G(last_error) = errno; - php_error_docref(NULL, E_WARNING, "unable to select [%d]: %s", errno, sockets_strerror(errno)); + php_error_docref(NULL, E_WARNING, "Unable to select [%d]: %s", errno, sockets_strerror(errno)); RETURN_FALSE; } @@ -1031,67 +793,66 @@ PHP_FUNCTION(socket_select) } /* }}} */ -/* {{{ proto resource socket_create_listen(int port[, int backlog]) - Opens a socket on port to accept connections */ +/* {{{ Opens a socket on port to accept connections */ PHP_FUNCTION(socket_create_listen) { php_socket *php_sock; zend_long port, backlog = 128; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &port, &backlog) == FAILURE) { - return; + RETURN_THROWS(); } - if (!php_open_listen_sock(&php_sock, port, backlog)) { + object_init_ex(return_value, socket_ce); + php_sock = Z_SOCKET_P(return_value); + + if (!php_open_listen_sock(php_sock, port, backlog)) { + zval_ptr_dtor(return_value); RETURN_FALSE; } php_sock->error = 0; php_sock->blocking = 1; - - RETURN_RES(zend_register_resource(php_sock, le_socket)); } /* }}} */ -/* {{{ proto resource socket_accept(resource socket) - Accepts a connection on the listening socket fd */ +/* {{{ Accepts a connection on the listening socket fd */ PHP_FUNCTION(socket_accept) { - zval *arg1; + zval *arg1; php_socket *php_sock, *new_sock; php_sockaddr_storage sa; socklen_t php_sa_len = sizeof(sa); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, socket_ce) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); - if (!php_accept_connect(php_sock, &new_sock, (struct sockaddr*)&sa, &php_sa_len)) { + object_init_ex(return_value, socket_ce); + new_sock = Z_SOCKET_P(return_value); + + if (!php_accept_connect(php_sock, new_sock, (struct sockaddr*)&sa, &php_sa_len)) { + zval_ptr_dtor(return_value); RETURN_FALSE; } - - RETURN_RES(zend_register_resource(new_sock, le_socket)); } /* }}} */ -/* {{{ proto bool socket_set_nonblock(resource socket) - Sets nonblocking mode on a socket resource */ +/* {{{ Sets nonblocking mode on a socket resource */ PHP_FUNCTION(socket_set_nonblock) { zval *arg1; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, socket_ce) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); if (!Z_ISUNDEF(php_sock->zstream)) { php_stream *stream; @@ -1116,20 +877,18 @@ PHP_FUNCTION(socket_set_nonblock) } /* }}} */ -/* {{{ proto bool socket_set_block(resource socket) - Sets blocking mode on a socket resource */ +/* {{{ Sets blocking mode on a socket resource */ PHP_FUNCTION(socket_set_block) { zval *arg1; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, socket_ce) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); /* if socket was created from a stream, give the stream a chance to take * care of the operation itself, thereby allowing it to update its internal @@ -1156,21 +915,19 @@ PHP_FUNCTION(socket_set_block) } /* }}} */ -/* {{{ proto bool socket_listen(resource socket[, int backlog]) - Sets the maximum number of connections allowed to be waited for on the socket specified by fd */ +/* {{{ Sets the maximum number of connections allowed to be waited for on the socket specified by fd */ PHP_FUNCTION(socket_listen) { zval *arg1; php_socket *php_sock; zend_long backlog = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &arg1, &backlog) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &arg1, socket_ce, &backlog) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); if (listen(php_sock->bsd_socket, backlog) != 0) { PHP_SOCKET_ERROR(php_sock, "unable to listen on socket", errno); @@ -1180,24 +937,22 @@ PHP_FUNCTION(socket_listen) } /* }}} */ -/* {{{ proto void socket_close(resource socket) - Closes a file descriptor */ +/* {{{ Closes a file descriptor */ PHP_FUNCTION(socket_close) { - zval *arg1; - php_socket *php_sock; + zval *arg1; + php_socket *php_socket; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, socket_ce) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_socket = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_socket); - if (!Z_ISUNDEF(php_sock->zstream)) { + if (!Z_ISUNDEF(php_socket->zstream)) { php_stream *stream = NULL; - php_stream_from_zval_no_verify(stream, &php_sock->zstream); + php_stream_from_zval_no_verify(stream, &php_socket->zstream); if (stream != NULL) { /* close & destroy stream, incl. removing it from the rsrc list; * resource stored in php_sock->zstream will become invalid */ @@ -1205,13 +960,18 @@ PHP_FUNCTION(socket_close) PHP_STREAM_FREE_KEEP_RSRC | PHP_STREAM_FREE_CLOSE | (stream->is_persistent?PHP_STREAM_FREE_CLOSE_PERSISTENT:0)); } + } else { + if (!IS_INVALID_SOCKET(php_socket)) { + close(php_socket->bsd_socket); + } } - zend_list_close(Z_RES_P(arg1)); + + ZVAL_UNDEF(&php_socket->zstream); + php_socket->bsd_socket = -1; } /* }}} */ -/* {{{ proto int socket_write(resource socket, string buf[, int length]) - Writes the buffer to the socket resource, length is optional */ +/* {{{ Writes the buffer to the socket resource, length is optional */ PHP_FUNCTION(socket_write) { zval *arg1; @@ -1219,22 +979,22 @@ PHP_FUNCTION(socket_write) int retval; size_t str_len; zend_long length = 0; + zend_bool length_is_null = 1; char *str; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &arg1, &str, &str_len, &length) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l!", &arg1, socket_ce, &str, &str_len, &length, &length_is_null) == FAILURE) { + RETURN_THROWS(); } - if (length < 0) { - php_error_docref(NULL, E_WARNING, "Length cannot be negative"); - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; + if (length < 0) { + zend_argument_value_error(3, "must be greater than or equal to 0"); + RETURN_THROWS(); } - if (ZEND_NUM_ARGS() < 3) { + if (length_is_null) { length = str_len; } @@ -1253,8 +1013,7 @@ PHP_FUNCTION(socket_write) } /* }}} */ -/* {{{ proto string socket_read(resource socket, int length [, int type]) - Reads a maximum of length bytes from socket */ +/* {{{ Reads a maximum of length bytes from socket */ PHP_FUNCTION(socket_read) { zval *arg1; @@ -1263,10 +1022,13 @@ PHP_FUNCTION(socket_read) int retval; zend_long length, type = PHP_BINARY_READ; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|l", &arg1, &length, &type) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|l", &arg1, socket_ce, &length, &type) == FAILURE) { + RETURN_THROWS(); } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); + /* overflow check */ if ((length + 1) < 2) { RETURN_FALSE; @@ -1274,10 +1036,6 @@ PHP_FUNCTION(socket_read) tmpbuf = zend_string_alloc(length, 0); - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } - if (type == PHP_NORMAL_READ) { retval = php_read(php_sock, ZSTR_VAL(tmpbuf), length, 0); } else { @@ -1313,8 +1071,7 @@ PHP_FUNCTION(socket_read) } /* }}} */ -/* {{{ proto bool socket_getsockname(resource socket, string &addr[, int &port]) - Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type. */ +/* {{{ Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type. */ PHP_FUNCTION(socket_getsockname) { zval *arg1, *addr, *port = NULL; @@ -1330,13 +1087,12 @@ PHP_FUNCTION(socket_getsockname) char *addr_string; socklen_t salen = sizeof(php_sockaddr_storage); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz|z", &arg1, &addr, &port) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz|z", &arg1, socket_ce, &addr, &port) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); sa = (struct sockaddr *) &sa_storage; @@ -1381,14 +1137,13 @@ PHP_FUNCTION(socket_getsockname) break; default: - php_error_docref(NULL, E_WARNING, "Unsupported address family %d", sa->sa_family); - RETURN_FALSE; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } } /* }}} */ -/* {{{ proto bool socket_getpeername(resource socket, string &addr[, int &port]) - Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type. */ +/* {{{ Queries the remote side of the given socket which may either result in host/port or in a UNIX filesystem path, dependent on its type. */ PHP_FUNCTION(socket_getpeername) { zval *arg1, *arg2, *arg3 = NULL; @@ -1404,13 +1159,12 @@ PHP_FUNCTION(socket_getpeername) char *addr_string; socklen_t salen = sizeof(php_sockaddr_storage); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz|z", &arg1, &arg2, &arg3) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz|z", &arg1, socket_ce, &arg2, &arg3) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); sa = (struct sockaddr *) &sa_storage; @@ -1458,83 +1212,81 @@ PHP_FUNCTION(socket_getpeername) break; default: - php_error_docref(NULL, E_WARNING, "Unsupported address family %d", sa->sa_family); - RETURN_FALSE; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } } /* }}} */ -/* {{{ proto resource socket_create(int domain, int type, int protocol) - Creates an endpoint for communication in the domain specified by domain, of type specified by type */ +/* {{{ Creates an endpoint for communication in the domain specified by domain, of type specified by type */ PHP_FUNCTION(socket_create) { - zend_long arg1, arg2, arg3; - php_socket *php_sock = php_create_socket(); + zend_long domain, type, protocol; + php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &arg1, &arg2, &arg3) == FAILURE) { - efree(php_sock); - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &domain, &type, &protocol) == FAILURE) { + RETURN_THROWS(); } - if (arg1 != AF_UNIX + if (domain != AF_UNIX #if HAVE_IPV6 - && arg1 != AF_INET6 + && domain != AF_INET6 #endif - && arg1 != AF_INET) { - php_error_docref(NULL, E_WARNING, "invalid socket domain [" ZEND_LONG_FMT "] specified for argument 1, assuming AF_INET", arg1); - arg1 = AF_INET; + && domain != AF_INET) { + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET6, or AF_INET"); + RETURN_THROWS(); } - if (arg2 > 10) { - php_error_docref(NULL, E_WARNING, "invalid socket type [" ZEND_LONG_FMT "] specified for argument 2, assuming SOCK_STREAM", arg2); - arg2 = SOCK_STREAM; + if (type > 10) { + zend_argument_value_error(2, "must be either SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET," + " SOCK_RAW, or SOCK_RDM"); + RETURN_THROWS(); } - php_sock->bsd_socket = socket(arg1, arg2, arg3); - php_sock->type = arg1; + object_init_ex(return_value, socket_ce); + php_sock = Z_SOCKET_P(return_value); + + php_sock->bsd_socket = socket(domain, type, protocol); + php_sock->type = domain; if (IS_INVALID_SOCKET(php_sock)) { SOCKETS_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Unable to create socket [%d]: %s", errno, sockets_strerror(errno)); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } php_sock->error = 0; php_sock->blocking = 1; - - RETURN_RES(zend_register_resource(php_sock, le_socket)); } /* }}} */ -/* {{{ proto bool socket_connect(resource socket, string addr [, int port]) - Opens a connection to addr:port on the socket specified by socket */ +/* {{{ Opens a connection to addr:port on the socket specified by socket */ PHP_FUNCTION(socket_connect) { - zval *arg1; + zval *resource_socket; php_socket *php_sock; char *addr; int retval; size_t addr_len; - zend_long port = 0; - int argc = ZEND_NUM_ARGS(); + zend_long port; + zend_bool port_is_null = 1; - if (zend_parse_parameters(argc, "rs|l", &arg1, &addr, &addr_len, &port) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l!", &resource_socket, socket_ce, &addr, &addr_len, &port, &port_is_null) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(resource_socket); + ENSURE_SOCKET_VALID(php_sock); switch(php_sock->type) { #if HAVE_IPV6 case AF_INET6: { struct sockaddr_in6 sin6 = {0}; - if (argc != 3) { - php_error_docref(NULL, E_WARNING, "Socket of type AF_INET6 requires 3 arguments"); - RETURN_FALSE; + if (port_is_null) { + zend_argument_value_error(3, "cannot be null when the socket type is AF_INET6"); + RETURN_THROWS(); } memset(&sin6, 0, sizeof(struct sockaddr_in6)); @@ -1553,9 +1305,9 @@ PHP_FUNCTION(socket_connect) case AF_INET: { struct sockaddr_in sin = {0}; - if (argc != 3) { - php_error_docref(NULL, E_WARNING, "Socket of type AF_INET requires 3 arguments"); - RETURN_FALSE; + if (port_is_null) { + zend_argument_value_error(3, "cannot be null when the socket type is AF_INET"); + RETURN_THROWS(); } sin.sin_family = AF_INET; @@ -1573,8 +1325,8 @@ PHP_FUNCTION(socket_connect) struct sockaddr_un s_un = {0}; if (addr_len >= sizeof(s_un.sun_path)) { - php_error_docref(NULL, E_WARNING, "Path too long"); - RETURN_FALSE; + zend_argument_value_error(2, "must be less than %d", sizeof(s_un.sun_path)); + RETURN_THROWS(); } s_un.sun_family = AF_UNIX; @@ -1585,8 +1337,8 @@ PHP_FUNCTION(socket_connect) } default: - php_error_docref(NULL, E_WARNING, "Unsupported socket type %d", php_sock->type); - RETURN_FALSE; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } if (retval != 0) { @@ -1598,22 +1350,20 @@ PHP_FUNCTION(socket_connect) } /* }}} */ -/* {{{ proto string socket_strerror(int errno) - Returns a string describing an error */ +/* {{{ Returns a string describing an error */ PHP_FUNCTION(socket_strerror) { zend_long arg1; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &arg1) == FAILURE) { - return; + RETURN_THROWS(); } RETURN_STRING(sockets_strerror(arg1)); } /* }}} */ -/* {{{ proto bool socket_bind(resource socket, string addr [, int port]) - Binds an open socket to a listening port, port is only specified in AF_INET family. */ +/* {{{ Binds an open socket to a listening port, port is only specified in AF_INET family. */ PHP_FUNCTION(socket_bind) { zval *arg1; @@ -1625,13 +1375,12 @@ PHP_FUNCTION(socket_bind) zend_long port = 0; zend_long retval = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &arg1, &addr, &addr_len, &port) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &arg1, socket_ce, &addr, &addr_len, &port) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); switch(php_sock->type) { case AF_UNIX: @@ -1641,10 +1390,8 @@ PHP_FUNCTION(socket_bind) sa->sun_family = AF_UNIX; if (addr_len >= sizeof(sa->sun_path)) { - php_error_docref(NULL, E_WARNING, - "Invalid path: too long (maximum size is %d)", - (int)sizeof(sa->sun_path) - 1); - RETURN_FALSE; + zend_argument_value_error(2, "must be less than %d", sizeof(sa->sun_path)); + RETURN_THROWS(); } memcpy(&sa->sun_path, addr, addr_len); @@ -1684,12 +1431,12 @@ PHP_FUNCTION(socket_bind) } #endif default: - php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type); - RETURN_FALSE; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to bind address", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to bind address", errno); RETURN_FALSE; } @@ -1697,8 +1444,7 @@ PHP_FUNCTION(socket_bind) } /* }}} */ -/* {{{ proto int socket_recv(resource socket, string &buf, int len, int flags) - Receives data from a connected socket */ +/* {{{ Receives data from a connected socket */ PHP_FUNCTION(socket_recv) { zval *php_sock_res, *buf; @@ -1707,13 +1453,12 @@ PHP_FUNCTION(socket_recv) int retval; zend_long len, flags; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rzll", &php_sock_res, &buf, &len, &flags) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ozll", &php_sock_res, socket_ce, &buf, &len, &flags) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(php_sock_res), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(php_sock_res); + ENSURE_SOCKET_VALID(php_sock); /* overflow check */ if ((len + 1) < 2) { @@ -1732,7 +1477,7 @@ PHP_FUNCTION(socket_recv) } if (retval == -1) { - PHP_SOCKET_ERROR(php_sock, "unable to read from socket", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to read from socket", errno); RETURN_FALSE; } @@ -1740,8 +1485,7 @@ PHP_FUNCTION(socket_recv) } /* }}} */ -/* {{{ proto int socket_send(resource socket, string buf, int len, int flags) - Sends data to a connected socket */ +/* {{{ Sends data to a connected socket */ PHP_FUNCTION(socket_send) { zval *arg1; @@ -1750,23 +1494,22 @@ PHP_FUNCTION(socket_send) zend_long len, flags; char *buf; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsll", &arg1, &buf, &buf_len, &len, &flags) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osll", &arg1, socket_ce, &buf, &buf_len, &len, &flags) == FAILURE) { + RETURN_THROWS(); } - if (len < 0) { - php_error_docref(NULL, E_WARNING, "Length cannot be negative"); - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; + if (len < 0) { + zend_argument_value_error(3, "must be greater than or equal to 0"); + RETURN_THROWS(); } retval = send(php_sock->bsd_socket, buf, (buf_len < (size_t)len ? buf_len : (size_t)len), flags); if (retval == (size_t)-1) { - PHP_SOCKET_ERROR(php_sock, "unable to write to socket", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to write to socket", errno); RETURN_FALSE; } @@ -1774,8 +1517,7 @@ PHP_FUNCTION(socket_send) } /* }}} */ -/* {{{ proto int socket_recvfrom(resource socket, string &buf, int len, int flags, string &name [, int &port]) - Receives data from a socket, connected or not */ +/* {{{ Receives data from a socket, connected or not */ PHP_FUNCTION(socket_recvfrom) { zval *arg1, *arg2, *arg5, *arg6 = NULL; @@ -1792,15 +1534,15 @@ PHP_FUNCTION(socket_recvfrom) char *address; zend_string *recv_buf; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rzllz|z", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ozllz|z", &arg1, socket_ce, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); /* overflow check */ + /* Shouldthrow ? */ if ((arg3 + 2) < 3) { RETURN_FALSE; } @@ -1816,7 +1558,7 @@ PHP_FUNCTION(socket_recvfrom) retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&s_un, (socklen_t *)&slen); if (retval < 0) { - PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to recvfrom", errno); zend_string_efree(recv_buf); RETURN_FALSE; } @@ -1840,7 +1582,7 @@ PHP_FUNCTION(socket_recvfrom) retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sin, (socklen_t *)&slen); if (retval < 0) { - PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to recvfrom", errno); zend_string_efree(recv_buf); RETURN_FALSE; } @@ -1883,16 +1625,15 @@ PHP_FUNCTION(socket_recvfrom) break; #endif default: - php_error_docref(NULL, E_WARNING, "Unsupported socket type %d", php_sock->type); - RETURN_FALSE; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } RETURN_LONG(retval); } /* }}} */ -/* {{{ proto int socket_sendto(resource socket, string buf, int len, int flags, string addr [, int port]) - Sends a message to a socket, whether it is connected or not */ +/* {{{ Sends a message to a socket, whether it is connected or not */ PHP_FUNCTION(socket_sendto) { zval *arg1; @@ -1904,35 +1645,35 @@ PHP_FUNCTION(socket_sendto) #endif int retval; size_t buf_len, addr_len; - zend_long len, flags, port = 0; + zend_long len, flags, port; + zend_bool port_is_null = 1; char *buf, *addr; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc, "rslls|l", &arg1, &buf, &buf_len, &len, &flags, &addr, &addr_len, &port) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oslls|l!", &arg1, socket_ce, &buf, &buf_len, &len, &flags, &addr, &addr_len, &port, &port_is_null) == FAILURE) { + RETURN_THROWS(); } - if (len < 0) { - php_error_docref(NULL, E_WARNING, "Length cannot be negative"); - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; + if (len < 0) { + zend_argument_value_error(3, "must be greater than or equal to 0"); + RETURN_THROWS(); } switch (php_sock->type) { case AF_UNIX: memset(&s_un, 0, sizeof(s_un)); s_un.sun_family = AF_UNIX; - snprintf(s_un.sun_path, 108, "%s", addr); + snprintf(s_un.sun_path, sizeof(s_un.sun_path), "%s", addr); retval = sendto(php_sock->bsd_socket, buf, ((size_t)len > buf_len) ? buf_len : (size_t)len, flags, (struct sockaddr *) &s_un, SUN_LEN(&s_un)); break; case AF_INET: - if (argc != 6) { - WRONG_PARAM_COUNT; + if (port_is_null) { + zend_argument_value_error(6, "cannot be null when the socket type is AF_INET"); + RETURN_THROWS(); } memset(&sin, 0, sizeof(sin)); @@ -1947,8 +1688,9 @@ PHP_FUNCTION(socket_sendto) break; #if HAVE_IPV6 case AF_INET6: - if (argc != 6) { - WRONG_PARAM_COUNT; + if (port_is_null) { + zend_argument_value_error(6, "cannot be null when the socket type is AF_INET6"); + RETURN_THROWS(); } memset(&sin6, 0, sizeof(sin6)); @@ -1963,12 +1705,12 @@ PHP_FUNCTION(socket_sendto) break; #endif default: - php_error_docref(NULL, E_WARNING, "Unsupported socket type %d", php_sock->type); - RETURN_FALSE; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } if (retval == -1) { - PHP_SOCKET_ERROR(php_sock, "unable to write to socket", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to write to socket", errno); RETURN_FALSE; } @@ -1976,8 +1718,7 @@ PHP_FUNCTION(socket_sendto) } /* }}} */ -/* {{{ proto mixed socket_get_option(resource socket, int level, int optname) - Gets socket options for the socket */ +/* {{{ Gets socket options for the socket */ PHP_FUNCTION(socket_get_option) { zval *arg1; @@ -1991,13 +1732,12 @@ PHP_FUNCTION(socket_get_option) int other_val; zend_long level, optname; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rll", &arg1, &level, &optname) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oll", &arg1, socket_ce, &level, &optname) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); if (level == IPPROTO_IP) { switch (optname) { @@ -2006,7 +1746,7 @@ PHP_FUNCTION(socket_get_option) unsigned int if_index; optlen = sizeof(if_addr); if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&if_addr, &optlen) != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); RETURN_FALSE; } if (php_add4_to_if_index(&if_addr, php_sock, &if_index) == SUCCESS) { @@ -2034,7 +1774,7 @@ PHP_FUNCTION(socket_get_option) optlen = sizeof(linger_val); if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&linger_val, &optlen) != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); RETURN_FALSE; } @@ -2049,14 +1789,14 @@ PHP_FUNCTION(socket_get_option) optlen = sizeof(tv); if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&tv, &optlen) != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); RETURN_FALSE; } #else optlen = sizeof(int); if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&timeout, &optlen) != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); RETURN_FALSE; } @@ -2075,7 +1815,7 @@ PHP_FUNCTION(socket_get_option) optlen = sizeof(other_val); if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); RETURN_FALSE; } @@ -2087,8 +1827,7 @@ PHP_FUNCTION(socket_get_option) } /* }}} */ -/* {{{ proto bool socket_set_option(resource socket, int level, int optname, int|array optval) - Sets socket options for the socket */ +/* {{{ Sets socket options for the socket */ PHP_FUNCTION(socket_set_option) { zval *arg1, *arg4; @@ -2106,14 +1845,12 @@ PHP_FUNCTION(socket_set_option) zval *l_onoff, *l_linger; zval *sec, *usec; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllz", &arg1, &level, &optname, &arg4) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ollz", &arg1, socket_ce, &level, &optname, &arg4) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); set_errno(0); @@ -2149,12 +1886,12 @@ PHP_FUNCTION(socket_set_option) opt_ht = Z_ARRVAL_P(arg4); if ((l_onoff = zend_hash_str_find(opt_ht, l_onoff_key, sizeof(l_onoff_key) - 1)) == NULL) { - php_error_docref(NULL, E_WARNING, "no key \"%s\" passed in optval", l_onoff_key); - RETURN_FALSE; + zend_argument_value_error(4, "must have key \"%s\"", l_onoff_key); + RETURN_THROWS(); } if ((l_linger = zend_hash_str_find(opt_ht, l_linger_key, sizeof(l_linger_key) - 1)) == NULL) { - php_error_docref(NULL, E_WARNING, "no key \"%s\" passed in optval", l_linger_key); - RETURN_FALSE; + zend_argument_value_error(4, "must have key \"%s\"", l_linger_key); + RETURN_THROWS(); } convert_to_long_ex(l_onoff); @@ -2177,12 +1914,12 @@ PHP_FUNCTION(socket_set_option) opt_ht = Z_ARRVAL_P(arg4); if ((sec = zend_hash_str_find(opt_ht, sec_key, sizeof(sec_key) - 1)) == NULL) { - php_error_docref(NULL, E_WARNING, "no key \"%s\" passed in optval", sec_key); - RETURN_FALSE; + zend_argument_value_error(4, "must have key \"%s\"", sec_key); + RETURN_THROWS(); } if ((usec = zend_hash_str_find(opt_ht, usec_key, sizeof(usec_key) - 1)) == NULL) { - php_error_docref(NULL, E_WARNING, "no key \"%s\" passed in optval", usec_key); - RETURN_FALSE; + zend_argument_value_error(4, "must have key \"%s\"", usec_key); + RETURN_THROWS(); } convert_to_long_ex(sec); @@ -2224,7 +1961,7 @@ default_case: retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen); if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); RETURN_FALSE; } @@ -2233,8 +1970,7 @@ default_case: /* }}} */ #ifdef HAVE_SOCKETPAIR -/* {{{ proto bool socket_create_pair(int domain, int type, int protocol, array &fd) - Creates a pair of indistinguishable sockets and stores them in fds. */ +/* {{{ Creates a pair of indistinguishable sockets and stores them in fds. */ PHP_FUNCTION(socket_create_pair) { zval retval[2], *fds_array_zval; @@ -2243,39 +1979,43 @@ PHP_FUNCTION(socket_create_pair) zend_long domain, type, protocol; if (zend_parse_parameters(ZEND_NUM_ARGS(), "lllz", &domain, &type, &protocol, &fds_array_zval) == FAILURE) { - return; + RETURN_THROWS(); } - php_sock[0] = php_create_socket(); - php_sock[1] = php_create_socket(); - if (domain != AF_INET #if HAVE_IPV6 && domain != AF_INET6 #endif && domain != AF_UNIX) { - php_error_docref(NULL, E_WARNING, "invalid socket domain [" ZEND_LONG_FMT "] specified for argument 1, assuming AF_INET", domain); - domain = AF_INET; + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET6 or AF_INET"); + RETURN_THROWS(); } if (type > 10) { - php_error_docref(NULL, E_WARNING, "invalid socket type [" ZEND_LONG_FMT "] specified for argument 2, assuming SOCK_STREAM", type); - type = SOCK_STREAM; + zend_argument_value_error(2, "must be either SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET," + " SOCK_RAW, or SOCK_RDM"); + RETURN_THROWS(); } + object_init_ex(&retval[0], socket_ce); + php_sock[0] = Z_SOCKET_P(&retval[0]); + + object_init_ex(&retval[1], socket_ce); + php_sock[1] = Z_SOCKET_P(&retval[1]); + if (socketpair(domain, type, protocol, fds_array) != 0) { SOCKETS_G(last_error) = errno; - php_error_docref(NULL, E_WARNING, "unable to create socket pair [%d]: %s", errno, sockets_strerror(errno)); - efree(php_sock[0]); - efree(php_sock[1]); + php_error_docref(NULL, E_WARNING, "Unable to create socket pair [%d]: %s", errno, sockets_strerror(errno)); + zval_ptr_dtor(&retval[0]); + zval_ptr_dtor(&retval[1]); RETURN_FALSE; } fds_array_zval = zend_try_array_init(fds_array_zval); if (!fds_array_zval) { - efree(php_sock[0]); - efree(php_sock[1]); - return; + zval_ptr_dtor(&retval[0]); + zval_ptr_dtor(&retval[1]); + RETURN_THROWS(); } php_sock[0]->bsd_socket = fds_array[0]; @@ -2287,9 +2027,6 @@ PHP_FUNCTION(socket_create_pair) php_sock[0]->blocking = 1; php_sock[1]->blocking = 1; - ZVAL_RES(&retval[0], zend_register_resource(php_sock[0], le_socket)); - ZVAL_RES(&retval[1], zend_register_resource(php_sock[1], le_socket)); - add_index_zval(fds_array_zval, 0, &retval[0]); add_index_zval(fds_array_zval, 1, &retval[1]); @@ -2299,24 +2036,22 @@ PHP_FUNCTION(socket_create_pair) #endif #ifdef HAVE_SHUTDOWN -/* {{{ proto bool socket_shutdown(resource socket[, int how]) - Shuts down a socket for receiving, sending, or both. */ +/* {{{ Shuts down a socket for receiving, sending, or both. */ PHP_FUNCTION(socket_shutdown) { zval *arg1; zend_long how_shutdown = 2; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &arg1, &how_shutdown) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &arg1, socket_ce, &how_shutdown) == FAILURE) { + RETURN_THROWS(); } - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); if (shutdown(php_sock->bsd_socket, how_shutdown) != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to shutdown socket", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to shutdown socket", errno); RETURN_FALSE; } @@ -2325,21 +2060,20 @@ PHP_FUNCTION(socket_shutdown) /* }}} */ #endif -/* {{{ proto int socket_last_error([resource socket]) - Returns the last socket error (either the last used or the provided socket resource) */ +/* {{{ Returns the last socket error (either the last used or the provided socket resource) */ PHP_FUNCTION(socket_last_error) { zval *arg1 = NULL; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &arg1, socket_ce) == FAILURE) { + RETURN_THROWS(); } if (arg1) { - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); + RETVAL_LONG(php_sock->error); } else { RETVAL_LONG(SOCKETS_G(last_error)); @@ -2347,21 +2081,20 @@ PHP_FUNCTION(socket_last_error) } /* }}} */ -/* {{{ proto void socket_clear_error([resource socket]) - Clears the error on the socket or the last error code. */ +/* {{{ Clears the error on the socket or the last error code. */ PHP_FUNCTION(socket_clear_error) { zval *arg1 = NULL; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &arg1, socket_ce) == FAILURE) { + RETURN_THROWS(); } if (arg1) { - if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; - } + php_sock = Z_SOCKET_P(arg1); + ENSURE_SOCKET_VALID(php_sock); + php_sock->error = 0; } else { SOCKETS_G(last_error) = 0; @@ -2371,20 +2104,18 @@ PHP_FUNCTION(socket_clear_error) } /* }}} */ -php_socket *socket_import_file_descriptor(PHP_SOCKET socket) +int socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock) { #ifdef SO_DOMAIN int type; socklen_t type_len = sizeof(type); #endif - php_socket *retsock; php_sockaddr_storage addr; socklen_t addr_len = sizeof(addr); #ifndef PHP_WIN32 int t; #endif - retsock = php_create_socket(); retsock->bsd_socket = socket; /* determine family */ @@ -2396,30 +2127,25 @@ php_socket *socket_import_file_descriptor(PHP_SOCKET socket) if (getsockname(socket, (struct sockaddr*)&addr, &addr_len) == 0) { retsock->type = addr.ss_family; } else { - PHP_SOCKET_ERROR(retsock, "unable to obtain socket family", errno); - goto error; + PHP_SOCKET_ERROR(retsock, "Unable to obtain socket family", errno); + return 0; } /* determine blocking mode */ #ifndef PHP_WIN32 t = fcntl(socket, F_GETFL); if (t == -1) { - PHP_SOCKET_ERROR(retsock, "unable to obtain blocking state", errno); - goto error; + PHP_SOCKET_ERROR(retsock, "Unable to obtain blocking state", errno); + return 0; } else { retsock->blocking = !(t & O_NONBLOCK); } #endif - return retsock; - -error: - efree(retsock); - return NULL; + return 1; } -/* {{{ proto resource socket_import_stream(resource stream) - Imports a stream that encapsulates a socket into a socket extension resource. */ +/* {{{ Imports a stream that encapsulates a socket into a socket extension resource. */ PHP_FUNCTION(socket_import_stream) { zval *zstream; @@ -2428,7 +2154,7 @@ PHP_FUNCTION(socket_import_stream) PHP_SOCKET socket; /* fd */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zstream) == FAILURE) { - return; + RETURN_THROWS(); } php_stream_from_zval(stream, zstream); @@ -2437,8 +2163,11 @@ PHP_FUNCTION(socket_import_stream) RETURN_FALSE; } - retsock = socket_import_file_descriptor(socket); - if (retsock == NULL) { + object_init_ex(return_value, socket_ce); + retsock = Z_SOCKET_P(return_value); + + if (!socket_import_file_descriptor(socket, retsock)) { + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2457,15 +2186,11 @@ PHP_FUNCTION(socket_import_stream) * also be done, but this makes socket_export_stream a bit simpler) */ ZVAL_COPY(&retsock->zstream, zstream); - php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, - PHP_STREAM_BUFFER_NONE, NULL); - - RETURN_RES(zend_register_resource(retsock, le_socket)); + php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); } /* }}} */ -/* {{{ proto resource socket_export_stream(resource socket) - Exports a socket extension resource into a stream that encapsulates a socket. */ +/* {{{ Exports a socket extension resource into a stream that encapsulates a socket. */ PHP_FUNCTION(socket_export_stream) { zval *zsocket; @@ -2475,17 +2200,17 @@ PHP_FUNCTION(socket_export_stream) char *protocol = NULL; size_t protocollen = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zsocket) == FAILURE) { - return; - } - if ((socket = (php_socket *) zend_fetch_resource(Z_RES_P(zsocket), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zsocket, socket_ce) == FAILURE) { + RETURN_THROWS(); } + socket = Z_SOCKET_P(zsocket); + ENSURE_SOCKET_VALID(socket); + /* Either we already exported a stream or the socket came from an import, * just return the existing stream */ if (!Z_ISUNDEF(socket->zstream)) { - RETURN_ZVAL(&socket->zstream, 1, 0); + RETURN_COPY(&socket->zstream); } /* Determine if socket is using a protocol with one of the default registered @@ -2544,7 +2269,7 @@ PHP_FUNCTION(socket_export_stream) stream = php_stream_sock_open_from_socket(socket->bsd_socket, 0); if (stream == NULL) { - php_error_docref(NULL, E_WARNING, "failed to create stream"); + php_error_docref(NULL, E_WARNING, "Failed to create stream"); RETURN_FALSE; } } @@ -2557,39 +2282,32 @@ PHP_FUNCTION(socket_export_stream) php_stream_to_zval(stream, &socket->zstream); - RETURN_ZVAL(&socket->zstream, 1, 0); + RETURN_COPY(&socket->zstream); } /* }}} */ -/* {{{ proto resource addrinfo socket_addrinfo_lookup(string hostname[, mixed service, array hints]) - Gets array with contents of getaddrinfo about the given hostname. */ +/* {{{ Gets array with contents of getaddrinfo about the given hostname. */ PHP_FUNCTION(socket_addrinfo_lookup) { char *service = NULL; - size_t service_len; + size_t service_len = 0; zend_string *hostname, *key; zval *hint, *zhints = NULL; - struct addrinfo hints, *result, *rp, *res; + struct addrinfo hints, *result, *rp; + php_addrinfo *res; - memset(&hints, 0, sizeof(hints)); - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|sa", &hostname, &service, &service_len, &zhints) == FAILURE) { - RETURN_NULL(); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|s!a", &hostname, &service, &service_len, &zhints) == FAILURE) { + RETURN_THROWS(); } + memset(&hints, 0, sizeof(hints)); + if (zhints) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zhints), key, hint) { if (key) { if (zend_string_equals_literal(key, "ai_flags")) { - zend_long flags = zval_get_long(hint); -#if HAVE_AI_IDN - if (flags & (AI_IDN_ALLOW_UNASSIGNED | AI_IDN_USE_STD3_ASCII_RULES)) { - php_error_docref(NULL, E_DEPRECATED, - "AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES are deprecated"); - } -#endif - hints.ai_flags = flags; + hints.ai_flags = zval_get_long(hint); } else if (zend_string_equals_literal(key, "ai_socktype")) { hints.ai_socktype = zval_get_long(hint); } else if (zend_string_equals_literal(key, "ai_protocol")) { @@ -2597,6 +2315,7 @@ PHP_FUNCTION(socket_addrinfo_lookup) } else if (zend_string_equals_literal(key, "ai_family")) { hints.ai_family = zval_get_long(hint); } else { + /* TODO Promote to warning/error? */ php_error_docref(NULL, E_NOTICE, "Unknown hint %s", ZSTR_VAL(key)); } } @@ -2611,17 +2330,21 @@ PHP_FUNCTION(socket_addrinfo_lookup) for (rp = result; rp != NULL; rp = rp->ai_next) { if (rp->ai_family != AF_UNSPEC) { - res = emalloc(sizeof(struct addrinfo)); - memcpy(res, rp, sizeof(struct addrinfo)); + zval zaddr; + + object_init_ex(&zaddr, address_info_ce); + res = Z_ADDRESS_INFO_P(&zaddr); + + memcpy(&res->addrinfo, rp, sizeof(struct addrinfo)); - res->ai_addr = emalloc(rp->ai_addrlen); - memcpy(res->ai_addr, rp->ai_addr, rp->ai_addrlen); + res->addrinfo.ai_addr = emalloc(rp->ai_addrlen); + memcpy(res->addrinfo.ai_addr, rp->ai_addr, rp->ai_addrlen); if (rp->ai_canonname != NULL) { - res->ai_canonname = estrdup(rp->ai_canonname); + res->addrinfo.ai_canonname = estrdup(rp->ai_canonname); } - add_next_index_resource(return_value, zend_register_resource(res, le_addrinfo)); + add_next_index_zval(return_value, &zaddr); } } @@ -2629,31 +2352,30 @@ PHP_FUNCTION(socket_addrinfo_lookup) } /* }}} */ -/* {{{ proto resource socket_addrinfo_bind(resource addrinfo) - Creates and binds to a socket from a given addrinfo resource */ +/* {{{ Creates and binds to a socket from a given addrinfo resource */ PHP_FUNCTION(socket_addrinfo_bind) { zval *arg1; int retval; - struct addrinfo *ai; + php_addrinfo *ai; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, address_info_ce) == FAILURE) { + RETURN_THROWS(); } - if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) { - RETURN_FALSE; - } + ai = Z_ADDRESS_INFO_P(arg1); + + object_init_ex(return_value, socket_ce); + php_sock = Z_SOCKET_P(return_value); - php_sock = php_create_socket(); - php_sock->bsd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - php_sock->type = ai->ai_family; + php_sock->bsd_socket = socket(ai->addrinfo.ai_family, ai->addrinfo.ai_socktype, ai->addrinfo.ai_protocol); + php_sock->type = ai->addrinfo.ai_family; if (IS_INVALID_SOCKET(php_sock)) { SOCKETS_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Unable to create socket [%d]: %s", errno, sockets_strerror(errno)); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2665,7 +2387,7 @@ PHP_FUNCTION(socket_addrinfo_bind) { // AF_UNIX sockets via getaddrino are not implemented due to security problems close(php_sock->bsd_socket); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2674,52 +2396,49 @@ PHP_FUNCTION(socket_addrinfo_bind) case AF_INET6: #endif { - retval = bind(php_sock->bsd_socket, ai->ai_addr, ai->ai_addrlen); + retval = bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen); break; } default: - php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type); close(php_sock->bsd_socket); - efree(php_sock); - RETURN_FALSE; + zval_ptr_dtor(return_value); + zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6"); + RETURN_THROWS(); } if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to bind address", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to bind address", errno); close(php_sock->bsd_socket); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } - - RETURN_RES(zend_register_resource(php_sock, le_socket)); } /* }}} */ -/* {{{ proto resource socket_addrinfo_connect(resource addrinfo) - Creates and connects to a socket from a given addrinfo resource */ +/* {{{ Creates and connects to a socket from a given addrinfo resource */ PHP_FUNCTION(socket_addrinfo_connect) { zval *arg1; int retval; - struct addrinfo *ai; + php_addrinfo *ai; php_socket *php_sock; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, address_info_ce) == FAILURE) { + RETURN_THROWS(); } - if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) { - RETURN_FALSE; - } + ai = Z_ADDRESS_INFO_P(arg1); - php_sock = php_create_socket(); - php_sock->bsd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - php_sock->type = ai->ai_family; + object_init_ex(return_value, socket_ce); + php_sock = Z_SOCKET_P(return_value); + + php_sock->bsd_socket = socket(ai->addrinfo.ai_family, ai->addrinfo.ai_socktype, ai->addrinfo.ai_protocol); + php_sock->type = ai->addrinfo.ai_family; if (IS_INVALID_SOCKET(php_sock)) { SOCKETS_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Unable to create socket [%d]: %s", errno, sockets_strerror(errno)); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2731,7 +2450,7 @@ PHP_FUNCTION(socket_addrinfo_connect) { // AF_UNIX sockets via getaddrino are not implemented due to security problems close(php_sock->bsd_socket); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2740,72 +2459,67 @@ PHP_FUNCTION(socket_addrinfo_connect) case AF_INET6: #endif { - retval = connect(php_sock->bsd_socket, ai->ai_addr, ai->ai_addrlen); + retval = connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen); break; } default: - php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type); + zend_argument_value_error(1, "socket type must be either AF_UNIX, AF_INET, or AF_INET6"); close(php_sock->bsd_socket); - efree(php_sock); - RETURN_FALSE; + zval_ptr_dtor(return_value); + RETURN_THROWS(); } if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "unable to connect address", errno); + PHP_SOCKET_ERROR(php_sock, "Unable to connect address", errno); close(php_sock->bsd_socket); - efree(php_sock); + zval_ptr_dtor(return_value); RETURN_FALSE; } - - RETURN_RES(zend_register_resource(php_sock, le_socket)); } /* }}} */ -/* {{{ proto resource socket_addrinfo_explain(resource addrinfo) - Creates and connects to a socket from a given addrinfo resource */ +/* {{{ Creates and connects to a socket from a given addrinfo resource */ PHP_FUNCTION(socket_addrinfo_explain) { zval *arg1, sockaddr; - struct addrinfo *ai; + php_addrinfo *ai; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, address_info_ce) == FAILURE) { + RETURN_THROWS(); } - if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) { - RETURN_FALSE; - } + ai = Z_ADDRESS_INFO_P(arg1); array_init(return_value); - add_assoc_long(return_value, "ai_flags", ai->ai_flags); - add_assoc_long(return_value, "ai_family", ai->ai_family); - add_assoc_long(return_value, "ai_socktype", ai->ai_socktype); - add_assoc_long(return_value, "ai_protocol", ai->ai_protocol); - if (ai->ai_canonname != NULL) { - add_assoc_string(return_value, "ai_canonname", ai->ai_canonname); + add_assoc_long(return_value, "ai_flags", ai->addrinfo.ai_flags); + add_assoc_long(return_value, "ai_family", ai->addrinfo.ai_family); + add_assoc_long(return_value, "ai_socktype", ai->addrinfo.ai_socktype); + add_assoc_long(return_value, "ai_protocol", ai->addrinfo.ai_protocol); + if (ai->addrinfo.ai_canonname != NULL) { + add_assoc_string(return_value, "ai_canonname", ai->addrinfo.ai_canonname); } array_init(&sockaddr); - switch(ai->ai_family) { + switch (ai->addrinfo.ai_family) { case AF_INET: { - struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; + struct sockaddr_in *sa = (struct sockaddr_in *) ai->addrinfo.ai_addr; char addr[INET_ADDRSTRLEN]; add_assoc_long(&sockaddr, "sin_port", ntohs((unsigned short) sa->sin_port)); - inet_ntop(ai->ai_family, &sa->sin_addr, addr, sizeof(addr)); + inet_ntop(ai->addrinfo.ai_family, &sa->sin_addr, addr, sizeof(addr)); add_assoc_string(&sockaddr, "sin_addr", addr); break; } #if HAVE_IPV6 case AF_INET6: { - struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; + struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->addrinfo.ai_addr; char addr[INET6_ADDRSTRLEN]; add_assoc_long(&sockaddr, "sin6_port", ntohs((unsigned short) sa->sin6_port)); - inet_ntop(ai->ai_family, &sa->sin6_addr, addr, sizeof(addr)); + inet_ntop(ai->addrinfo.ai_family, &sa->sin6_addr, addr, sizeof(addr)); add_assoc_string(&sockaddr, "sin6_addr", addr); break; } @@ -2818,8 +2532,7 @@ PHP_FUNCTION(socket_addrinfo_explain) #ifdef PHP_WIN32 - /* {{{ proto string socket_wsaprotocol_info_export(resource stream, int target_pid) - Exports the network socket information suitable to be used in another process and returns the info id. */ + /* {{{ Exports the network socket information suitable to be used in another process and returns the info id. */ PHP_FUNCTION(socket_wsaprotocol_info_export) { WSAPROTOCOL_INFO wi; @@ -2829,13 +2542,13 @@ PHP_FUNCTION(socket_wsaprotocol_info_export) zend_string *seg_name; HANDLE map; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &zsocket, &target_pid) == FAILURE) { - return; - } - if ((socket = (php_socket *) zend_fetch_resource(Z_RES_P(zsocket), le_socket_name, le_socket)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zsocket, socket_ce, &target_pid) == FAILURE) { + RETURN_THROWS(); } + socket = Z_SOCKET_P(zsocket); + ENSURE_SOCKET_VALID(socket); + if (SOCKET_ERROR == WSADuplicateSocket(socket->bsd_socket, (DWORD)target_pid, &wi)) { DWORD err = WSAGetLastError(); char *buf = php_win32_error_to_msg(err); @@ -2874,8 +2587,7 @@ PHP_FUNCTION(socket_wsaprotocol_info_export) } /* }}} */ -/* {{{ proto resource socket_wsaprotocol_info_import(string id) - Imports the network socket information using the supplied id and creates a new socket on its base. */ +/* {{{ Imports the network socket information using the supplied id and creates a new socket on its base. */ PHP_FUNCTION(socket_wsaprotocol_info_import) { char *id; @@ -2886,7 +2598,7 @@ PHP_FUNCTION(socket_wsaprotocol_info_import) HANDLE map; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &id, &id_len) == FAILURE) { - return; + RETURN_THROWS(); } map = OpenFileMapping(FILE_MAP_READ, FALSE, id); @@ -2923,25 +2635,24 @@ PHP_FUNCTION(socket_wsaprotocol_info_import) RETURN_FALSE; } - php_sock = php_create_socket(); + object_init_ex(return_value, socket_ce); + php_sock = Z_SOCKET_P(return_value); + php_sock->bsd_socket = sock; php_sock->type = wi.iAddressFamily; php_sock->error = 0; php_sock->blocking = 1; - - RETURN_RES(zend_register_resource(php_sock, le_socket)); } /* }}} */ -/* {{{ proto bool socket_wsaprotocol_info_release(string id) - Frees the exported info and corresponding resources using the supplied id. */ +/* {{{ Frees the exported info and corresponding resources using the supplied id. */ PHP_FUNCTION(socket_wsaprotocol_info_release) { char *id; size_t id_len; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &id, &id_len) == FAILURE) { - return; + RETURN_THROWS(); } RETURN_BOOL(SUCCESS == zend_hash_str_del(&(SOCKETS_G(wsa_info)), id, id_len)); diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php new file mode 100644 index 0000000000..b3f0dcbbc2 --- /dev/null +++ b/ext/sockets/sockets.stub.php @@ -0,0 +1,117 @@ +<?php + +/** @generate-function-entries */ + +final class Socket +{ +} + +final class AddressInfo +{ +} + +function socket_select(?array &$read_fds, ?array &$write_fds, ?array &$except_fds, ?int $tv_sec, int $tv_usec = 0): int|false {} + +function socket_create_listen(int $port, int $backlog = 128): Socket|false {} + +function socket_accept(Socket $socket): Socket|false {} + +function socket_set_nonblock(Socket $socket): bool {} + +function socket_set_block(Socket $socket): bool {} + +function socket_listen(Socket $socket, int $backlog = 0): bool {} + +function socket_close(Socket $socket): void {} + +function socket_write(Socket $socket, string $buf, ?int $length = null): int|false {} + +function socket_read(Socket $socket, int $length, int $type = PHP_BINARY_READ): string|false {} + +/** + * @param string $addr + * @param int $port + */ +function socket_getsockname(Socket $socket, &$addr, &$port = UNKNOWN): bool {} + +/** + * @param string $addr + * @param int $port + */ +function socket_getpeername(Socket $socket, &$addr, &$port = UNKNOWN): bool {} + +function socket_create(int $domain, int $type, int $protocol): Socket|false {} + +function socket_connect(Socket $socket, string $addr, ?int $port = null): bool {} + +function socket_strerror(int $errno): string {} + +function socket_bind(Socket $socket, string $addr, int $port = 0): bool {} + +function socket_recv(Socket $socket, &$buf, int $len, int $flags): int|false {} + +function socket_send(Socket $socket, string $buf, int $len, int $flags): int|false {} + +/** + * @param string $buf + * @param string $name + * @param int $port + */ +function socket_recvfrom(Socket $socket, &$buf, int $len, int $flags, &$name, &$port = UNKNOWN): int|false {} + +function socket_sendto(Socket $socket, string $buf, int $len, int $flags, string $addr, ?int $port = null): int|false {} + +function socket_get_option(Socket $socket, int $level, int $optname): array|int|false {} + +/** @alias socket_get_option */ +function socket_getopt(Socket $socket, int $level, int $optname): array|int|false {} + +/** @param array|string|int $optval */ +function socket_set_option(Socket $socket, int $level, int $optname, $optval): bool {} + +/** + * @param array|string|int $optval + * @alias socket_set_option + */ +function socket_setopt(Socket $socket, int $level, int $optname, $optval): bool {} + +#ifdef HAVE_SOCKETPAIR +/** @param array $fd */ +function socket_create_pair(int $domain, int $type, int $protocol, &$fd): bool|null {} +#endif + +#ifdef HAVE_SHUTDOWN +function socket_shutdown(Socket $socket, int $how = 2): bool {} +#endif + +function socket_last_error(?Socket $socket = null): int {} + +function socket_clear_error(?Socket $socket = null): void {} + +/** @param resource $stream */ +function socket_import_stream($stream): Socket|false {} + +/** @return resource|false */ +function socket_export_stream(Socket $socket) {} + +function socket_sendmsg(Socket $socket, array $msghdr, int $flags = 0): int|false {} + +function socket_recvmsg(Socket $socket, array &$msghdr, int $flags = 0): int|false {} + +function socket_cmsg_space(int $level, int $type, int $n = 0): ?int {} + +function socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = []): array|false {} + +function socket_addrinfo_connect(AddressInfo $addr): Socket|false {} + +function socket_addrinfo_bind(AddressInfo $addr): Socket|false {} + +function socket_addrinfo_explain(AddressInfo $addr): array {} + +#ifdef PHP_WIN32 +function socket_wsaprotocol_info_export(Socket $socket, int $target_pid): string|false {} + +function socket_wsaprotocol_info_import(string $info_id): Socket|false {} + +function socket_wsaprotocol_info_release(string $info_id): bool {} +#endif diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h new file mode 100644 index 0000000000..234b0c7982 --- /dev/null +++ b/ext/sockets/sockets_arginfo.h @@ -0,0 +1,323 @@ +/* This is a generated file, edit the .stub.php file instead. + * Stub hash: 3256069f3943ec6dac1db915d737324962dda7c4 */ + +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_fds, IS_ARRAY, 1) + ZEND_ARG_TYPE_INFO(1, write_fds, IS_ARRAY, 1) + ZEND_ARG_TYPE_INFO(1, except_fds, IS_ARRAY, 1) + ZEND_ARG_TYPE_INFO(0, tv_sec, IS_LONG, 1) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tv_usec, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_create_listen, 0, 1, Socket, MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, backlog, IS_LONG, 0, "128") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_accept, 0, 1, Socket, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_set_nonblock, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) +ZEND_END_ARG_INFO() + +#define arginfo_socket_set_block arginfo_socket_set_nonblock + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_listen, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, backlog, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_close, 0, 1, IS_VOID, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_write, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, buf, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_read, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_LONG, 0, "PHP_BINARY_READ") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_getsockname, 0, 2, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_INFO(1, addr) + ZEND_ARG_INFO(1, port) +ZEND_END_ARG_INFO() + +#define arginfo_socket_getpeername arginfo_socket_getsockname + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_create, 0, 3, Socket, MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, domain, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, protocol, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_connect, 0, 2, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, addr, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_strerror, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, errno, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_bind, 0, 2, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, addr, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_recv, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_INFO(1, buf) + ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_send, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, buf, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_recvfrom, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_INFO(1, buf) + ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) + ZEND_ARG_INFO(1, name) + ZEND_ARG_INFO(1, port) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_sendto, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, buf, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, addr, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_get_option, 0, 3, MAY_BE_ARRAY|MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, level, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, optname, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_socket_getopt arginfo_socket_get_option + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_set_option, 0, 4, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, level, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, optname, IS_LONG, 0) + ZEND_ARG_INFO(0, optval) +ZEND_END_ARG_INFO() + +#define arginfo_socket_setopt arginfo_socket_set_option + +#if defined(HAVE_SOCKETPAIR) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_create_pair, 0, 4, _IS_BOOL, 1) + ZEND_ARG_TYPE_INFO(0, domain, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, protocol, IS_LONG, 0) + ZEND_ARG_INFO(1, fd) +ZEND_END_ARG_INFO() +#endif + +#if defined(HAVE_SHUTDOWN) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_shutdown, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, how, IS_LONG, 0, "2") +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_last_error, 0, 0, IS_LONG, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, socket, Socket, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_clear_error, 0, 0, IS_VOID, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, socket, Socket, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_import_stream, 0, 1, Socket, MAY_BE_FALSE) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_export_stream, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_sendmsg, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, msghdr, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_recvmsg, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(1, msghdr, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_cmsg_space, 0, 2, IS_LONG, 1) + ZEND_ARG_TYPE_INFO(0, level, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, n, IS_LONG, 0, "0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_addrinfo_lookup, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, service, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, hints, IS_ARRAY, 0, "[]") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_addrinfo_connect, 0, 1, Socket, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, addr, AddressInfo, 0) +ZEND_END_ARG_INFO() + +#define arginfo_socket_addrinfo_bind arginfo_socket_addrinfo_connect + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_addrinfo_explain, 0, 1, IS_ARRAY, 0) + ZEND_ARG_OBJ_INFO(0, addr, AddressInfo, 0) +ZEND_END_ARG_INFO() + +#if defined(PHP_WIN32) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_wsaprotocol_info_export, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) + ZEND_ARG_TYPE_INFO(0, target_pid, IS_LONG, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(PHP_WIN32) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_wsaprotocol_info_import, 0, 1, Socket, MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, info_id, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(PHP_WIN32) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_wsaprotocol_info_release, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, info_id, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + + +ZEND_FUNCTION(socket_select); +ZEND_FUNCTION(socket_create_listen); +ZEND_FUNCTION(socket_accept); +ZEND_FUNCTION(socket_set_nonblock); +ZEND_FUNCTION(socket_set_block); +ZEND_FUNCTION(socket_listen); +ZEND_FUNCTION(socket_close); +ZEND_FUNCTION(socket_write); +ZEND_FUNCTION(socket_read); +ZEND_FUNCTION(socket_getsockname); +ZEND_FUNCTION(socket_getpeername); +ZEND_FUNCTION(socket_create); +ZEND_FUNCTION(socket_connect); +ZEND_FUNCTION(socket_strerror); +ZEND_FUNCTION(socket_bind); +ZEND_FUNCTION(socket_recv); +ZEND_FUNCTION(socket_send); +ZEND_FUNCTION(socket_recvfrom); +ZEND_FUNCTION(socket_sendto); +ZEND_FUNCTION(socket_get_option); +ZEND_FUNCTION(socket_set_option); +#if defined(HAVE_SOCKETPAIR) +ZEND_FUNCTION(socket_create_pair); +#endif +#if defined(HAVE_SHUTDOWN) +ZEND_FUNCTION(socket_shutdown); +#endif +ZEND_FUNCTION(socket_last_error); +ZEND_FUNCTION(socket_clear_error); +ZEND_FUNCTION(socket_import_stream); +ZEND_FUNCTION(socket_export_stream); +ZEND_FUNCTION(socket_sendmsg); +ZEND_FUNCTION(socket_recvmsg); +ZEND_FUNCTION(socket_cmsg_space); +ZEND_FUNCTION(socket_addrinfo_lookup); +ZEND_FUNCTION(socket_addrinfo_connect); +ZEND_FUNCTION(socket_addrinfo_bind); +ZEND_FUNCTION(socket_addrinfo_explain); +#if defined(PHP_WIN32) +ZEND_FUNCTION(socket_wsaprotocol_info_export); +#endif +#if defined(PHP_WIN32) +ZEND_FUNCTION(socket_wsaprotocol_info_import); +#endif +#if defined(PHP_WIN32) +ZEND_FUNCTION(socket_wsaprotocol_info_release); +#endif + + +static const zend_function_entry ext_functions[] = { + ZEND_FE(socket_select, arginfo_socket_select) + ZEND_FE(socket_create_listen, arginfo_socket_create_listen) + ZEND_FE(socket_accept, arginfo_socket_accept) + ZEND_FE(socket_set_nonblock, arginfo_socket_set_nonblock) + ZEND_FE(socket_set_block, arginfo_socket_set_block) + ZEND_FE(socket_listen, arginfo_socket_listen) + ZEND_FE(socket_close, arginfo_socket_close) + ZEND_FE(socket_write, arginfo_socket_write) + ZEND_FE(socket_read, arginfo_socket_read) + ZEND_FE(socket_getsockname, arginfo_socket_getsockname) + ZEND_FE(socket_getpeername, arginfo_socket_getpeername) + ZEND_FE(socket_create, arginfo_socket_create) + ZEND_FE(socket_connect, arginfo_socket_connect) + ZEND_FE(socket_strerror, arginfo_socket_strerror) + ZEND_FE(socket_bind, arginfo_socket_bind) + ZEND_FE(socket_recv, arginfo_socket_recv) + ZEND_FE(socket_send, arginfo_socket_send) + ZEND_FE(socket_recvfrom, arginfo_socket_recvfrom) + ZEND_FE(socket_sendto, arginfo_socket_sendto) + ZEND_FE(socket_get_option, arginfo_socket_get_option) + ZEND_FALIAS(socket_getopt, socket_get_option, arginfo_socket_getopt) + ZEND_FE(socket_set_option, arginfo_socket_set_option) + ZEND_FALIAS(socket_setopt, socket_set_option, arginfo_socket_setopt) +#if defined(HAVE_SOCKETPAIR) + ZEND_FE(socket_create_pair, arginfo_socket_create_pair) +#endif +#if defined(HAVE_SHUTDOWN) + ZEND_FE(socket_shutdown, arginfo_socket_shutdown) +#endif + ZEND_FE(socket_last_error, arginfo_socket_last_error) + ZEND_FE(socket_clear_error, arginfo_socket_clear_error) + ZEND_FE(socket_import_stream, arginfo_socket_import_stream) + ZEND_FE(socket_export_stream, arginfo_socket_export_stream) + ZEND_FE(socket_sendmsg, arginfo_socket_sendmsg) + ZEND_FE(socket_recvmsg, arginfo_socket_recvmsg) + ZEND_FE(socket_cmsg_space, arginfo_socket_cmsg_space) + ZEND_FE(socket_addrinfo_lookup, arginfo_socket_addrinfo_lookup) + ZEND_FE(socket_addrinfo_connect, arginfo_socket_addrinfo_connect) + ZEND_FE(socket_addrinfo_bind, arginfo_socket_addrinfo_bind) + ZEND_FE(socket_addrinfo_explain, arginfo_socket_addrinfo_explain) +#if defined(PHP_WIN32) + ZEND_FE(socket_wsaprotocol_info_export, arginfo_socket_wsaprotocol_info_export) +#endif +#if defined(PHP_WIN32) + ZEND_FE(socket_wsaprotocol_info_import, arginfo_socket_wsaprotocol_info_import) +#endif +#if defined(PHP_WIN32) + ZEND_FE(socket_wsaprotocol_info_release, arginfo_socket_wsaprotocol_info_release) +#endif + ZEND_FE_END +}; + + +static const zend_function_entry class_Socket_methods[] = { + ZEND_FE_END +}; + + +static const zend_function_entry class_AddressInfo_methods[] = { + ZEND_FE_END +}; diff --git a/ext/sockets/tests/ai_idn_deprecation.phpt b/ext/sockets/tests/ai_idn_deprecation.phpt deleted file mode 100644 index 02a6965d26..0000000000 --- a/ext/sockets/tests/ai_idn_deprecation.phpt +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES are deprecated ---SKIPIF-- -<?php -if (!extension_loaded('sockets')) die('skip The sockets extension is not loaded'); -if (!defined('AI_IDN_ALLOW_UNASSIGNED')) die('skip AI_IDN_ALLOW_UNASSIGNED not defined'); -?> ---FILE-- -<?php -$addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( - 'ai_family' => AF_INET, - 'ai_socktype' => SOCK_DGRAM, - 'ai_flags' => AI_IDN_ALLOW_UNASSIGNED, -)); -var_dump(socket_addrinfo_connect($addrinfo[0])); -echo "Done"; ---EXPECTF-- -Deprecated: socket_addrinfo_lookup(): AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES are deprecated in %s on line %d -resource(%d) of type (Socket) -Done diff --git a/ext/sockets/tests/bug76839.phpt b/ext/sockets/tests/bug76839.phpt index d63370cc31..49aff731f7 100644 --- a/ext/sockets/tests/bug76839.phpt +++ b/ext/sockets/tests/bug76839.phpt @@ -12,7 +12,7 @@ if (!extension_loaded('sockets')) { <?php // This bug only occurs when a specific portion of memory is unclean. -// Unforunately, looping around 10 times and using random paths is the +// Unfortunately, looping around 10 times and using random paths is the // best way I could manage to reproduce this problem without modifying php itself :-/ for ($i = 0; $i < 10; $i++) { diff --git a/ext/sockets/tests/ipv4loop.phpt b/ext/sockets/tests/ipv4loop.phpt index 7d72992012..4e5d15453b 100644 --- a/ext/sockets/tests/ipv4loop.phpt +++ b/ext/sockets/tests/ipv4loop.phpt @@ -8,45 +8,45 @@ IPv4 Loopback test ?> --FILE-- <?php - /* Setup socket server */ - $server = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); - if (!$server) { - die('Unable to create AF_INET socket [server]'); - } - - if (!socket_bind($server, '127.0.0.1', 0)) { - die("Unable to bind to 127.0.0.1"); - } - - if (!socket_listen($server, 2)) { - die('Unable to listen on socket'); - } - - socket_getsockname($server, $unused, $port); - - /* Connect to it */ - $client = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); - if (!$client) { - die('Unable to create AF_INET socket [client]'); - } - if (!socket_connect($client, '127.0.0.1', $port)) { - die('Unable to connect to server socket'); - } - - /* Accept that connection */ - $socket = socket_accept($server); - if (!$socket) { - die('Unable to accept connection'); - } - - socket_write($client, "ABCdef123\n"); - - $data = socket_read($socket, 10, PHP_BINARY_READ); - var_dump($data); - - socket_close($client); - socket_close($socket); - socket_close($server); + /* Setup socket server */ + $server = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); + if (!$server) { + die('Unable to create AF_INET socket [server]'); + } + + if (!socket_bind($server, '127.0.0.1', 0)) { + die("Unable to bind to 127.0.0.1"); + } + + if (!socket_listen($server, 2)) { + die('Unable to listen on socket'); + } + + socket_getsockname($server, $unused, $port); + + /* Connect to it */ + $client = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); + if (!$client) { + die('Unable to create AF_INET socket [client]'); + } + if (!socket_connect($client, '127.0.0.1', $port)) { + die('Unable to connect to server socket'); + } + + /* Accept that connection */ + $socket = socket_accept($server); + if (!$socket) { + die('Unable to accept connection'); + } + + socket_write($client, "ABCdef123\n"); + + $data = socket_read($socket, 10, PHP_BINARY_READ); + var_dump($data); + + socket_close($client); + socket_close($socket); + socket_close($server); ?> --EXPECT-- string(10) "ABCdef123 diff --git a/ext/sockets/tests/ipv6_skipif.inc b/ext/sockets/tests/ipv6_skipif.inc index 8c723a0b20..b2a28bfb02 100644 --- a/ext/sockets/tests/ipv6_skipif.inc +++ b/ext/sockets/tests/ipv6_skipif.inc @@ -1,7 +1,7 @@ <?php if (getenv("CI_NO_IPV6") || !defined("AF_INET6")) { - die('skip no IPv6 support'); + die('skip no IPv6 support'); } if (@stream_socket_client('udp://[::1]:8888') === false) - die('skip no IPv6 support'); + die('skip no IPv6 support'); diff --git a/ext/sockets/tests/ipv6loop.phpt b/ext/sockets/tests/ipv6loop.phpt index 24e2b6d4f6..109da5bc2d 100644 --- a/ext/sockets/tests/ipv6loop.phpt +++ b/ext/sockets/tests/ipv6loop.phpt @@ -9,48 +9,48 @@ IPv6 Loopback test ?> --FILE-- <?php - /* Setup socket server */ - $server = socket_create(AF_INET6, SOCK_STREAM, getprotobyname('tcp')); - if (!$server) { - die('Unable to create AF_INET6 socket [server]'); - } - $bound = false; - for($port = 31337; $port < 31357; ++$port) { - if (@socket_bind($server, '::1', $port)) { - $bound = true; - break; - } - } - if (!$bound) { - die("Unable to bind to [::1]:$port"); - } - if (!socket_listen($server, 2)) { - die('Unable to listen on socket'); - } + /* Setup socket server */ + $server = socket_create(AF_INET6, SOCK_STREAM, getprotobyname('tcp')); + if (!$server) { + die('Unable to create AF_INET6 socket [server]'); + } + $bound = false; + for($port = 31337; $port < 31357; ++$port) { + if (@socket_bind($server, '::1', $port)) { + $bound = true; + break; + } + } + if (!$bound) { + die("Unable to bind to [::1]:$port"); + } + if (!socket_listen($server, 2)) { + die('Unable to listen on socket'); + } - /* Connect to it */ - $client = socket_create(AF_INET6, SOCK_STREAM, getprotobyname('tcp')); - if (!$client) { - die('Unable to create AF_INET6 socket [client]'); - } - if (!socket_connect($client, '::1', $port)) { - die('Unable to connect to server socket'); - } + /* Connect to it */ + $client = socket_create(AF_INET6, SOCK_STREAM, getprotobyname('tcp')); + if (!$client) { + die('Unable to create AF_INET6 socket [client]'); + } + if (!socket_connect($client, '::1', $port)) { + die('Unable to connect to server socket'); + } - /* Accept that connection */ - $socket = socket_accept($server); - if (!$socket) { - die('Unable to accept connection'); - } + /* Accept that connection */ + $socket = socket_accept($server); + if (!$socket) { + die('Unable to accept connection'); + } - socket_write($client, "ABCdef123\n"); + socket_write($client, "ABCdef123\n"); - $data = socket_read($socket, 10, PHP_BINARY_READ); - var_dump($data); + $data = socket_read($socket, 10, PHP_BINARY_READ); + var_dump($data); - socket_close($client); - socket_close($socket); - socket_close($server); + socket_close($client); + socket_close($socket); + socket_close($server); ?> --EXPECT-- string(10) "ABCdef123 diff --git a/ext/sockets/tests/mcast_helpers.php.inc b/ext/sockets/tests/mcast_helpers.php.inc index ad65a3f9d6..7b73a9d77a 100644 --- a/ext/sockets/tests/mcast_helpers.php.inc +++ b/ext/sockets/tests/mcast_helpers.php.inc @@ -1,8 +1,8 @@ <?php function checktimeout($sock, $limit) { - $readfs = array($sock); - $writefs = $exceptfs = array(); - if (socket_select($readfs, $writefs, $exceptfs, 0, $limit*1000) != 1) { - die("Socket read timeout hit. Can be a bug, a test bug, or a firewall issue."); - } + $readfs = array($sock); + $writefs = $exceptfs = array(); + if (socket_select($readfs, $writefs, $exceptfs, 0, $limit*1000) != 1) { + die("Socket read timeout hit. Can be a bug, a test bug, or a firewall issue."); + } } diff --git a/ext/sockets/tests/mcast_ipv4_recv.phpt b/ext/sockets/tests/mcast_ipv4_recv.phpt index f56b21a2fa..28237f415e 100644 --- a/ext/sockets/tests/mcast_ipv4_recv.phpt +++ b/ext/sockets/tests/mcast_ipv4_recv.phpt @@ -8,7 +8,7 @@ if (!extension_loaded('sockets')) { if (getenv('SKIP_ONLINE_TESTS')) die('skip online test'); $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); $br = socket_bind($s, '0.0.0.0', 3000); -$so = socket_set_option($s, IPPROTO_IP, MCAST_JOIN_GROUP, array( +$so = @socket_set_option($s, IPPROTO_IP, MCAST_JOIN_GROUP, array( "group" => '224.0.0.23', "interface" => 'lo', )); @@ -43,8 +43,8 @@ $br = socket_bind($s, '0.0.0.0', 3000); var_dump($br); $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, + "group" => $mcastaddr, + "interface" => $interface, )); var_dump($so); @@ -54,101 +54,101 @@ var_dump($r); $i = 0; checktimeout($s, 500); while (($str = socket_read($s, 3000)) !== FALSE) { - $i++; - echo "$i> ", $str, "\n"; + $i++; + echo "$i> ", $str, "\n"; if ($i == 1) { - echo "leaving group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); - var_dump($r); + echo "leaving group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); + var_dump($r); } if ($i == 2) { - echo "re-joining group\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends2, $m = "ignored mcast packet (different interface)", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "re-joining group\n"; + $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends2, $m = "ignored mcast packet (different interface)", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 3) { - echo "blocking source\n"; - $so = socket_set_option($s, $level, MCAST_BLOCK_SOURCE, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored packet (blocked source)", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); - var_dump($r); + echo "blocking source\n"; + $so = socket_set_option($s, $level, MCAST_BLOCK_SOURCE, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored packet (blocked source)", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); + var_dump($r); } if ($i == 4) { - echo "unblocking source\n"; - $so = socket_set_option($s, $level, MCAST_UNBLOCK_SOURCE, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "mcast packet from 127.0.0.1", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "unblocking source\n"; + $so = socket_set_option($s, $level, MCAST_UNBLOCK_SOURCE, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "mcast packet from 127.0.0.1", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 5) { - echo "leaving group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); - var_dump($r); + echo "leaving group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); + var_dump($r); } if ($i == 6) { - echo "joining source group\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "mcast packet from 127.0.0.1", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "joining source group\n"; + $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "mcast packet from 127.0.0.1", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 7) { - echo "leaving source group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); - var_dump($r); + echo "leaving source group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "127.0.0.1", 3000); + var_dump($r); } if ($i == 8) { /* echo "rjsg\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so);*/ - break; + $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so);*/ + break; } } @@ -158,7 +158,8 @@ bool(true) creating unbound socket and hoping the routing table causes an interface other than lo to be used for sending messages to 224.0.0.23 bool(true) creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) bool(true) int(14) diff --git a/ext/sockets/tests/mcast_ipv4_send_error.phpt b/ext/sockets/tests/mcast_ipv4_send_error.phpt index 91063f4253..5d254c6843 100644 --- a/ext/sockets/tests/mcast_ipv4_send_error.phpt +++ b/ext/sockets/tests/mcast_ipv4_send_error.phpt @@ -38,8 +38,12 @@ echo "\n"; echo "Setting IP_MULTICAST_TTL with 256\n"; //if we had a simple cast to unsigned char, this would be the same as 0 -$r = socket_set_option($s, $level, IP_MULTICAST_TTL, 256); -var_dump($r); +try { + $r = socket_set_option($s, $level, IP_MULTICAST_TTL, 256); + var_dump($r); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} $r = socket_get_option($s, $level, IP_MULTICAST_TTL); var_dump($r); echo "\n"; @@ -53,12 +57,16 @@ echo "\n"; echo "Setting IP_MULTICAST_TTL with -1\n"; //should give error, not be the same as 255 -$r = socket_set_option($s, $level, IP_MULTICAST_TTL, -1); -var_dump($r); +try { + $r = socket_set_option($s, $level, IP_MULTICAST_TTL, -1); + var_dump($r); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} $r = socket_get_option($s, $level, IP_MULTICAST_TTL); var_dump($r); echo "\n"; ---EXPECTF-- +--EXPECT-- Setting IP_MULTICAST_LOOP with 256 bool(true) int(1) @@ -68,9 +76,7 @@ bool(true) int(0) Setting IP_MULTICAST_TTL with 256 - -Warning: socket_set_option(): Expected a value between 0 and 255 in %s on line %d -bool(false) +socket_set_option(): Argument #4 ($optval) must be between 0 and 255 int(1) Setting IP_MULTICAST_TTL with "254" @@ -78,7 +84,5 @@ bool(true) int(254) Setting IP_MULTICAST_TTL with -1 - -Warning: socket_set_option(): Expected a value between 0 and 255 in %s on line %d -bool(false) +socket_set_option(): Argument #4 ($optval) must be between 0 and 255 int(254) diff --git a/ext/sockets/tests/mcast_ipv6_recv.phpt b/ext/sockets/tests/mcast_ipv6_recv.phpt index 62fa1a9c4d..3bc791a451 100644 --- a/ext/sockets/tests/mcast_ipv6_recv.phpt +++ b/ext/sockets/tests/mcast_ipv6_recv.phpt @@ -63,8 +63,8 @@ $br = socket_bind($s, '::0', 3000) or die("err"); var_dump($br); $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, + "group" => $mcastaddr, + "interface" => $interface, )) or die("err"); var_dump($so); @@ -81,108 +81,110 @@ var_dump($r); $i = 0; checktimeout($s, 500); while (($str = socket_read($s, 3000)) !== FALSE) { - $i++; - echo "$i> ", $str, "\n"; + $i++; + echo "$i> ", $str, "\n"; if ($i == 1) { - echo "leaving group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); - var_dump($r); + echo "leaving group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); + var_dump($r); } if ($i == 2) { - echo "re-joining group\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "re-joining group\n"; + $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 3) { - echo "blocking source\n"; - $so = socket_set_option($s, $level, MCAST_BLOCK_SOURCE, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored packet (blocked source)", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); - var_dump($r); + echo "blocking source\n"; + $so = socket_set_option($s, $level, MCAST_BLOCK_SOURCE, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored packet (blocked source)", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); + var_dump($r); } if ($i == 4) { - echo "unblocking source\n"; - $so = socket_set_option($s, $level, MCAST_UNBLOCK_SOURCE, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "unblocking source\n"; + $so = socket_set_option($s, $level, MCAST_UNBLOCK_SOURCE, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 5) { - echo "leaving group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); - var_dump($r); + echo "leaving group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); + var_dump($r); } if ($i == 6) { - echo "joining source group\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "mcast packet from desired source", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "joining source group\n"; + $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "mcast packet from desired source", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 7) { - echo "leaving source group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); - var_dump($r); + echo "leaving source group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_SOURCE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); + var_dump($r); } if ($i == 8) { - /*echo "joining source group\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - "source" => $sblock, - )); - var_dump($so);*/ - break; + /*echo "joining source group\n"; + $so = socket_set_option($s, $level, MCAST_JOIN_SOURCE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + "source" => $sblock, + )); + var_dump($so);*/ + break; } } --EXPECTF-- creating send socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) bool(true) int(14) diff --git a/ext/sockets/tests/mcast_ipv6_recv_limited.phpt b/ext/sockets/tests/mcast_ipv6_recv_limited.phpt index c739264062..dda3756b7e 100644 --- a/ext/sockets/tests/mcast_ipv6_recv_limited.phpt +++ b/ext/sockets/tests/mcast_ipv6_recv_limited.phpt @@ -58,8 +58,8 @@ $br = socket_bind($s, '::0', 3000) or die("err"); var_dump($br); $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, + "group" => $mcastaddr, + "interface" => $interface, )) or die("err"); var_dump($so); @@ -76,41 +76,43 @@ var_dump($r); $i = 0; checktimeout($s, 500); while (($str = socket_read($s, 3000, 500)) !== FALSE) { - $i++; - echo "$i> ", $str, "\n"; + $i++; + echo "$i> ", $str, "\n"; if ($i == 1) { - echo "leaving group\n"; - $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); - $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); - var_dump($r); + echo "leaving group\n"; + $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); + $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000); + var_dump($r); } if ($i == 2) { - echo "re-joining group\n"; - $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( - "group" => $mcastaddr, - "interface" => $interface, - )); - var_dump($so); - $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); - var_dump($r); + echo "re-joining group\n"; + $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array( + "group" => $mcastaddr, + "interface" => $interface, + )); + var_dump($so); + $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000); + var_dump($r); } if ($i == 3) { - break; + break; } } --EXPECTF-- creating send socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) bool(true) int(14) diff --git a/ext/sockets/tests/socket_abstract_path.phpt b/ext/sockets/tests/socket_abstract_path.phpt index 4c89dc4238..bbe4debeaa 100644 --- a/ext/sockets/tests/socket_abstract_path.phpt +++ b/ext/sockets/tests/socket_abstract_path.phpt @@ -28,8 +28,8 @@ socket_connect($clients, $path) or die("Error connecting"); $conns = socket_accept($servers) or die("Could not accept connection"); $r = socket_sendmsg($clients, [ - //"name" => [ "addr" => $path, ], - "iov" => ["test ", "thing", "\n"], + //"name" => [ "addr" => $path, ], + "iov" => ["test ", "thing", "\n"], ], 0); var_dump($r); checktimeout($conns, 500); diff --git a/ext/sockets/tests/socket_abstract_path_sendmsg.phpt b/ext/sockets/tests/socket_abstract_path_sendmsg.phpt index e8499e021c..ca9ab3f534 100644 --- a/ext/sockets/tests/socket_abstract_path_sendmsg.phpt +++ b/ext/sockets/tests/socket_abstract_path_sendmsg.phpt @@ -24,8 +24,8 @@ $s = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err"); socket_bind($s, $path) or die("err"); $r = socket_sendmsg($sends1, [ - "name" => [ "path" => $path], - "iov" => ["test ", "thing", "\n"], + "name" => [ "path" => $path], + "iov" => ["test ", "thing", "\n"], ], 0); var_dump($r); checktimeout($s, 500); diff --git a/ext/sockets/tests/socket_addrinfo_bind.phpt b/ext/sockets/tests/socket_addrinfo_bind.phpt index eb15afee25..40a746bdb9 100644 --- a/ext/sockets/tests/socket_addrinfo_bind.phpt +++ b/ext/sockets/tests/socket_addrinfo_bind.phpt @@ -13,6 +13,7 @@ $addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( )); var_dump(socket_addrinfo_bind($addrinfo[0])); echo "Done"; ---EXPECTF-- -resource(%d) of type (Socket) +--EXPECT-- +object(Socket)#2 (0) { +} Done diff --git a/ext/sockets/tests/socket_addrinfo_connect.phpt b/ext/sockets/tests/socket_addrinfo_connect.phpt index 009d54839b..a5a604ee61 100644 --- a/ext/sockets/tests/socket_addrinfo_connect.phpt +++ b/ext/sockets/tests/socket_addrinfo_connect.phpt @@ -13,6 +13,7 @@ $addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( )); var_dump(socket_addrinfo_connect($addrinfo[0])); echo "Done"; ---EXPECTF-- -resource(%d) of type (Socket) +--EXPECT-- +object(Socket)#2 (0) { +} Done diff --git a/ext/sockets/tests/socket_addrinfo_lookup.phpt b/ext/sockets/tests/socket_addrinfo_lookup.phpt index 5ecd945f71..8393eaa7ef 100644 --- a/ext/sockets/tests/socket_addrinfo_lookup.phpt +++ b/ext/sockets/tests/socket_addrinfo_lookup.phpt @@ -16,5 +16,6 @@ var_dump($addrinfo[0]); echo "Done"; --EXPECTF-- Notice: socket_addrinfo_lookup(): Unknown hint invalid in %ssocket_addrinfo_lookup.php on line %d -resource(%d) of type (AddressInfo) +object(AddressInfo)#%d (0) { +} Done diff --git a/ext/sockets/tests/socket_cmsg_credentials.phpt b/ext/sockets/tests/socket_cmsg_credentials.phpt index 09266e6cbd..33f770510f 100644 --- a/ext/sockets/tests/socket_cmsg_credentials.phpt +++ b/ext/sockets/tests/socket_cmsg_credentials.phpt @@ -58,9 +58,11 @@ $pid = getmypid(); var_dump($data['control'][0]['data']['pid'] === $pid); --EXPECTF-- creating send socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) int(5) Array diff --git a/ext/sockets/tests/socket_cmsg_rights.phpt b/ext/sockets/tests/socket_cmsg_rights.phpt index bd758abdf9..7c7334ffca 100644 --- a/ext/sockets/tests/socket_cmsg_rights.phpt +++ b/ext/sockets/tests/socket_cmsg_rights.phpt @@ -79,9 +79,11 @@ if ($data["control"]) { } --EXPECTF-- creating send socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) int(11) array(3) { diff --git a/ext/sockets/tests/socket_connect_params.phpt b/ext/sockets/tests/socket_connect_params.phpt index 45ff56d031..608e5d1c2e 100644 --- a/ext/sockets/tests/socket_connect_params.phpt +++ b/ext/sockets/tests/socket_connect_params.phpt @@ -16,19 +16,22 @@ $s_c = socket_create_listen(0); socket_getsockname($s_c, $addr, $port); // wrong parameter count -$s_w = socket_connect(); -$s_w = socket_connect($s_c); -$s_w = socket_connect($s_c, '0.0.0.0'); +try { + socket_connect($s_c); +} catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + socket_connect($s_c, '0.0.0.0'); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} $s_w = socket_connect($s_c, '0.0.0.0', $port); socket_close($s_c); - ?> --EXPECTF-- -Warning: socket_connect() expects at least 2 parameters, 0 given in %s on line %d - -Warning: socket_connect() expects at least 2 parameters, 1 given in %s on line %d - -Warning: socket_connect(): Socket of type AF_INET requires 3 arguments in %s on line %d +socket_connect() expects at least 2 parameters, 1 given +socket_connect(): Argument #3 ($port) cannot be null when the socket type is AF_INET Warning: socket_connect(): unable to connect [%i]: %a in %s on line %d diff --git a/ext/sockets/tests/socket_create_listen_used.phpt b/ext/sockets/tests/socket_create_listen_used.phpt index b41e2caefc..5e5c587188 100644 --- a/ext/sockets/tests/socket_create_listen_used.phpt +++ b/ext/sockets/tests/socket_create_listen_used.phpt @@ -18,13 +18,11 @@ fa@php.net // default invocation $s_c_l2 = socket_create_listen(31330+$rand); var_dump($s_c_l2); - socket_close($s_c_l2); socket_close($s_c_l); ?> --EXPECTF-- -resource(%i) of type (Socket) +object(Socket)#%d (0) { +} Warning: socket_create_listen(): unable to bind to given address [%i]: %a in %s on line %d bool(false) - -Warning: socket_close() expects parameter 1 to be resource, bool given in %s on line %d diff --git a/ext/sockets/tests/socket_create_pair-wrongparams-win32.phpt b/ext/sockets/tests/socket_create_pair-wrongparams-win32.phpt index 554819ac99..de939f6657 100644 --- a/ext/sockets/tests/socket_create_pair-wrongparams-win32.phpt +++ b/ext/sockets/tests/socket_create_pair-wrongparams-win32.phpt @@ -10,29 +10,24 @@ if (!extension_loaded('sockets')) { } --FILE-- <?php -var_dump(socket_create_pair(AF_INET, null, null)); - -$domain = 'unknown'; -var_dump(socket_create_pair($domain, SOCK_STREAM, 0, $sockets)); var_dump(socket_create_pair(AF_INET, null, null, $sockets)); -var_dump(socket_create_pair(31337, null, null, $sockets)); - -var_dump(socket_create_pair(AF_INET, 31337, 0, $sockets)); ---EXPECTF-- -Warning: socket_create_pair() expects exactly 4 parameters, 3 given in %s on line %d -NULL - -Warning: socket_create_pair() expects parameter 1 to be int, string given in %s on line %d -NULL -bool(true) - -Warning: socket_create_pair(): invalid socket domain [31337] specified for argument 1, assuming AF_INET in %s on line %d -bool(true) +try { + var_dump(socket_create_pair(31337, null, null, $sockets)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} -Warning: socket_create_pair(): invalid socket type [31337] specified for argument 2, assuming SOCK_STREAM in %s on line %d +try { + var_dump(socket_create_pair(AF_INET, 31337, 0, $sockets)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +--EXPECT-- bool(true) +socket_create_pair(): Argument #1 ($domain) must be either AF_UNIX, AF_INET6 or AF_INET +socket_create_pair(): Argument #2 ($type) must be either SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM --CREDITS-- Till Klampaeckel, till@php.net Berlin TestFest 2009 diff --git a/ext/sockets/tests/socket_create_pair-wrongparams.phpt b/ext/sockets/tests/socket_create_pair-wrongparams.phpt index 856d2cdc52..7adbc91d8a 100644 --- a/ext/sockets/tests/socket_create_pair-wrongparams.phpt +++ b/ext/sockets/tests/socket_create_pair-wrongparams.phpt @@ -10,35 +10,27 @@ if (!extension_loaded('sockets')) { } --FILE-- <?php -var_dump(socket_create_pair(AF_INET, null, null)); - -$domain = 'unknown'; -var_dump(socket_create_pair($domain, SOCK_STREAM, 0, $sockets)); var_dump(socket_create_pair(AF_INET, null, null, $sockets)); -var_dump(socket_create_pair(31337, null, null, $sockets)); - -var_dump(socket_create_pair(AF_INET, 31337, 0, $sockets)); ---EXPECTF-- -Warning: socket_create_pair() expects exactly 4 parameters, 3 given in %s on line %d -NULL - -Warning: socket_create_pair() expects parameter 1 to be int, string given in %s on line %d -NULL - -Warning: socket_create_pair(): unable to create socket pair [%d]: %s not supported in %s on line %d -bool(false) - -Warning: socket_create_pair(): invalid socket domain [31337] specified for argument 1, assuming AF_INET in %s on line %d - -Warning: socket_create_pair(): unable to create socket pair [%d]: %s not supported in %s on line %d -bool(false) +try { + var_dump(socket_create_pair(31337, null, null, $sockets)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} -Warning: socket_create_pair(): invalid socket type [31337] specified for argument 2, assuming SOCK_STREAM in %s on line %d +try { + var_dump(socket_create_pair(AF_INET, 31337, 0, $sockets)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} -Warning: socket_create_pair(): unable to create socket pair [%d]: %s not supported %s on line %d +?> +--EXPECTF-- +Warning: socket_create_pair(): Unable to create socket pair [%d]: %s not supported in %s on line %d bool(false) +socket_create_pair(): Argument #1 ($domain) must be either AF_UNIX, AF_INET6 or AF_INET +socket_create_pair(): Argument #2 ($type) must be either SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM --CREDITS-- Till Klampaeckel, till@php.net Berlin TestFest 2009 diff --git a/ext/sockets/tests/socket_create_pair.phpt b/ext/sockets/tests/socket_create_pair.phpt index 6af6e42f20..604d5a2319 100644 --- a/ext/sockets/tests/socket_create_pair.phpt +++ b/ext/sockets/tests/socket_create_pair.phpt @@ -18,7 +18,9 @@ var_dump($sockets); --EXPECT-- array(2) { [0]=> - resource(4) of type (Socket) + object(Socket)#1 (0) { + } [1]=> - resource(5) of type (Socket) + object(Socket)#2 (0) { + } } diff --git a/ext/sockets/tests/socket_export_stream-2.phpt b/ext/sockets/tests/socket_export_stream-2.phpt index 6d5835e4a5..503db5b004 100644 --- a/ext/sockets/tests/socket_export_stream-2.phpt +++ b/ext/sockets/tests/socket_export_stream-2.phpt @@ -8,39 +8,32 @@ if (!extension_loaded('sockets')) { --FILE-- <?php -var_dump(socket_export_stream()); -var_dump(socket_export_stream(1, 2)); -var_dump(socket_export_stream(1)); -var_dump(socket_export_stream(new stdclass)); -var_dump(socket_export_stream(fopen(__FILE__, "rb"))); -var_dump(socket_export_stream(stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND))); +try { + socket_export_stream(fopen(__FILE__, "rb")); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + socket_export_stream(stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); var_dump($s); socket_close($s); -var_dump(socket_export_stream($s)); +try { + var_dump(socket_export_stream($s)); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} echo "Done."; +?> --EXPECTF-- -Warning: socket_export_stream() expects exactly 1 parameter, 0 given in %s on line %d -NULL - -Warning: socket_export_stream() expects exactly 1 parameter, 2 given in %s on line %d -NULL - -Warning: socket_export_stream() expects parameter 1 to be resource, int given in %s on line %d -NULL - -Warning: socket_export_stream() expects parameter 1 to be resource, object given in %s on line %d -NULL - -Warning: socket_export_stream(): supplied resource is not a valid Socket resource in %s on line %d -bool(false) - -Warning: socket_export_stream(): supplied resource is not a valid Socket resource in %s on line %d -bool(false) -resource(%d) of type (Socket) - -Warning: socket_export_stream(): supplied resource is not a valid Socket resource in %s on line %d -bool(false) +socket_export_stream(): Argument #1 ($socket) must be of type Socket, resource given +socket_export_stream(): Argument #1 ($socket) must be of type Socket, resource given +object(Socket)#%d (0) { +} +socket_export_stream(): Argument #1 ($socket) has already been closed Done. diff --git a/ext/sockets/tests/socket_export_stream-3.phpt b/ext/sockets/tests/socket_export_stream-3.phpt index 69b0ebe47d..ed3b7f83e5 100644 --- a/ext/sockets/tests/socket_export_stream-3.phpt +++ b/ext/sockets/tests/socket_export_stream-3.phpt @@ -6,7 +6,7 @@ if (!extension_loaded('sockets')) { die('SKIP sockets extension not available.'); } $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); -$br = socket_bind($s, '0.0.0.0', 58393); +$br = @socket_bind($s, '0.0.0.0', 58393); if ($br === false) die("SKIP IPv4/port 58393 not available"); $so = @socket_set_option($s, IPPROTO_IP, MCAST_JOIN_GROUP, array( @@ -23,8 +23,8 @@ socket_bind($sock, '0.0.0.0', 58393); $stream = socket_export_stream($sock); var_dump($stream); $so = socket_set_option($sock, IPPROTO_IP, MCAST_JOIN_GROUP, array( - "group" => '224.0.0.23', - "interface" => "lo", + "group" => '224.0.0.23', + "interface" => "lo", )); var_dump($so); @@ -40,7 +40,8 @@ echo "Done.\n"; --EXPECTF-- resource(%d) of type (stream) bool(true) -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} int(10) string(10) "my message" Done. diff --git a/ext/sockets/tests/socket_export_stream-4-win.phpt b/ext/sockets/tests/socket_export_stream-4-win.phpt index 3b80092c18..a1899d3eff 100644 --- a/ext/sockets/tests/socket_export_stream-4-win.phpt +++ b/ext/sockets/tests/socket_export_stream-4-win.phpt @@ -12,20 +12,32 @@ if(substr(PHP_OS, 0, 3) != 'WIN' ) { <?php function test($stream, $sock) { - if ($stream !== null) { - echo "stream_set_blocking "; - print_r(stream_set_blocking($stream, 0)); - echo "\n"; - } - if ($sock !== null) { - echo "socket_set_block "; - print_r(socket_set_block($sock)); - echo "\n"; - echo "socket_get_option "; - print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); - echo "\n"; - } - echo "\n"; + if ($stream !== null) { + echo "stream_set_blocking "; + try { + print_r(stream_set_blocking($stream, 0)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + if ($sock !== null) { + echo "socket_set_block "; + try { + print_r(socket_set_block($sock)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + echo "socket_get_option "; + try { + print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + echo "\n"; } echo "normal\n"; @@ -61,8 +73,6 @@ socket_bind($sock4, '0.0.0.0', 0); $stream4 = socket_export_stream($sock4); socket_close($sock4); test($stream4, $sock4); - -echo "Done.\n"; --EXPECTF-- normal stream_set_blocking 1 @@ -80,28 +90,21 @@ stream_set_blocking 1 close stream -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource socket_set_block Warning: socket_set_block(): unable to set blocking mode [%d]: An operation was attempted on something that is not a socket. in %s on line %d socket_get_option -Warning: socket_get_option(): unable to retrieve socket option [%d]: An operation was attempted on something that is not a socket. +Warning: socket_get_option(): Unable to retrieve socket option [%d]: An operation was attempted on something that is not a socket. in %s on line %d close socket -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d - -socket_set_block -Warning: socket_set_block(): supplied resource is not a valid Socket resource in %s on line %d - -socket_get_option -Warning: socket_get_option(): supplied resource is not a valid Socket resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource +socket_set_block Error: socket_set_block(): Argument #1 ($socket) has already been closed -Done. +socket_get_option Error: socket_get_option(): Argument #1 ($socket) has already been closed diff --git a/ext/sockets/tests/socket_export_stream-4.phpt b/ext/sockets/tests/socket_export_stream-4.phpt index 169d690a39..7a38ba9129 100644 --- a/ext/sockets/tests/socket_export_stream-4.phpt +++ b/ext/sockets/tests/socket_export_stream-4.phpt @@ -12,20 +12,32 @@ if(substr(PHP_OS, 0, 3) == 'WIN' ) { <?php function test($stream, $sock) { - if ($stream !== null) { - echo "stream_set_blocking "; - print_r(stream_set_blocking($stream, 0)); - echo "\n"; - } - if ($sock !== null) { - echo "socket_set_block "; - print_r(socket_set_block($sock)); - echo "\n"; - echo "socket_get_option "; - print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); - echo "\n"; - } - echo "\n"; + if ($stream !== null) { + echo "stream_set_blocking "; + try { + print_r(stream_set_blocking($stream, 0)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + if ($sock !== null) { + echo "socket_set_block "; + try { + print_r(socket_set_block($sock)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + echo "socket_get_option "; + try { + print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + echo "\n"; } echo "normal\n"; @@ -80,26 +92,22 @@ stream_set_blocking 1 close stream -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource socket_set_block Warning: socket_set_block(): unable to set blocking mode [%d]: %s in %s on line %d socket_get_option -Warning: socket_get_option(): unable to retrieve socket option [%d]: %s in %s on line %d +Warning: socket_get_option(): Unable to retrieve socket option [%d]: %s in %s on line %d close socket -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource -socket_set_block -Warning: socket_set_block(): supplied resource is not a valid Socket resource in %s on line %d +socket_set_block Error: socket_set_block(): Argument #1 ($socket) has already been closed -socket_get_option -Warning: socket_get_option(): supplied resource is not a valid Socket resource in %s on line %d +socket_get_option Error: socket_get_option(): Argument #1 ($socket) has already been closed Done. diff --git a/ext/sockets/tests/socket_export_stream-5.phpt b/ext/sockets/tests/socket_export_stream-5.phpt index 5a1d03fa6e..219fec5574 100644 --- a/ext/sockets/tests/socket_export_stream-5.phpt +++ b/ext/sockets/tests/socket_export_stream-5.phpt @@ -7,6 +7,9 @@ if (!extension_loaded('sockets')) { } if (!function_exists('zend_leak_variable')) die('SKIP only for debug builds'); +?> +--INI-- +report_memleaks=0 --FILE-- <?php diff --git a/ext/sockets/tests/socket_getpeername_ipv4loop.phpt b/ext/sockets/tests/socket_getpeername_ipv4loop.phpt index c7eb1003e0..0c242e75c1 100644 --- a/ext/sockets/tests/socket_getpeername_ipv4loop.phpt +++ b/ext/sockets/tests/socket_getpeername_ipv4loop.phpt @@ -11,8 +11,8 @@ Tatjana Andersen tatjana.andersen@redpill-linpro.com ?> --FILE-- <?php - /* Bind and connect sockets to localhost */ - $localhost = '127.0.0.1'; + /* Bind and connect sockets to localhost */ + $localhost = '127.0.0.1'; /* Setup socket server */ $server = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); @@ -20,16 +20,16 @@ Tatjana Andersen tatjana.andersen@redpill-linpro.com die('Unable to create AF_INET socket [server]'); } - $minport = 31337; - $maxport = 31356; - $bound = false; - for($port = $minport; $port <= $maxport; ++$port) { - if (@socket_bind($server, $localhost, $port)) { - $bound = true; - break; - } - } - if (!$bound) { + $minport = 31337; + $maxport = 31356; + $bound = false; + for($port = $minport; $port <= $maxport; ++$port) { + if (@socket_bind($server, $localhost, $port)) { + $bound = true; + break; + } + } + if (!$bound) { die('Unable to bind to '.$localhost); } if (!socket_listen($server, 2)) { @@ -51,9 +51,9 @@ Tatjana Andersen tatjana.andersen@redpill-linpro.com die('Unable to accept connection'); } - if (!socket_getpeername($client, $address, $peerport)) { - die('Unable to retrieve peer name'); - } + if (!socket_getpeername($client, $address, $peerport)) { + die('Unable to retrieve peer name'); + } var_dump($address, $port === $peerport); socket_close($client); diff --git a/ext/sockets/tests/socket_getpeername_ipv6loop.phpt b/ext/sockets/tests/socket_getpeername_ipv6loop.phpt index 73a5a66410..3dab562bbb 100644 --- a/ext/sockets/tests/socket_getpeername_ipv6loop.phpt +++ b/ext/sockets/tests/socket_getpeername_ipv6loop.phpt @@ -12,8 +12,8 @@ require 'ipv6_skipif.inc'; ?> --FILE-- <?php - /* Bind and connect sockets to localhost */ - $localhost = '::1'; + /* Bind and connect sockets to localhost */ + $localhost = '::1'; /* Setup socket server */ $server = socket_create(AF_INET6, SOCK_STREAM, getprotobyname('tcp')); @@ -21,16 +21,16 @@ require 'ipv6_skipif.inc'; die('Unable to create AF_INET6 socket [server]'); } - $minport = 31337; - $maxport = 31356; - $bound = false; - for($port = $minport; $port <= $maxport; ++$port) { - if (@socket_bind($server, $localhost, $port)) { - $bound = true; - break; - } - } - if (!$bound) { + $minport = 31337; + $maxport = 31356; + $bound = false; + for($port = $minport; $port <= $maxport; ++$port) { + if (@socket_bind($server, $localhost, $port)) { + $bound = true; + break; + } + } + if (!$bound) { die('Unable to bind to '.$localhost); } if (!socket_listen($server, 2)) { @@ -49,12 +49,12 @@ require 'ipv6_skipif.inc'; /* Accept that connection */ $socket = socket_accept($server); if (!$socket) { - die('Unable to accept connection'); + die('Unable to accept connection'); } - if (!socket_getpeername($client, $address, $peerport)) { - die('Unable to retrieve peer name'); - } + if (!socket_getpeername($client, $address, $peerport)) { + die('Unable to retrieve peer name'); + } var_dump($address, $port === $peerport); socket_close($client); diff --git a/ext/sockets/tests/socket_import_stream-1.phpt b/ext/sockets/tests/socket_import_stream-1.phpt index 925966312d..8608af33d4 100644 --- a/ext/sockets/tests/socket_import_stream-1.phpt +++ b/ext/sockets/tests/socket_import_stream-1.phpt @@ -21,5 +21,6 @@ socket_close($sock); var_dump(stream_get_contents($s1)); --EXPECTF-- -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} string(12) "test message" diff --git a/ext/sockets/tests/socket_import_stream-2.phpt b/ext/sockets/tests/socket_import_stream-2.phpt index ab303fdae8..a16a3dc18a 100644 --- a/ext/sockets/tests/socket_import_stream-2.phpt +++ b/ext/sockets/tests/socket_import_stream-2.phpt @@ -8,40 +8,28 @@ if (!extension_loaded('sockets')) { --FILE-- <?php -var_dump(socket_import_stream()); -var_dump(socket_import_stream(1, 2)); -var_dump(socket_import_stream(1)); -var_dump(socket_import_stream(new stdclass)); var_dump(socket_import_stream(fopen(__FILE__, "rb"))); -var_dump(socket_import_stream(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP))); +try { + socket_import_stream(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} $s = stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND); var_dump($s); var_dump(fclose($s)); -var_dump(socket_import_stream($s)); - +try { + socket_import_stream($s); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} echo "Done."; +?> --EXPECTF-- -Warning: socket_import_stream() expects exactly 1 parameter, 0 given in %s on line %d -NULL - -Warning: socket_import_stream() expects exactly 1 parameter, 2 given in %s on line %d -NULL - -Warning: socket_import_stream() expects parameter 1 to be resource, int given in %s on line %d -NULL - -Warning: socket_import_stream() expects parameter 1 to be resource, object given in %s on line %d -NULL - -Warning: socket_import_stream(): cannot represent a stream of type STDIO as a Socket Descriptor in %s on line %d -bool(false) - -Warning: socket_import_stream(): supplied resource is not a valid stream resource in %s on line %d +Warning: socket_import_stream(): Cannot represent a stream of type STDIO as a Socket Descriptor in %s on line %d bool(false) +socket_import_stream(): Argument #1 ($stream) must be of type resource, Socket given resource(%d) of type (stream) bool(true) - -Warning: socket_import_stream(): supplied resource is not a valid stream resource in %s on line %d -bool(false) +socket_import_stream(): supplied resource is not a valid stream resource Done. diff --git a/ext/sockets/tests/socket_import_stream-3.phpt b/ext/sockets/tests/socket_import_stream-3.phpt index f83e8a487b..6f340a4e6c 100644 --- a/ext/sockets/tests/socket_import_stream-3.phpt +++ b/ext/sockets/tests/socket_import_stream-3.phpt @@ -6,7 +6,7 @@ if (!extension_loaded('sockets')) { die('SKIP sockets extension not available.'); } $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); -$br = socket_bind($s, '0.0.0.0', 58379); +$br = @socket_bind($s, '0.0.0.0', 58379); if ($br === false) die("SKIP IPv4/port 58379 not available"); $so = @socket_set_option($s, IPPROTO_IP, MCAST_JOIN_GROUP, array( @@ -22,8 +22,8 @@ $stream = stream_socket_server("udp://0.0.0.0:58379", $errno, $errstr, STREAM_SE $sock = socket_import_stream($stream); var_dump($sock); $so = socket_set_option($sock, IPPROTO_IP, MCAST_JOIN_GROUP, array( - "group" => '224.0.0.23', - "interface" => "lo", + "group" => '224.0.0.23', + "interface" => "lo", )); var_dump($so); @@ -37,9 +37,11 @@ stream_set_blocking($stream, 0); var_dump(fread($stream, strlen($m))); echo "Done.\n"; --EXPECTF-- -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} int(10) string(10) "my message" Done. diff --git a/ext/sockets/tests/socket_import_stream-4-win.phpt b/ext/sockets/tests/socket_import_stream-4-win.phpt index e14e94c122..0845d8b510 100644 --- a/ext/sockets/tests/socket_import_stream-4-win.phpt +++ b/ext/sockets/tests/socket_import_stream-4-win.phpt @@ -12,20 +12,32 @@ if(substr(PHP_OS, 0, 3) != 'WIN' ) { <?php function test($stream, $sock) { - if ($stream !== null) { - echo "stream_set_blocking "; - print_r(stream_set_blocking($stream, 0)); - echo "\n"; - } - if ($sock !== null) { - echo "socket_set_block "; - print_r(socket_set_block($sock)); - echo "\n"; - echo "socket_get_option "; - print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); - echo "\n"; - } - echo "\n"; + if ($stream !== null) { + echo "stream_set_blocking "; + try { + print_r(stream_set_blocking($stream, 0)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + if ($sock !== null) { + echo "socket_set_block "; + try { + print_r(socket_set_block($sock)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + echo "socket_get_option "; + try { + print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + echo "\n"; } echo "normal\n"; @@ -56,8 +68,6 @@ $stream4 = stream_socket_server("udp://0.0.0.0:0", $errno, $errstr, STREAM_SERVE $sock4 = socket_import_stream($stream4); socket_close($sock4); test($stream4, $sock4); - -echo "Done.\n"; --EXPECTF-- normal stream_set_blocking 1 @@ -75,28 +85,21 @@ stream_set_blocking 1 close stream -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource socket_set_block Warning: socket_set_block(): unable to set blocking mode [10038]: %s in %ssocket_import_stream-4-win.php on line %d socket_get_option -Warning: socket_get_option(): unable to retrieve socket option [10038]: %s +Warning: socket_get_option(): Unable to retrieve socket option [10038]: %s in %ssocket_import_stream-4-win.php on line %d close socket -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d - -socket_set_block -Warning: socket_set_block(): supplied resource is not a valid Socket resource in %s on line %d - -socket_get_option -Warning: socket_get_option(): supplied resource is not a valid Socket resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource +socket_set_block Error: socket_set_block(): Argument #1 ($socket) has already been closed -Done. +socket_get_option Error: socket_get_option(): Argument #1 ($socket) has already been closed diff --git a/ext/sockets/tests/socket_import_stream-4.phpt b/ext/sockets/tests/socket_import_stream-4.phpt index f124161e10..bd2ac05aef 100644 --- a/ext/sockets/tests/socket_import_stream-4.phpt +++ b/ext/sockets/tests/socket_import_stream-4.phpt @@ -12,20 +12,32 @@ if(substr(PHP_OS, 0, 3) == 'WIN' ) { <?php function test($stream, $sock) { - if ($stream !== null) { - echo "stream_set_blocking "; - print_r(stream_set_blocking($stream, 0)); - echo "\n"; - } - if ($sock !== null) { - echo "socket_set_block "; - print_r(socket_set_block($sock)); - echo "\n"; - echo "socket_get_option "; - print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); - echo "\n"; - } - echo "\n"; + if ($stream !== null) { + echo "stream_set_blocking "; + try { + print_r(stream_set_blocking($stream, 0)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + if ($sock !== null) { + echo "socket_set_block "; + try { + print_r(socket_set_block($sock)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + echo "socket_get_option "; + try { + print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); + } catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + echo "\n"; + } + echo "\n"; } echo "normal\n"; @@ -75,26 +87,22 @@ stream_set_blocking 1 close stream -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource socket_set_block Warning: socket_set_block(): unable to set blocking mode [%d]: %s in %s on line %d socket_get_option -Warning: socket_get_option(): unable to retrieve socket option [%d]: %s in %s on line %d +Warning: socket_get_option(): Unable to retrieve socket option [%d]: %s in %s on line %d close socket -stream_set_blocking -Warning: stream_set_blocking(): supplied resource is not a valid stream resource in %s on line %d +stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource -socket_set_block -Warning: socket_set_block(): supplied resource is not a valid Socket resource in %s on line %d +socket_set_block Error: socket_set_block(): Argument #1 ($socket) has already been closed -socket_get_option -Warning: socket_get_option(): supplied resource is not a valid Socket resource in %s on line %d +socket_get_option Error: socket_get_option(): Argument #1 ($socket) has already been closed Done. diff --git a/ext/sockets/tests/socket_import_stream-5.phpt b/ext/sockets/tests/socket_import_stream-5.phpt index b3fbadc054..5eaf579854 100644 --- a/ext/sockets/tests/socket_import_stream-5.phpt +++ b/ext/sockets/tests/socket_import_stream-5.phpt @@ -7,6 +7,9 @@ if (!extension_loaded('sockets')) { } if (!function_exists('zend_leak_variable')) die('SKIP only for debug builds'); +?> +--INI-- +report_memleaks=0 --FILE-- <?php diff --git a/ext/sockets/tests/socket_listen-wrongparams.phpt b/ext/sockets/tests/socket_listen-wrongparams.phpt index 41d7ac1f10..b5715a5ff5 100644 --- a/ext/sockets/tests/socket_listen-wrongparams.phpt +++ b/ext/sockets/tests/socket_listen-wrongparams.phpt @@ -10,13 +10,9 @@ if (!extension_loaded('sockets')) { } --FILE-- <?php -var_dump(socket_listen(null)); $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); var_dump(socket_listen($socket)); --EXPECTF-- -Warning: socket_listen() expects parameter 1 to be resource, null given in %s on line %d -NULL - Warning: socket_listen(): unable to listen on socket [%d]: Invalid argument in %s on line %d bool(false) --CREDITS-- diff --git a/ext/sockets/tests/socket_recvmsg.phpt b/ext/sockets/tests/socket_recvmsg.phpt index 2d7a2f0d69..21f7b73058 100644 --- a/ext/sockets/tests/socket_recvmsg.phpt +++ b/ext/sockets/tests/socket_recvmsg.phpt @@ -49,10 +49,12 @@ if (!socket_recvmsg($s, $data, 0)) die("recvmsg"); print_r($data); --EXPECTF-- creating send socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) int(14) Array diff --git a/ext/sockets/tests/socket_select-wrongparams-1.phpt b/ext/sockets/tests/socket_select-wrongparams-1.phpt index 848088fe45..2658063e36 100644 --- a/ext/sockets/tests/socket_select-wrongparams-1.phpt +++ b/ext/sockets/tests/socket_select-wrongparams-1.phpt @@ -19,7 +19,7 @@ $except = null; $time = -1; var_dump(socket_select($sockets, $write, $except, $time)); --EXPECTF-- -Warning: socket_select(): unable to select [%d]: Invalid argument in %s on line %d +Warning: socket_select(): Unable to select [%d]: Invalid argument in %s on line %d bool(false) --CREDITS-- Till Klampaeckel, till@php.net diff --git a/ext/sockets/tests/socket_select-wrongparams-2.phpt b/ext/sockets/tests/socket_select-wrongparams-2.phpt index c149973e70..601ddb4efa 100644 --- a/ext/sockets/tests/socket_select-wrongparams-2.phpt +++ b/ext/sockets/tests/socket_select-wrongparams-2.phpt @@ -11,13 +11,14 @@ $sockets = null; $write = null; $except = null; $time = 0; -var_dump(socket_select($sockets, $write, $except, $time)); -socket_select($sockets, $write, $except); ---EXPECTF-- -Warning: socket_select(): no resource arrays were passed to select in %s on line %d -bool(false) -Warning: socket_select() expects at least 4 parameters, 3 given in %s on line %d +try { + socket_select($sockets, $write, $except, $time); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +--EXPECTF-- +socket_select(): At least one array argument must be passed --CREDITS-- Till Klampaeckel, till@php.net Berlin TestFest 2009 diff --git a/ext/sockets/tests/socket_select-wrongparams-3.phpt b/ext/sockets/tests/socket_select-wrongparams-3.phpt deleted file mode 100644 index 51686f9ccc..0000000000 --- a/ext/sockets/tests/socket_select-wrongparams-3.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -Test parameter handling in socket_select(). ---DESCRIPTION-- -Time must be long, otherwise it's casted. ---SKIPIF-- -<?php -if (!extension_loaded('sockets')) { - die('SKIP The sockets extension is not loaded.'); -} ---FILE-- -<?php -$sockets = array(); -if (strtolower(substr(PHP_OS, 0, 3)) == 'win') { - $domain = AF_INET; -} else { - $domain = AF_UNIX; -} -socket_create_pair($domain, SOCK_STREAM, 0, $sockets); - -$write = null; -$except = null; -$time = array(); -var_dump(socket_select($sockets, $write, $except, $time)); ---EXPECT-- -int(0) ---CREDITS-- -Till Klampaeckel, till@php.net -Berlin TestFest 2009 diff --git a/ext/sockets/tests/socket_select_error.phpt b/ext/sockets/tests/socket_select_error.phpt new file mode 100644 index 0000000000..645707467d --- /dev/null +++ b/ext/sockets/tests/socket_select_error.phpt @@ -0,0 +1,17 @@ +--TEST-- +socket_select() error conditions +--SKIPIF-- +<?php +if (!extension_loaded('sockets')) die('skip socket extension not available'); +?> +--FILE-- +<?php +$r = $w = $e = ['no resource']; +try { + socket_select($r, $w, $e, 1); +} catch (TypeError $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +socket_select(): Argument #1 ($read_fds) must only have elements of type Socket, string given diff --git a/ext/sockets/tests/socket_send_params.phpt b/ext/sockets/tests/socket_send_params.phpt index cc05288eb9..4c3f57729f 100644 --- a/ext/sockets/tests/socket_send_params.phpt +++ b/ext/sockets/tests/socket_send_params.phpt @@ -9,8 +9,12 @@ ext/sockets - socket_send - test with incorrect parameters --FILE-- <?php $s_c = socket_create_listen(0); - $s_w = socket_send($s_c, "foo", -1, MSG_OOB); + try { + $s_w = socket_send($s_c, "foo", -1, MSG_OOB); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } socket_close($s_c); ?> ---EXPECTF-- -Warning: socket_send(): Length cannot be negative in %s on line %i +--EXPECT-- +socket_send(): Argument #3 ($len) must be greater than or equal to 0 diff --git a/ext/sockets/tests/socket_sendrecvmsg_error.phpt b/ext/sockets/tests/socket_sendrecvmsg_error.phpt index 8cd353c769..8700b4184c 100644 --- a/ext/sockets/tests/socket_sendrecvmsg_error.phpt +++ b/ext/sockets/tests/socket_sendrecvmsg_error.phpt @@ -12,4 +12,4 @@ socket_recvmsg($socket, $message, -1); --EXPECTF-- Warning: socket_sendmsg(): error in sendmsg [%d]: %a in %s on line %d -Warning: socket_recvmsg(): error in recvmsg [%d]: %a in %s on line %d +Warning: socket_recvmsg(): Error in recvmsg [%d]: %a in %s on line %d diff --git a/ext/sockets/tests/socket_sendrecvmsg_multi_msg-unix.phpt b/ext/sockets/tests/socket_sendrecvmsg_multi_msg-unix.phpt index be42447f58..107aa626e8 100644 --- a/ext/sockets/tests/socket_sendrecvmsg_multi_msg-unix.phpt +++ b/ext/sockets/tests/socket_sendrecvmsg_multi_msg-unix.phpt @@ -41,13 +41,13 @@ socket_set_option($s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) or die("err"); socket_set_option($s, IPPROTO_IPV6, IPV6_RECVTCLASS, 1) or die("err"); $r = socket_sendmsg($sends1, [ - "name" => [ "addr" => "::1", "port" => 3002], - "iov" => ["test ", "thing", "\n"], - "control" => [[ - "level" => IPPROTO_IPV6, - "type" => IPV6_TCLASS, - "data" => 40, - ]] + "name" => [ "addr" => "::1", "port" => 3002], + "iov" => ["test ", "thing", "\n"], + "control" => [[ + "level" => IPPROTO_IPV6, + "type" => IPV6_TCLASS, + "data" => 40, + ]] ], 0); var_dump($r); checktimeout($s, 500); @@ -56,16 +56,18 @@ $data = [ "name" => ["family" => AF_INET6, "addr" => "::1"], "buffer_size" => 2000, "controllen" => socket_cmsg_space(IPPROTO_IPV6, IPV6_PKTINFO) + - socket_cmsg_space(IPPROTO_IPV6, IPV6_TCLASS), + socket_cmsg_space(IPPROTO_IPV6, IPV6_TCLASS), ]; if (!socket_recvmsg($s, $data, 0)) die("recvmsg"); print_r($data); --EXPECTF-- creating send socket -resource(5) of type (Socket) +object(Socket)#%d (0) { +} bool(true) creating receive socket -resource(6) of type (Socket) +object(Socket)#%d (0) { +} bool(true) int(11) Array diff --git a/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt b/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt index 72b90d0527..9e004afa22 100644 --- a/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt +++ b/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt @@ -36,16 +36,16 @@ socket_set_option($s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) or die("err"); socket_set_option($s, IPPROTO_IPV6, IPV6_RECVTCLASS, 1) or die("err"); $r = socket_sendmsg($sends1, [ - "name" => [ "addr" => "::1", "port" => 3003], - "iov" => ["test ", "thing", "\n"], - "control" => [[ - "level" => IPPROTO_IPV6, - "type" => IPV6_PKTINFO, - "data" => [ - 'addr' => '::1', + "name" => [ "addr" => "::1", "port" => 3003], + "iov" => ["test ", "thing", "\n"], + "control" => [[ + "level" => IPPROTO_IPV6, + "type" => IPV6_PKTINFO, + "data" => [ + 'addr' => '::1', 'ifindex' => 1 /* we're assuming loopback is 1. Is this a safe assumption? */ - ], - ]] + ], + ]] ], 0); var_dump($r); checktimeout($s, 500); @@ -54,16 +54,18 @@ $data = [ "name" => ["family" => AF_INET6, "addr" => "::1"], "buffer_size" => 2000, "controllen" => socket_cmsg_space(IPPROTO_IPV6, IPV6_PKTINFO) + - socket_cmsg_space(IPPROTO_IPV6, IPV6_TCLASS), + socket_cmsg_space(IPPROTO_IPV6, IPV6_TCLASS), ]; if (!socket_recvmsg($s, $data, 0)) die("recvmsg"); print_r($data); --EXPECTF-- creating send socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) creating receive socket -resource(%d) of type (Socket) +object(Socket)#%d (0) { +} bool(true) int(11) Array diff --git a/ext/sockets/tests/socket_sendto_params.phpt b/ext/sockets/tests/socket_sendto_params.phpt index e4808a93ee..09cb859ad7 100644 --- a/ext/sockets/tests/socket_sendto_params.phpt +++ b/ext/sockets/tests/socket_sendto_params.phpt @@ -9,8 +9,12 @@ ext/sockets - socket_sendto - test with incorrect parameters --FILE-- <?php $s_c = socket_create_listen(0); - $s_w = socket_sendto($s_c, "foo", -1, MSG_OOB, '127.0.0.1'); + try { + $s_w = socket_sendto($s_c, "foo", -1, MSG_OOB, '127.0.0.1'); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } socket_close($s_c); ?> ---EXPECTF-- -Warning: socket_sendto(): Length cannot be negative in %s on line %i +--EXPECT-- +socket_sendto(): Argument #3 ($len) must be greater than or equal to 0 diff --git a/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp-win32.phpt b/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp-win32.phpt index 8754028f84..fbc4da3861 100644 --- a/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp-win32.phpt +++ b/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp-win32.phpt @@ -20,7 +20,6 @@ require 'ipv6_skipif.inc'; } socket_recvfrom($socket, $buf, 12, 0, $from, $port); // cause warning $address = '::1'; - socket_sendto($socket, '', 1, 0, $address); // cause warning if (!socket_bind($socket, $address, 1223)) { die("Unable to bind to $address:1223"); } @@ -36,8 +35,6 @@ require 'ipv6_skipif.inc'; $from = ""; $port = 0; - socket_recvfrom($socket, $buf, 12, 0); // cause warning - socket_recvfrom($socket, $buf, 12, 0, $from); // cause warning $bytes_received = socket_recvfrom($socket, $buf, 12, 0, $from, $port); if ($bytes_received == -1) { die('An error occurred while receiving from the socket'); @@ -50,12 +47,6 @@ require 'ipv6_skipif.inc'; --EXPECTF-- Warning: socket_recvfrom(): unable to recvfrom [10022]: %s in %s on line %d - -Warning: Wrong parameter count for socket_sendto() in %s on line %d - -Warning: socket_recvfrom() expects at least 5 parameters, 4 given in %s on line %d - -Warning: Wrong parameter count for socket_recvfrom() in %s on line %d Received Ping! from remote address ::1 and remote port 1223 --CREDITS-- Falko Menge <mail at falko-menge dot de> diff --git a/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt b/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt index e25bf4df1a..6e063c5b52 100644 --- a/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt +++ b/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt @@ -26,13 +26,12 @@ if (!extension_loaded('sockets')) { $msg = "Ping!"; $len = strlen($msg); - $bytes_sent = socket_sendto($socket, $msg, $len, 0); // cause warning $bytes_sent = socket_sendto($socket, $msg, $len, 0, $address); if ($bytes_sent == -1) { - @unlink($address); + @unlink($address); die('An error occurred while sending to the socket'); } else if ($bytes_sent != $len) { - @unlink($address); + @unlink($address); die($bytes_sent . ' bytes have been sent instead of the ' . $len . ' bytes expected'); } @@ -40,22 +39,20 @@ if (!extension_loaded('sockets')) { var_dump(socket_recvfrom($socket, $buf, 0, 0, $from)); // expect false $bytes_received = socket_recvfrom($socket, $buf, 12, 0, $from); if ($bytes_received == -1) { - @unlink($address); + @unlink($address); die('An error occurred while receiving from the socket'); } else if ($bytes_received != $len) { - @unlink($address); + @unlink($address); die($bytes_received . ' bytes have been received instead of the ' . $len . ' bytes expected'); } echo "Received $buf"; socket_close($socket); - @unlink($address); + @unlink($address); ?> --EXPECTF-- Warning: socket_create(): Unable to create socket [%d]: Protocol not supported in %s on line %d bool(false) - -Warning: socket_sendto() expects at least 5 parameters, 4 given in %s on line %d bool(false) Received Ping! --CREDITS-- diff --git a/ext/sockets/tests/socket_set_block-retval.phpt b/ext/sockets/tests/socket_set_block-retval.phpt index 88e0029989..00ec7038de 100644 --- a/ext/sockets/tests/socket_set_block-retval.phpt +++ b/ext/sockets/tests/socket_set_block-retval.phpt @@ -15,14 +15,13 @@ socket_close($socket); $socket2 = socket_create_listen(31340); socket_close($socket2); -var_dump(socket_set_block($socket2)); +try { + var_dump(socket_set_block($socket2)); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} ?> ---EXPECTF-- +--EXPECT-- bool(true) - -Warning: socket_set_block(): supplied resource is not a valid Socket resource in %s on line %d -bool(false) ---CREDITS-- -Robin Mehner, robin@coding-robin.de -PHP Testfest Berlin 2009-05-09 +socket_set_block(): Argument #1 ($socket) has already been closed diff --git a/ext/sockets/tests/socket_set_nonblock-retval.phpt b/ext/sockets/tests/socket_set_nonblock-retval.phpt index c9bb1150ab..6df6521324 100644 --- a/ext/sockets/tests/socket_set_nonblock-retval.phpt +++ b/ext/sockets/tests/socket_set_nonblock-retval.phpt @@ -15,14 +15,13 @@ socket_close($socket); $socket2 = socket_create_listen(31340); socket_close($socket2); -var_dump(socket_set_nonblock($socket2)); +try { + var_dump(socket_set_nonblock($socket2)); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} ?> ---EXPECTF-- +--EXPECT-- bool(true) - -Warning: socket_set_nonblock(): supplied resource is not a valid Socket resource in %s on line %d -bool(false) ---CREDITS-- -Robin Mehner, robin@coding-robin.de -PHP Testfest Berlin 2009-05-09 +socket_set_nonblock(): Argument #1 ($socket) has already been closed diff --git a/ext/sockets/tests/socket_set_nonblock.phpt b/ext/sockets/tests/socket_set_nonblock.phpt index 88f29d928e..46d673232e 100644 --- a/ext/sockets/tests/socket_set_nonblock.phpt +++ b/ext/sockets/tests/socket_set_nonblock.phpt @@ -17,5 +17,6 @@ fa@php.net //socket_accept($s_c_l); socket_close($s_c_l); ?> ---EXPECTF-- -resource(%i) of type (Socket) +--EXPECT-- +object(Socket)#1 (0) { +} diff --git a/ext/sockets/tests/socket_set_option_bindtodevice.phpt b/ext/sockets/tests/socket_set_option_bindtodevice.phpt index fe0afd7c51..acce4d832c 100644 --- a/ext/sockets/tests/socket_set_option_bindtodevice.phpt +++ b/ext/sockets/tests/socket_set_option_bindtodevice.phpt @@ -33,7 +33,7 @@ socket_close($socket); --EXPECTF-- bool(true) -Warning: socket_set_option(): unable to set socket option [19]: No such device in %s on line %d +Warning: socket_set_option(): Unable to set socket option [19]: No such device in %s on line %d bool(false) --CREDITS-- Damjan Cvetko, foreach.org diff --git a/ext/sockets/tests/socket_set_option_error_socket_option.phpt b/ext/sockets/tests/socket_set_option_error_socket_option.phpt index 53d76fa4c1..0729524f6e 100644 --- a/ext/sockets/tests/socket_set_option_error_socket_option.phpt +++ b/ext/sockets/tests/socket_set_option_error_socket_option.phpt @@ -1,5 +1,5 @@ --TEST-- -Test if socket_set_option() returns 'unable to set socket option' failure for invalid options +Test if socket_set_option() returns 'Unable to set socket option' failure for invalid options --SKIPIF-- <?php if (!extension_loaded('sockets')) { @@ -28,7 +28,7 @@ socket_set_option( $socket, SOL_SOCKET, 1, 1); socket_close($socket); ?> --EXPECTF-- -Warning: socket_set_option(): unable to set socket option [%d]: Permission denied in %s on line %d +Warning: socket_set_option(): Unable to set socket option [%d]: Permission denied in %s on line %d --CREDITS-- Moritz Neuhaeuser, info@xcompile.net PHP Testfest Berlin 2009-05-10 diff --git a/ext/sockets/tests/socket_set_option_rcvtimeo.phpt b/ext/sockets/tests/socket_set_option_rcvtimeo.phpt index a27d4075db..819d0ee443 100644 --- a/ext/sockets/tests/socket_set_option_rcvtimeo.phpt +++ b/ext/sockets/tests/socket_set_option_rcvtimeo.phpt @@ -18,7 +18,11 @@ if (!$socket) { socket_set_block($socket); //wrong params -$retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_RCVTIMEO, array()); +try { + $retval_1 = socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, []); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} //set/get comparison $options = array("sec" => 1, "usec" => 0); @@ -29,8 +33,8 @@ var_dump($retval_2); var_dump($retval_3 === $options); socket_close($socket); ?> ---EXPECTF-- -Warning: socket_set_option(): no key "sec" passed in optval in %s on line %d +--EXPECT-- +socket_set_option(): Argument #4 ($optval) must have key "sec" bool(true) bool(true) --CREDITS-- diff --git a/ext/sockets/tests/socket_set_option_seolinger.phpt b/ext/sockets/tests/socket_set_option_seolinger.phpt index 4d171fc70a..132d4e0c6e 100644 --- a/ext/sockets/tests/socket_set_option_seolinger.phpt +++ b/ext/sockets/tests/socket_set_option_seolinger.phpt @@ -18,7 +18,11 @@ if (!$socket) { die('Unable to create AF_INET socket [socket]'); } // wrong params -$retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_LINGER, array()); +try { + $retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_LINGER, []); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} // set/get comparison $options = array("l_onoff" => 1, "l_linger" => 1); @@ -27,7 +31,11 @@ $retval_3 = socket_get_option( $socket, SOL_SOCKET, SO_LINGER); //l_linger not given $options_2 = array("l_onoff" => 1); -var_dump(socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_2)); +try { + var_dump(socket_set_option( $socket, SOL_SOCKET, SO_LINGER, $options_2)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump($retval_2); var_dump($retval_3["l_linger"] === $options["l_linger"]); @@ -36,11 +44,9 @@ var_dump((bool)$retval_3["l_onoff"] === (bool)$options["l_onoff"]); socket_close($socket); ?> ---EXPECTF-- -Warning: socket_set_option(): no key "l_onoff" passed in optval in %s on line %d - -Warning: socket_set_option(): no key "l_linger" passed in optval in %s on line %d -bool(false) +--EXPECT-- +socket_set_option(): Argument #4 ($optval) must have key "l_onoff" +socket_set_option(): Argument #4 ($optval) must have key "l_linger" bool(true) bool(true) bool(true) diff --git a/ext/sockets/tests/socket_set_option_sndtimeo.phpt b/ext/sockets/tests/socket_set_option_sndtimeo.phpt index 1b4fb5570d..359aab9ae9 100644 --- a/ext/sockets/tests/socket_set_option_sndtimeo.phpt +++ b/ext/sockets/tests/socket_set_option_sndtimeo.phpt @@ -18,7 +18,11 @@ if (!$socket) { socket_set_block($socket); //wrong params -$retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_SNDTIMEO, array()); +try { + $retval_1 = socket_set_option( $socket, SOL_SOCKET, SO_SNDTIMEO, []); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} //set/get comparison $options = array("sec" => 1, "usec" => 0); @@ -29,8 +33,8 @@ var_dump($retval_2); var_dump($retval_3 === $options); socket_close($socket); ?> ---EXPECTF-- -Warning: socket_set_option(): no key "sec" passed in optval in %s on line %d +--EXPECT-- +socket_set_option(): Argument #4 ($optval) must have key "sec" bool(true) bool(true) --CREDITS-- diff --git a/ext/sockets/tests/socket_shutdown-win32.phpt b/ext/sockets/tests/socket_shutdown-win32.phpt index 6280e61044..aced74b7f8 100644 --- a/ext/sockets/tests/socket_shutdown-win32.phpt +++ b/ext/sockets/tests/socket_shutdown-win32.phpt @@ -50,10 +50,10 @@ bool(true) bool(true) bool(true) -Warning: socket_shutdown(): unable to shutdown socket [%d]: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. +Warning: socket_shutdown(): Unable to shutdown socket [%d]: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. in %s on line %d bool(false) -Warning: socket_shutdown(): unable to shutdown socket [%d]: An invalid argument was supplied. +Warning: socket_shutdown(): Unable to shutdown socket [%d]: An invalid argument was supplied. in %s on line %d bool(false) diff --git a/ext/sockets/tests/socket_shutdown.phpt b/ext/sockets/tests/socket_shutdown.phpt index 747016b795..554958a77a 100644 --- a/ext/sockets/tests/socket_shutdown.phpt +++ b/ext/sockets/tests/socket_shutdown.phpt @@ -51,8 +51,8 @@ bool(true) bool(true) bool(true) -Warning: socket_shutdown(): unable to shutdown socket [%d]: Transport endpoint is not connected in %s on line %d +Warning: socket_shutdown(): Unable to shutdown socket [%d]: Transport endpoint is not connected in %s on line %d bool(false) -Warning: socket_shutdown(): unable to shutdown socket [%d]: Invalid argument in %s on line %d +Warning: socket_shutdown(): Unable to shutdown socket [%d]: Invalid argument in %s on line %d bool(false) diff --git a/ext/sockets/tests/socket_strerror.phpt b/ext/sockets/tests/socket_strerror.phpt index be0492a25c..1381a39f87 100644 --- a/ext/sockets/tests/socket_strerror.phpt +++ b/ext/sockets/tests/socket_strerror.phpt @@ -14,13 +14,11 @@ fa@php.net ?> --FILE-- <?php - $s_s = socket_strerror(); for ($i=0;$i<=132;$i++) { var_dump(socket_strerror($i)); } ?> --EXPECTF-- -Warning: socket_strerror() expects exactly 1 parameter, 0 given in %s on line %d string(7) "Success" string(23) "Operation not permitted" string(25) "No such file or directory" diff --git a/ext/sockets/tests/unixloop.phpt b/ext/sockets/tests/unixloop.phpt index cd4afd65c7..31740c97c6 100644 --- a/ext/sockets/tests/unixloop.phpt +++ b/ext/sockets/tests/unixloop.phpt @@ -11,47 +11,47 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { ?> --FILE-- <?php - $sock_path = sprintf("/tmp/%s.sock", uniqid()); + $sock_path = sprintf("/tmp/%s.sock", uniqid()); - if (file_exists($sock_path)) - die('Temporary socket already exists.'); + if (file_exists($sock_path)) + die('Temporary socket already exists.'); - /* Setup socket server */ - $server = socket_create(AF_UNIX, SOCK_STREAM, 0); - if (!$server) { - die('Unable to create AF_UNIX socket [server]'); - } - if (!socket_bind($server, $sock_path)) { - die("Unable to bind to $sock_path"); - } - if (!socket_listen($server, 2)) { - die('Unable to listen on socket'); - } + /* Setup socket server */ + $server = socket_create(AF_UNIX, SOCK_STREAM, 0); + if (!$server) { + die('Unable to create AF_UNIX socket [server]'); + } + if (!socket_bind($server, $sock_path)) { + die("Unable to bind to $sock_path"); + } + if (!socket_listen($server, 2)) { + die('Unable to listen on socket'); + } - /* Connect to it */ - $client = socket_create(AF_UNIX, SOCK_STREAM, 0); - if (!$client) { - die('Unable to create AF_UNIX socket [client]'); - } - if (!socket_connect($client, $sock_path)) { - die('Unable to connect to server socket'); - } + /* Connect to it */ + $client = socket_create(AF_UNIX, SOCK_STREAM, 0); + if (!$client) { + die('Unable to create AF_UNIX socket [client]'); + } + if (!socket_connect($client, $sock_path)) { + die('Unable to connect to server socket'); + } - /* Accept that connection */ - $socket = socket_accept($server); - if (!$socket) { - die('Unable to accept connection'); - } + /* Accept that connection */ + $socket = socket_accept($server); + if (!$socket) { + die('Unable to accept connection'); + } - socket_write($client, "ABCdef123\n"); + socket_write($client, "ABCdef123\n"); - $data = socket_read($socket, 10, PHP_BINARY_READ); - var_dump($data); + $data = socket_read($socket, 10, PHP_BINARY_READ); + var_dump($data); - socket_close($client); - socket_close($socket); - socket_close($server); - @unlink($sock_path); + socket_close($client); + socket_close($socket); + socket_close($server); + @unlink($sock_path); ?> --EXPECT-- string(10) "ABCdef123 diff --git a/ext/sockets/tests/wsaprotocol_info_0.phpt b/ext/sockets/tests/wsaprotocol_info_0.phpt index 2750b32080..7ea50d359f 100644 --- a/ext/sockets/tests/wsaprotocol_info_0.phpt +++ b/ext/sockets/tests/wsaprotocol_info_0.phpt @@ -11,47 +11,51 @@ if (!extension_loaded('sockets')) { ?> --FILE-- <?php - $address = 'localhost'; - $port = 10000; + $address = 'localhost'; + $port = 10000; - if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { - fprintf(STDERR, "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"); - } + if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { + fprintf(STDERR, "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"); + } - if (socket_bind($sock, $address, $port) === false) { - fprintf(STDERR, "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); - } + if (socket_bind($sock, $address, $port) === false) { + fprintf(STDERR, "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); + } - if (socket_listen($sock, 5) === false) { - fprintf(STDERR, "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); - } + if (socket_listen($sock, 5) === false) { + fprintf(STDERR, "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); + } - /* Duplicate socket in the same process. */ - $pid = getmypid(); - $info = socket_wsaprotocol_info_export($sock, $pid); - $sock2 = socket_wsaprotocol_info_import($info); - var_dump(socket_wsaprotocol_info_release($info)); + /* Duplicate socket in the same process. */ + $pid = getmypid(); + $info = socket_wsaprotocol_info_export($sock, $pid); + $sock2 = socket_wsaprotocol_info_import($info); + var_dump(socket_wsaprotocol_info_release($info)); - var_dump($sock, $sock2); + var_dump($sock, $sock2); - /* Close duplicated socket, teh orig is still valid. */ - socket_close($sock2); - var_dump($sock, $sock2); + /* Close duplicated socket, the original is still valid. */ + socket_close($sock2); + var_dump($sock, $sock2); - /* Using invalid PID. */ - $info = socket_wsaprotocol_info_export($sock, 123412341); + /* Using invalid PID. */ + $info = socket_wsaprotocol_info_export($sock, 123412341); - socket_close($sock); + socket_close($sock); - /* Importing with invalid identifier. */ - $sock2 = socket_wsaprotocol_info_import("garbage"); + /* Importing with invalid identifier. */ + $sock2 = socket_wsaprotocol_info_import("garbage"); ?> --EXPECTF-- bool(true) -resource(%d) of type (Socket) -resource(%d) of type (Socket) -resource(%d) of type (Socket) -resource(%d) of type (Unknown) +object(Socket)#%d (0) { +} +object(Socket)#%d (0) { +} +object(Socket)#%d (0) { +} +object(Socket)#%d (0) { +} Warning: socket_wsaprotocol_info_export(): Unable to export WSA protocol info [0x00002726]: %s in %s on line %d diff --git a/ext/sockets/unix_socket_constants.h b/ext/sockets/unix_socket_constants.h index a8a276ccbf..53763b6aa1 100644 --- a/ext/sockets/unix_socket_constants.h +++ b/ext/sockets/unix_socket_constants.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | diff --git a/ext/sockets/win32_socket_constants.h b/ext/sockets/win32_socket_constants.h index e2adf8cacf..656b530a29 100644 --- a/ext/sockets/win32_socket_constants.h +++ b/ext/sockets/win32_socket_constants.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | diff --git a/ext/sockets/windows_common.h b/ext/sockets/windows_common.h index 771d07d752..2923503556 100644 --- a/ext/sockets/windows_common.h +++ b/ext/sockets/windows_common.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | |
