]> granicus.if.org Git - php/commitdiff
Convert resources to objects in ext/sockets
authorMáté Kocsis <kocsismate@woohoolabs.com>
Mon, 27 Jul 2020 19:23:27 +0000 (21:23 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 3 Aug 2020 21:26:38 +0000 (23:26 +0200)
Closes GH-5900.

36 files changed:
ext/posix/tests/posix_ttyname_error_wrongparams.phpt
ext/sockets/conversions.c
ext/sockets/php_sockets.h
ext/sockets/sendrecvmsg.c
ext/sockets/sockets.c
ext/sockets/sockets.stub.php
ext/sockets/sockets_arginfo.h
ext/sockets/tests/mcast_ipv4_recv.phpt
ext/sockets/tests/mcast_ipv6_recv.phpt
ext/sockets/tests/mcast_ipv6_recv_limited.phpt
ext/sockets/tests/socket_addrinfo_bind.phpt
ext/sockets/tests/socket_addrinfo_connect.phpt
ext/sockets/tests/socket_addrinfo_lookup.phpt
ext/sockets/tests/socket_cmsg_credentials.phpt
ext/sockets/tests/socket_cmsg_rights.phpt
ext/sockets/tests/socket_connect_params.phpt
ext/sockets/tests/socket_create_listen_used.phpt
ext/sockets/tests/socket_create_pair.phpt
ext/sockets/tests/socket_export_stream-2.phpt
ext/sockets/tests/socket_export_stream-3.phpt
ext/sockets/tests/socket_export_stream-4.phpt
ext/sockets/tests/socket_export_stream-5.phpt
ext/sockets/tests/socket_import_stream-1.phpt
ext/sockets/tests/socket_import_stream-2.phpt
ext/sockets/tests/socket_import_stream-3.phpt
ext/sockets/tests/socket_import_stream-4.phpt
ext/sockets/tests/socket_import_stream-5.phpt
ext/sockets/tests/socket_recvmsg.phpt
ext/sockets/tests/socket_select-wrongparams-2.phpt
ext/sockets/tests/socket_select_error.phpt
ext/sockets/tests/socket_sendrecvmsg_multi_msg-unix.phpt
ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt
ext/sockets/tests/socket_set_block-retval.phpt
ext/sockets/tests/socket_set_nonblock-retval.phpt
ext/sockets/tests/socket_set_nonblock.phpt
ext/sockets/tests/wsaprotocol_info_0.phpt

index 8d10ce5497757b0b9c62edb3e40228ab4fd1c007..d66651652197c71af5e8fff3cc7713b346ad18e4 100644 (file)
@@ -20,7 +20,7 @@ PHP Testfest Berlin 2009-05-10
 <?php
 var_dump(posix_ttyname(0)); // param not a resource
 try {
-    var_dump(posix_ttyname(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP))); // wrong resource type
+    var_dump(posix_ttyname(finfo_open(FILEINFO_NONE, __DIR__))); // wrong resource type
 } catch (TypeError $e) {
     echo $e->getMessage(), "\n";
 }
index b2221e26ec9ff499ee58fc2f0b05de4d2f083452..4eaa217b73805d6210273dff68008456d1bbf7ec 100644 (file)
@@ -1341,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)
@@ -1414,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);
index 7f67040ce3c720b40bbedd3a90c37a014c8021ff..83d5bdd7c25d8b6bfedd9c4f5ecd3334268db6f3 100644 (file)
@@ -29,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
@@ -52,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;
@@ -67,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 */ \
@@ -104,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
index 27e3681f6a250bf9a884b485a8d3ffaa2b8f6af1..9e97cf00e20d9e51339568aefd7ae7d7b2b03689 100644 (file)
@@ -172,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) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa|l", &zsocket, socket_ce, &zmsg, &flags) == FAILURE) {
                RETURN_THROWS();
        }
 
        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_THROWS();
-       }
+       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);
@@ -216,17 +214,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) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa|l", &zsocket, socket_ce, &zmsg, &flags) == FAILURE) {
                RETURN_THROWS();
        }
 
        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_THROWS();
-       }
+       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);
index d17203f0a484b07b558240430da5ece138eeae69..e1f7ec392c743dba6d119aaef6a56971253a7ea4 100644 (file)
@@ -28,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>
@@ -50,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
@@ -92,12 +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
-
 static PHP_GINIT_FUNCTION(sockets);
 static PHP_GSHUTDOWN_FUNCTION(sockets);
 static PHP_MINIT_FUNCTION(sockets);
@@ -105,6 +99,102 @@ static PHP_MSHUTDOWN_FUNCTION(sockets);
 static PHP_MINFO_FUNCTION(sockets);
 static PHP_RSHUTDOWN_FUNCTION(sockets);
 
+/* Socket class */
+
+zend_class_entry *socket_ce;
+static zend_object_handlers socket_object_handlers;
+
+static zend_object *socket_create_object(zend_class_entry *class_type) {
+       php_socket *intern = zend_object_alloc(sizeof(php_socket), class_type);
+
+       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",
@@ -133,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;
        }
 
@@ -207,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;
        }
 
@@ -216,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;
        }
 
@@ -231,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)) {
@@ -401,8 +432,35 @@ 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);
@@ -583,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;
@@ -593,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) return -1; /* If element is not a resource, bail out */
+
+               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) {
@@ -617,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);
-               ZEND_ASSERT(php_sock); /* element is supposed to be resource */
+
+               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 */
@@ -669,28 +738,27 @@ PHP_FUNCTION(socket_select)
        FD_ZERO(&efds);
 
        if (r_array != NULL) {
-               sets += retval = php_sock_array_to_fd_set(r_array, &rfds, &max_fd);
+               sets += retval = php_sock_array_to_fd_set(1, r_array, &rfds, &max_fd);
                if (retval == -1) {
-                       return;
+                       RETURN_THROWS();
                }
        }
        if (w_array != NULL) {
-               sets += retval = php_sock_array_to_fd_set(w_array, &wfds, &max_fd);
+               sets += retval = php_sock_array_to_fd_set(2, w_array, &wfds, &max_fd);
                if (retval == -1) {
-                       return;
+                       RETURN_THROWS();
                }
        }
        if (e_array != NULL) {
-               sets += retval = php_sock_array_to_fd_set(e_array, &efds, &max_fd);
+               sets += retval = php_sock_array_to_fd_set(3, e_array, &efds, &max_fd);
                if (retval == -1) {
-                       return;
+                       RETURN_THROWS();
                }
        }
 
        if (!sets) {
-               /* TODO Convert to Error? */
-               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 */
@@ -735,38 +803,41 @@ PHP_FUNCTION(socket_create_listen)
                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));
 }
 /* }}} */
 
 /* {{{ 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) {
+       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_THROWS();
-       }
+       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));
 }
 /* }}} */
 
@@ -776,13 +847,12 @@ PHP_FUNCTION(socket_set_nonblock)
        zval            *arg1;
        php_socket      *php_sock;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        if (!Z_ISUNDEF(php_sock->zstream)) {
                php_stream *stream;
@@ -813,13 +883,12 @@ PHP_FUNCTION(socket_set_block)
        zval            *arg1;
        php_socket      *php_sock;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) {
+       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_THROWS();
-       }
+       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
@@ -853,13 +922,12 @@ PHP_FUNCTION(socket_listen)
        php_socket      *php_sock;
        zend_long               backlog = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &arg1, &backlog) == FAILURE) {
+       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_THROWS();
-       }
+       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);
@@ -872,20 +940,19 @@ PHP_FUNCTION(socket_listen)
 /* {{{ 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) {
+       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_THROWS();
-       }
+       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 */
@@ -893,8 +960,14 @@ 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;
 }
 /* }}} */
 
@@ -906,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) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l!", &arg1, socket_ce, &str, &str_len, &length, &length_is_null) == FAILURE) {
                RETURN_THROWS();
        }
 
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
+
        if (length < 0) {
                zend_argument_value_error(3, "must be greater than or equal to 0");
                RETURN_THROWS();
        }
 
-       if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) {
-               RETURN_THROWS();
-       }
-
-       if (ZEND_NUM_ARGS() < 3) {
+       if (length_is_null) {
                length = str_len;
        }
 
@@ -949,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) {
+       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;
@@ -960,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_THROWS();
-       }
-
        if (type == PHP_NORMAL_READ) {
                retval = php_read(php_sock, ZSTR_VAL(tmpbuf), length, 0);
        } else {
@@ -1015,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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        sa = (struct sockaddr *) &sa_storage;
 
@@ -1088,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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        sa = (struct sockaddr *) &sa_storage;
 
@@ -1152,10 +1222,9 @@ PHP_FUNCTION(socket_getpeername)
 PHP_FUNCTION(socket_create)
 {
        zend_long       domain, type, protocol;
-       php_socket      *php_sock = php_create_socket();
+       php_socket      *php_sock;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &domain, &type, &protocol) == FAILURE) {
-               efree(php_sock);
                RETURN_THROWS();
        }
 
@@ -1164,32 +1233,31 @@ PHP_FUNCTION(socket_create)
                && domain != AF_INET6
 #endif
                && domain != AF_INET) {
-               zend_argument_value_error(1, "must be either AF_UNIX, AF_INET6 or AF_INET");
-               efree(php_sock);
+               zend_argument_value_error(1, "must be either AF_UNIX, AF_INET6, or AF_INET");
                RETURN_THROWS();
        }
 
        if (type > 10) {
                zend_argument_value_error(2, "must be either SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET,"
                        " SOCK_RAW, or SOCK_RDM");
-               efree(php_sock);
                RETURN_THROWS();
        }
 
+       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));
 }
 /* }}} */
 
@@ -1201,23 +1269,23 @@ PHP_FUNCTION(socket_connect)
        char                            *addr;
        int                                     retval;
        size_t              addr_len;
-       zend_long                               port = 0;
+       zend_long                               port;
+       zend_bool                               port_is_null = 1;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &resource_socket, &addr, &addr_len, &port) == FAILURE) {
+       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(resource_socket), le_socket_name, le_socket)) == NULL) {
-               RETURN_THROWS();
-       }
+       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 (ZEND_NUM_ARGS() != 3) {
-                               zend_argument_value_error(3, "must be specified for the AF_INET6 socket type");
+                       if (port_is_null) {
+                               zend_argument_value_error(3, "cannot be null when the socket type is AF_INET6");
                                RETURN_THROWS();
                        }
 
@@ -1237,8 +1305,8 @@ PHP_FUNCTION(socket_connect)
                case AF_INET: {
                        struct sockaddr_in sin = {0};
 
-                       if (ZEND_NUM_ARGS() != 3) {
-                               zend_argument_value_error(3, "must be specified for the AF_INET socket type");
+                       if (port_is_null) {
+                               zend_argument_value_error(3, "cannot be null when the socket type is AF_INET");
                                RETURN_THROWS();
                        }
 
@@ -1307,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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        switch(php_sock->type) {
                case AF_UNIX:
@@ -1386,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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(php_sock_res);
+       ENSURE_SOCKET_VALID(php_sock);
 
        /* overflow check */
        if ((len + 1) < 2) {
@@ -1428,19 +1494,18 @@ 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) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osll", &arg1, socket_ce, &buf, &buf_len, &len, &flags) == FAILURE) {
                RETURN_THROWS();
        }
 
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
+
        if (len < 0) {
                zend_argument_value_error(3, "must be greater than or equal to 0");
                RETURN_THROWS();
        }
 
-       if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) {
-               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) {
@@ -1469,13 +1534,12 @@ 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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        /* overflow check */
        /* Shouldthrow ? */
@@ -1581,23 +1645,22 @@ 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) {
+       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();
        }
 
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
+
        if (len < 0) {
                zend_argument_value_error(3, "must be greater than or equal to 0");
                RETURN_THROWS();
        }
 
-       if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(arg1), le_socket_name, le_socket)) == NULL) {
-               RETURN_THROWS();
-       }
-
        switch (php_sock->type) {
                case AF_UNIX:
                        memset(&s_un, 0, sizeof(s_un));
@@ -1608,8 +1671,9 @@ PHP_FUNCTION(socket_sendto)
                        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));
@@ -1624,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));
@@ -1667,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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        if (level == IPPROTO_IP) {
                switch (optname) {
@@ -1781,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) {
+       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_THROWS();
-       }
+       php_sock = Z_SOCKET_P(arg1);
+       ENSURE_SOCKET_VALID(php_sock);
 
        set_errno(0);
 
@@ -1935,21 +1997,24 @@ PHP_FUNCTION(socket_create_pair)
                RETURN_THROWS();
        }
 
-       php_sock[0] = php_create_socket();
-       php_sock[1] = php_create_socket();
+       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]);
+               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]);
+               zval_ptr_dtor(&retval[0]);
+               zval_ptr_dtor(&retval[1]);
                RETURN_THROWS();
        }
 
@@ -1962,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]);
 
@@ -1981,13 +2043,12 @@ PHP_FUNCTION(socket_shutdown)
        zend_long               how_shutdown = 2;
        php_socket      *php_sock;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &arg1, &how_shutdown) == FAILURE) {
+       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_THROWS();
-       }
+       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);
@@ -2005,14 +2066,14 @@ PHP_FUNCTION(socket_last_error)
        zval            *arg1 = NULL;
        php_socket      *php_sock;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &arg1) == FAILURE) {
+       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_THROWS();
-               }
+               php_sock = Z_SOCKET_P(arg1);
+               ENSURE_SOCKET_VALID(php_sock);
+
                RETVAL_LONG(php_sock->error);
        } else {
                RETVAL_LONG(SOCKETS_G(last_error));
@@ -2026,14 +2087,14 @@ PHP_FUNCTION(socket_clear_error)
        zval            *arg1 = NULL;
        php_socket      *php_sock;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &arg1) == FAILURE) {
+       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_THROWS();
-               }
+               php_sock = Z_SOCKET_P(arg1);
+               ENSURE_SOCKET_VALID(php_sock);
+
                php_sock->error = 0;
        } else {
                SOCKETS_G(last_error) = 0;
@@ -2043,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 */
@@ -2069,7 +2128,7 @@ php_socket *socket_import_file_descriptor(PHP_SOCKET socket)
                retsock->type = addr.ss_family;
        } else {
                PHP_SOCKET_ERROR(retsock, "Unable to obtain socket family", errno);
-               goto error;
+               return 0;
        }
 
     /* determine blocking mode */
@@ -2077,17 +2136,13 @@ php_socket *socket_import_file_descriptor(PHP_SOCKET socket)
     t = fcntl(socket, F_GETFL);
     if (t == -1) {
                PHP_SOCKET_ERROR(retsock, "Unable to obtain blocking state", errno);
-               goto error;
+               return 0;
     } else {
        retsock->blocking = !(t & O_NONBLOCK);
     }
 #endif
 
-    return retsock;
-
-error:
-       efree(retsock);
-       return NULL;
+    return 1;
 }
 
 /* {{{ Imports a stream that encapsulates a socket into a socket extension resource. */
@@ -2108,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;
        }
 
@@ -2128,10 +2186,7 @@ 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);
 }
 /* }}} */
 
@@ -2145,13 +2200,13 @@ PHP_FUNCTION(socket_export_stream)
        char *protocol = NULL;
        size_t protocollen = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zsocket) == FAILURE) {
-               RETURN_THROWS();
-       }
-       if ((socket = (php_socket *) zend_fetch_resource(Z_RES_P(zsocket), le_socket_name, le_socket)) == NULL) {
+       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)) {
@@ -2235,18 +2290,19 @@ PHP_FUNCTION(socket_export_stream)
 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;
-
-       memset(&hints, 0, sizeof(hints));
+       struct addrinfo hints, *result, *rp;
+       php_addrinfo *res;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|sa", &hostname, &service, &service_len, &zhints) == FAILURE) {
+       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) {
@@ -2274,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;
 
-                       res->ai_addr = emalloc(rp->ai_addrlen);
-                       memcpy(res->ai_addr, rp->ai_addr, rp->ai_addrlen);
+                       object_init_ex(&zaddr, address_info_ce);
+                       res = Z_ADDRESS_INFO_P(&zaddr);
+
+                       memcpy(&res->addrinfo, rp, sizeof(struct addrinfo));
+
+                       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);
                }
        }
 
@@ -2297,25 +2357,25 @@ 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) {
+       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_THROWS();
-       }
+       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;
        }
 
@@ -2327,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;
                        }
 
@@ -2336,12 +2396,12 @@ 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:
                        close(php_sock->bsd_socket);
-                       efree(php_sock);
+                       zval_ptr_dtor(return_value);
                        zend_argument_value_error(1, "must be either AF_UNIX, AF_INET, or AF_INET6");
                        RETURN_THROWS();
        }
@@ -2349,11 +2409,9 @@ PHP_FUNCTION(socket_addrinfo_bind)
        if (retval != 0) {
                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));
 }
 /* }}} */
 
@@ -2362,25 +2420,25 @@ 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) {
+       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_THROWS();
-       }
+       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;
        }
 
@@ -2392,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;
                        }
 
@@ -2401,24 +2459,22 @@ 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:
                        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);
+                       zval_ptr_dtor(return_value);
                        RETURN_THROWS();
        }
 
        if (retval != 0) {
                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));
 }
 /* }}} */
 
@@ -2426,46 +2482,44 @@ PHP_FUNCTION(socket_addrinfo_connect)
 PHP_FUNCTION(socket_addrinfo_explain)
 {
        zval                    *arg1, sockaddr;
-       struct addrinfo *ai;
+       php_addrinfo    *ai;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) {
+       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_THROWS();
-       }
+       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;
                        }
@@ -2488,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_THROWS();
-       }
-       if ((socket = (php_socket *) zend_fetch_resource(Z_RES_P(zsocket), le_socket_name, le_socket)) == NULL) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &arg1, socket_ce, &target_pid) == FAILURE) {
                RETURN_THROWS();
        }
 
+       socket = Z_SOCKET_P(arg1);
+       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);
@@ -2581,13 +2635,13 @@ 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));
 }
 /* }}} */
 
index 680a1b883559fb5ee06d7a2156dfb9073d225908..b3f0dcbbc216dbafe615710c6ac4d12fef34b499 100644 (file)
 
 /** @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 {}
 
-/** @return resource|false */
-function socket_create_listen(int $port, int $backlog = 128) {}
+function socket_create_listen(int $port, int $backlog = 128): Socket|false {}
 
-/**
- * @param resource $socket
- * @return resource|false
- */
-function socket_accept($socket) {}
+function socket_accept(Socket $socket): Socket|false {}
 
-/** @param resource $socket */
-function socket_set_nonblock($socket): bool {}
+function socket_set_nonblock(Socket $socket): bool {}
 
-/** @param resource $socket */
-function socket_set_block($socket): bool {}
+function socket_set_block(Socket $socket): bool {}
 
-/** @param resource $socket */
-function socket_listen($socket, int $backlog = 0): bool {}
+function socket_listen(Socket $socket, int $backlog = 0): bool {}
 
-/** @param resource $socket */
-function socket_close($socket): void {}
+function socket_close(Socket $socket): void {}
 
-/** @param resource $socket */
-function socket_write($socket, string $buf, int $length = UNKNOWN): int|false {}
+function socket_write(Socket $socket, string $buf, ?int $length = null): int|false {}
 
-/** @param resource $socket */
-function socket_read($socket, int $length, int $type = PHP_BINARY_READ): string|false {}
+function socket_read(Socket $socket, int $length, int $type = PHP_BINARY_READ): string|false {}
 
-/** @param resource $socket */
-function socket_getsockname($socket, &$addr, &$port = UNKNOWN): bool {}
+/**
+ * @param string $addr
+ * @param int $port
+ */
+function socket_getsockname(Socket $socket, &$addr, &$port = UNKNOWN): bool {}
 
-/** @param resource $socket */
-function socket_getpeername($socket, &$addr, &$port = UNKNOWN): bool {}
+/**
+ * @param string $addr
+ * @param int $port
+ */
+function socket_getpeername(Socket $socket, &$addr, &$port = UNKNOWN): bool {}
 
-/** @return resource|false */
-function socket_create(int $domain, int $type, int $protocol) {}
+function socket_create(int $domain, int $type, int $protocol): Socket|false {}
 
-/** @param resource $socket */
-function socket_connect($socket, string $addr, int $port = UNKNOWN): bool {}
+function socket_connect(Socket $socket, string $addr, ?int $port = null): bool {}
 
 function socket_strerror(int $errno): string {}
 
-/** @param resource $socket */
-function socket_bind($socket, string $addr, int $port = 0): bool {}
+function socket_bind(Socket $socket, string $addr, int $port = 0): bool {}
 
-/** @param resource $socket */
-function socket_recv($socket, &$buf, int $len, int $flags): int|false {}
+function socket_recv(Socket $socket, &$buf, int $len, int $flags): int|false {}
 
-/** @param resource $socket */
-function socket_send($socket, string $buf, int $len, int $flags): int|false {}
+function socket_send(Socket $socket, string $buf, int $len, int $flags): int|false {}
 
-/** @param resource $socket */
-function socket_recvfrom($socket, &$buf, int $len, int $flags, &$name, &$port = UNKNOWN): 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 {}
 
-/** @param resource $socket */
-function socket_sendto($socket, string $buf, int $len, int $flags, string $addr, int $port = 0): int|false {}
+function socket_sendto(Socket $socket, string $buf, int $len, int $flags, string $addr, ?int $port = null): int|false {}
 
-/** @param resource $socket */
-function socket_get_option($socket, int $level, int $optname): array|int|false {}
+function socket_get_option(Socket $socket, int $level, int $optname): array|int|false {}
 
-/**
- * @param resource $socket
- * @alias socket_get_option
- */
-function socket_getopt($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 resource $socket */
-function socket_set_option($socket, int $level, int $optname, $optval): bool {}
+/** @param array|string|int $optval */
+function socket_set_option(Socket $socket, int $level, int $optname, $optval): bool {}
 
 /**
- * @param resource $socket
+ * @param array|string|int $optval
  * @alias socket_set_option
  */
-function socket_setopt($socket, int $level, int $optname, $optval): bool {}
+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
-/** @param resource $socket */
-function socket_shutdown($socket, int $how = 2): bool {}
+function socket_shutdown(Socket $socket, int $how = 2): bool {}
 #endif
 
-/** @param resource $socket */
-function socket_last_error($socket = UNKNOWN): int {}
+function socket_last_error(?Socket $socket = null): int {}
 
-/** @param resource $socket */
-function socket_clear_error($socket = UNKNOWN): void {}
+function socket_clear_error(?Socket $socket = null): void {}
 
-/**
- * @param resource $stream
- * @return resource|false
- */
-function socket_import_stream($stream) {}
+/** @param resource $stream */
+function socket_import_stream($stream): Socket|false {}
 
-/**
- * @param resource $socket
- * @return resource|false
- */
-function socket_export_stream($socket) {}
+/** @return resource|false */
+function socket_export_stream(Socket $socket) {}
 
-/** @param resource $socket */
-function socket_sendmsg($socket, array $msghdr, int $flags = 0): int|false {}
+function socket_sendmsg(Socket $socket, array $msghdr, int $flags = 0): int|false {}
 
-/** @param resource $socket */
-function socket_recvmsg($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 = UNKNOWN, array $hints = UNKNOWN): array|false {}
+function socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = []): array|false {}
 
-/**
- * @param resource $addr
- * @return resource|false
- */
-function socket_addrinfo_connect($addr) {}
+function socket_addrinfo_connect(AddressInfo $addr): Socket|false {}
 
-/**
- * @param resource $addr
- * @return resource|false
- */
-function socket_addrinfo_bind($addr) {}
+function socket_addrinfo_bind(AddressInfo $addr): Socket|false {}
 
-/** @param resource $addr */
-function socket_addrinfo_explain($addr): array {}
+function socket_addrinfo_explain(AddressInfo $addr): array {}
 
 #ifdef PHP_WIN32
-/** @param resource $socket */
-function socket_wsaprotocol_info_export($socket, int $target_pid): string|false {}
+function socket_wsaprotocol_info_export(Socket $socket, int $target_pid): string|false {}
 
-/** @return resource|false */
-function socket_wsaprotocol_info_import(string $info_id) {}
+function socket_wsaprotocol_info_import(string $info_id): Socket|false {}
 
 function socket_wsaprotocol_info_release(string $info_id): bool {}
 #endif
index 36aa16733e17e6172f72f823252013ef90daa7d9..234b0c7982df05a49599781efef6e2a35c9c5a4e 100644 (file)
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 4494f9f246dbc98047d97d913cc1add9f91eb0ff */
+ * 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)
@@ -9,60 +9,60 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tv_usec, IS_LONG, 0, "0")
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_create_listen, 0, 0, 1)
+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_INFO_EX(arginfo_socket_accept, 0, 0, 1)
-       ZEND_ARG_INFO(0, socket)
+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_INFO(0, socket)
+       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_INFO(0, socket)
+       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_INFO(0, socket)
+       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_INFO(0, socket)
+       ZEND_ARG_OBJ_INFO(0, socket, Socket, 0)
        ZEND_ARG_TYPE_INFO(0, buf, IS_STRING, 0)
-       ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 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_INFO(0, socket)
+       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_INFO(0, socket)
+       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_INFO_EX(arginfo_socket_create, 0, 0, 3)
+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_INFO(0, socket)
+       ZEND_ARG_OBJ_INFO(0, socket, Socket, 0)
        ZEND_ARG_TYPE_INFO(0, addr, IS_STRING, 0)
-       ZEND_ARG_TYPE_INFO(0, port, IS_LONG, 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)
@@ -70,27 +70,27 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_strerror, 0, 1, IS_STRING
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_bind, 0, 2, _IS_BOOL, 0)
-       ZEND_ARG_INFO(0, socket)
+       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_INFO(0, socket)
+       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_INFO(0, socket)
+       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_INFO(0, socket)
+       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)
@@ -99,16 +99,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_recvfrom, 0, 5, MAY_BE_LO
 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_INFO(0, socket)
+       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, 0, "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_INFO(0, socket)
+       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()
@@ -116,7 +116,7 @@ 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_INFO(0, socket)
+       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)
@@ -135,33 +135,35 @@ ZEND_END_ARG_INFO()
 
 #if defined(HAVE_SHUTDOWN)
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_shutdown, 0, 1, _IS_BOOL, 0)
-       ZEND_ARG_INFO(0, socket)
+       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_INFO(0, socket)
+       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_INFO(0, socket)
+       ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, socket, Socket, 1, "null")
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_import_stream, 0, 0, 1)
+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()
 
-#define arginfo_socket_export_stream arginfo_socket_accept
+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_INFO(0, socket)
+       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_INFO(0, socket)
+       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()
@@ -174,29 +176,29 @@ 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(0, service, IS_STRING, 0)
-       ZEND_ARG_TYPE_INFO(0, hints, IS_ARRAY, 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_INFO_EX(arginfo_socket_addrinfo_connect, 0, 0, 1)
-       ZEND_ARG_INFO(0, addr)
+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_INFO(0, addr)
+       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_INFO(0, socket)
+       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_INFO_EX(arginfo_socket_wsaprotocol_info_import, 0, 0, 1)
+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
@@ -309,3 +311,13 @@ static const zend_function_entry ext_functions[] = {
 #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
+};
index 16e2e91b62c468e9406ab5d4073aa63f175583eb..28237f415ed0343a8e6ddc050f029fb12dead2cf 100644 (file)
@@ -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)
index 10233b49a57ea358b42fbc45813c7514841b12aa..3bc791a451a1c4058ffeff193f1d700527804aa3 100644 (file)
@@ -180,9 +180,11 @@ if ($i == 8) {
 }
 --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)
index 87b38c144c1c38780118adad6475e886976b199a..dda3756b7ea57817b0882a53f5df9f7684a72d6e 100644 (file)
@@ -108,9 +108,11 @@ if ($i == 3) {
 }
 --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)
index eb15afee25ac605e501e9464d1af85e83cb581ba..40a746bdb932f8e367e35b0f6df19f638e65cc52 100644 (file)
@@ -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
index 009d54839b7d0a965e063a6c8891bac6db8eadf4..a5a604ee61d9ef7ff70a6b2b866401fd44948a2a 100644 (file)
@@ -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
index 5ecd945f7107917c1a8b3f25956065d1c61f6619..8393eaa7efb9be61cfa08bf63f714f6eaba081e7 100644 (file)
@@ -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
index 09266e6cbd9688fdf17bf03f4ae134b0deac3a82..33f770510f840c137e2fb3b414399bc4af914e81 100644 (file)
@@ -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
index bd758abdf97aa1c267a0e50d9ac606b42595f9a4..7c7334ffcacc40d1211a0395e5af57f5dac4b1ad 100644 (file)
@@ -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) {
index ea7c4971d1fe00f7f1e463d7bed46f568ab185e8..608e5d1c2e517f175dde6ccfac447d2d215d817f 100644 (file)
@@ -17,22 +17,21 @@ socket_getsockname($s_c, $addr, $port);
 
 // wrong parameter count
 try {
-    $s_w = socket_connect($s_c);
+    socket_connect($s_c);
 } catch (\ArgumentCountError $e) {
     echo $e->getMessage() . \PHP_EOL;
 }
 try {
-    $s_w = socket_connect($s_c, '0.0.0.0');
+    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--
 socket_connect() expects at least 2 parameters, 1 given
-socket_connect(): Argument #3 ($port) must be specified for the AF_INET socket type
+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
index 2dfec4fbf79680b76ba0c76886472ddd15400b2c..5e5c587188a497652b18c0bb9962637a05c38dd4 100644 (file)
@@ -21,7 +21,8 @@ fa@php.net
     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)
index 6af6e42f202237292fad4ab478b475cb8b07ad39..604d5a2319044c72867736608b25db24ec72512b 100644 (file)
@@ -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) {
+  }
 }
index 65a2a7f7559f1dc1f854c7d5561dd6c2c5f26084..503db5b00404e4757617544849ec262a738cd843 100644 (file)
@@ -9,30 +9,31 @@ if (!extension_loaded('sockets')) {
 <?php
 
 try {
-    var_dump(socket_export_stream(fopen(__FILE__, "rb")));
+    socket_export_stream(fopen(__FILE__, "rb"));
 } catch (TypeError $e) {
     echo $e->getMessage(), "\n";
 }
 try {
-    var_dump(socket_export_stream(stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND)));
+    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);
+
 try {
     var_dump(socket_export_stream($s));
-} catch (TypeError $e) {
+} catch (Error $e) {
     echo $e->getMessage(), "\n";
 }
 
-
 echo "Done.";
 ?>
 --EXPECTF--
-socket_export_stream(): supplied resource is not a valid Socket resource
-socket_export_stream(): supplied resource is not a valid Socket resource
-resource(%d) of type (Socket)
-socket_export_stream(): supplied resource is not a valid Socket resource
+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.
index ac48d865b9eecdaa407a5b844b4a361e26d8c355..ed3b7f83e5a4582a341c97325843a6d634e01255 100644 (file)
@@ -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.
index 6acc88d16b8f86ba0542578811b19884dfe2fec5..7a38ba91294affddcfb0407eb05e71b3d48b28c7 100644 (file)
@@ -16,8 +16,8 @@ function test($stream, $sock) {
         echo "stream_set_blocking ";
         try {
             print_r(stream_set_blocking($stream, 0));
-        } catch (TypeError $e) {
-            echo $e->getMessage(), "\n";
+        } catch (Error $e) {
+            echo get_class($e), ": ", $e->getMessage(), "\n";
         }
         echo "\n";
     }
@@ -25,15 +25,15 @@ function test($stream, $sock) {
         echo "socket_set_block ";
         try {
             print_r(socket_set_block($sock));
-        } catch (TypeError $e) {
-            echo $e->getMessage(), "\n";
+        } 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 (TypeError $e) {
-            echo $e->getMessage(), "\n";
+        } catch (Error $e) {
+            echo get_class($e), ": ", $e->getMessage(), "\n";
         }
         echo "\n";
     }
@@ -92,7 +92,7 @@ stream_set_blocking 1
 
 
 close stream
-stream_set_blocking stream_set_blocking(): supplied resource is not a valid stream resource
+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
@@ -103,11 +103,11 @@ Warning: socket_get_option(): Unable to retrieve socket option [%d]: %s in %s on
 
 
 close socket
-stream_set_blocking stream_set_blocking(): supplied resource is not a valid stream resource
+stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource
 
-socket_set_block socket_set_block(): supplied resource is not a valid Socket resource
+socket_set_block Error: socket_set_block(): Argument #1 ($socket) has already been closed
 
-socket_get_option socket_get_option(): supplied resource is not a valid Socket resource
+socket_get_option Error: socket_get_option(): Argument #1 ($socket) has already been closed
 
 
 Done.
index 5a1d03fa6e0729b70abf3ff33a72174c196ff862..219fec5574cdcc56eb55b2535bf55ed6c84a5e95 100644 (file)
@@ -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
 
index 925966312da2612d3dd38210640ca2059bff36b2..8608af33d4b06bfa5251f1037e504a899573434b 100644 (file)
@@ -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"
index 37849f67ab4969b8d118ec1cab89d08e6d2d79dd..a16a3dc18a54aba06fef2556cac91ce5a22a6fab 100644 (file)
@@ -10,7 +10,7 @@ if (!extension_loaded('sockets')) {
 
 var_dump(socket_import_stream(fopen(__FILE__, "rb")));
 try {
-    var_dump(socket_import_stream(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)));
+    socket_import_stream(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP));
 } catch (TypeError $e) {
     echo $e->getMessage(), "\n";
 }
@@ -18,7 +18,7 @@ $s = stream_socket_server("udp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BI
 var_dump($s);
 var_dump(fclose($s));
 try {
-    var_dump(socket_import_stream($s));
+    socket_import_stream($s);
 } catch (TypeError $e) {
     echo $e->getMessage(), "\n";
 }
@@ -28,7 +28,7 @@ echo "Done.";
 --EXPECTF--
 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(): supplied resource is not a valid stream resource
+socket_import_stream(): Argument #1 ($stream) must be of type resource, Socket given
 resource(%d) of type (stream)
 bool(true)
 socket_import_stream(): supplied resource is not a valid stream resource
index 4f8668ec872d75938e30dafee7ef5c089671a1de..6f340a4e6cdd32ed44522b87e7901eff774077a1 100644 (file)
@@ -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.
index a4c38b5a1b1639f50f0e86dd4737dbafa0cce6cd..bd2ac05aefefb85301bb048df81a510225e55a43 100644 (file)
@@ -16,8 +16,8 @@ function test($stream, $sock) {
         echo "stream_set_blocking ";
         try {
             print_r(stream_set_blocking($stream, 0));
-        } catch (TypeError $e) {
-            echo $e->getMessage(), "\n";
+        } catch (Error $e) {
+            echo get_class($e), ": ", $e->getMessage(), "\n";
         }
         echo "\n";
     }
@@ -25,15 +25,15 @@ function test($stream, $sock) {
         echo "socket_set_block ";
         try {
             print_r(socket_set_block($sock));
-        } catch (TypeError $e) {
-            echo $e->getMessage(), "\n";
+        } 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 (TypeError $e) {
-            echo $e->getMessage(), "\n";
+        } catch (Error $e) {
+            echo get_class($e), ": ", $e->getMessage(), "\n";
         }
         echo "\n";
     }
@@ -87,7 +87,7 @@ stream_set_blocking 1
 
 
 close stream
-stream_set_blocking stream_set_blocking(): supplied resource is not a valid stream resource
+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
@@ -98,11 +98,11 @@ Warning: socket_get_option(): Unable to retrieve socket option [%d]: %s in %s on
 
 
 close socket
-stream_set_blocking stream_set_blocking(): supplied resource is not a valid stream resource
+stream_set_blocking TypeError: stream_set_blocking(): supplied resource is not a valid stream resource
 
-socket_set_block socket_set_block(): supplied resource is not a valid Socket resource
+socket_set_block Error: socket_set_block(): Argument #1 ($socket) has already been closed
 
-socket_get_option socket_get_option(): supplied resource is not a valid Socket resource
+socket_get_option Error: socket_get_option(): Argument #1 ($socket) has already been closed
 
 
 Done.
index b3fbadc054d937cedae4cd32e651f255171c06f9..5eaf579854499cc5eee45bd1c56f2ced70fea31b 100644 (file)
@@ -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
 
index 2d7a2f0d694c97f74d1fcae33456d45aa256f844..21f7b730587e99d7f7b6c18bf5684152191b20a9 100644 (file)
@@ -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
index d45bc4c44a7170be5154aeb50b78207bb7c04901..601ddb4efa3434441472ee7f0494233a016cc026 100644 (file)
@@ -11,10 +11,14 @@ $sockets = null;
 $write   = null;
 $except  = null;
 $time    = 0;
-var_dump(socket_select($sockets, $write, $except, $time));
+
+try {
+    socket_select($sockets, $write, $except, $time);
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
 --EXPECTF--
-Warning: socket_select(): No resource arrays were passed to select in %s on line %d
-bool(false)
+socket_select(): At least one array argument must be passed
 --CREDITS--
 Till Klampaeckel, till@php.net
 Berlin TestFest 2009
index 48acb330200eba1beff4c745a021fcfaea55014f..645707467dc1c30438d09fd57d74f3c78b1cd6f5 100644 (file)
@@ -14,4 +14,4 @@ try {
 }
 ?>
 --EXPECT--
-socket_select(): supplied argument is not a valid Socket resource
+socket_select(): Argument #1 ($read_fds) must only have elements of type Socket, string given
index 2de272356a133d7f27c038b91ddc9ee61b3f051c..107aa626e81c95cb1d3cc11b1a278cef255e573e 100644 (file)
@@ -62,10 +62,12 @@ 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
index ff61d3a230dd9100b2b8537231ed2853869f4d34..b4ba00debe414bcbce2afecf9894635dfb3ee875 100644 (file)
@@ -56,10 +56,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(11)
 Array
index 89dcc7ab4f47ad0a4988f2ecad5d55d942a05276..00ec7038de501497caf8c54186835f987b87c96b 100644 (file)
@@ -17,14 +17,11 @@ $socket2 = socket_create_listen(31340);
 socket_close($socket2);
 try {
     var_dump(socket_set_block($socket2));
-} catch (TypeError $e) {
+} catch (Error $e) {
     echo $e->getMessage(), "\n";
 }
 
 ?>
 --EXPECT--
 bool(true)
-socket_set_block(): supplied resource is not a valid Socket resource
---CREDITS--
-Robin Mehner, robin@coding-robin.de
-PHP Testfest Berlin 2009-05-09
+socket_set_block(): Argument #1 ($socket) has already been closed
index fb0e593810b540dc1d9d51ef2f7504292785c57b..6df652132453d0b055481c1f2fcb7bd6afa1a32b 100644 (file)
@@ -17,14 +17,11 @@ $socket2 = socket_create_listen(31340);
 socket_close($socket2);
 try {
     var_dump(socket_set_nonblock($socket2));
-} catch (TypeError $e) {
+} catch (Error $e) {
     echo $e->getMessage(), "\n";
 }
 
 ?>
 --EXPECT--
 bool(true)
-socket_set_nonblock(): supplied resource is not a valid Socket resource
---CREDITS--
-Robin Mehner, robin@coding-robin.de
-PHP Testfest Berlin 2009-05-09
+socket_set_nonblock(): Argument #1 ($socket) has already been closed
index 88f29d928e8d5ae797084ad0774f5082e19e938c..46d673232e1ac1d4124ec12b47742042a7699747 100644 (file)
@@ -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) {
+}
index 3e251914ed0ac6354c13603d2d99894bcff8a78d..efe1728f838ed1a7cb1da9c04e48db77ee3f088a 100644 (file)
@@ -48,9 +48,12 @@ if (!extension_loaded('sockets')) {
 ?>
 --EXPECTF--
 bool(true)
-resource(%d) of type (Socket)
-resource(%d) of type (Socket)
-resource(%d) of type (Socket)
+object(Socket)#%d (0) {
+}
+object(Socket)#%d (0) {
+}
+object(Socket)#%d (0) {
+}
 resource(%d) of type (Unknown)
 
 Warning: socket_wsaprotocol_info_export(): Unable to export WSA protocol info [0x00002726]: %s