]> granicus.if.org Git - php/commitdiff
Refactoring socket (only compilable now)
authorXinchen Hui <laruence@php.net>
Sat, 17 May 2014 02:23:46 +0000 (10:23 +0800)
committerXinchen Hui <laruence@php.net>
Sat, 17 May 2014 02:23:46 +0000 (10:23 +0800)
ext/sockets/conversions.c
ext/sockets/conversions.h
ext/sockets/multicast.c
ext/sockets/multicast.h
ext/sockets/php_sockets.h
ext/sockets/sendrecvmsg.c
ext/sockets/sendrecvmsg.h
ext/sockets/sockets.c

index d81484521d8c018f1c10c1b140a94b7f922427d6..ff96e95c4c7e95783e2a680bd868aa512a1c6fcd 100644 (file)
@@ -106,9 +106,9 @@ const struct key_value empty_key_value_list[] = {{0}};
 /* PARAMETERS */
 static int param_get_bool(void *ctx, const char *key, int def)
 {
-       int **elem;
-       if (zend_hash_find(ctx, key, strlen(key) + 1, (void**)&elem) == SUCCESS) {
-               return **elem;
+       int *elem;
+       if ((elem = zend_hash_str_find_ptr(ctx, key, strlen(key))) != NULL) {
+               return *elem;
        } else {
                return def;
        }
@@ -159,8 +159,8 @@ static void do_from_to_zval_err(struct err_s *err,
                smart_str_appends(&path, " > ");
        }
 
-       if (path.len > 3) {
-               path.len -= 3;
+       if (path.s && path.s->len > 3) {
+               path.s->len -= 3;
        }
        smart_str_0(&path);
 
@@ -170,7 +170,7 @@ static void do_from_to_zval_err(struct err_s *err,
        err->level = E_WARNING;
        spprintf(&err->msg, 0, "error converting %s data (path: %s): %.*s",
                        what_conv,
-                       path.c && path.c != '\0' ? path.c : "unavailable",
+                       path.s && *path.s->val != '\0' ? path.s->val : "unavailable",
                        user_msg_size, user_msg);
        err->should_free = 1;
 
@@ -213,20 +213,20 @@ void allocations_dispose(zend_llist **allocations)
 }
 
 static unsigned from_array_iterate(const zval *arr,
-                                                                  void (*func)(zval **elem, unsigned i, void **args, ser_context *ctx),
+                                                                  void (*func)(zval *elem, unsigned i, void **args, ser_context *ctx),
                                                                   void **args,
                                                                   ser_context *ctx)
 {
        HashPosition    pos;
        unsigned                i;
-       zval                    **elem;
+       zval                    *elem;
        char                    buf[sizeof("element #4294967295")];
        char                    *bufp = buf;
 
        /* Note i starts at 1, not 0! */
     for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 1;
                        !ctx->err.has_error
-                       && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
+                       && (elem = zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), &pos)) != NULL;
                        zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos), i++) {
                if (snprintf(buf, sizeof(buf), "element #%u", i) >= sizeof(buf)) {
                        memcpy(buf, "element", sizeof("element"));
@@ -248,15 +248,15 @@ static void from_zval_write_aggregation(const zval *container,
                                                                                ser_context *ctx)
 {
        const field_descriptor  *descr;
-       zval                                    **elem;
+       zval                                    *elem;
 
        if (Z_TYPE_P(container) != IS_ARRAY) {
                do_from_zval_err(ctx, "%s", "expected an array here");
        }
 
        for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
-               if (zend_hash_find(Z_ARRVAL_P(container),
-                               descr->name, descr->name_size, (void**)&elem) == SUCCESS) {
+               if ((elem = zend_hash_str_find(Z_ARRVAL_P(container),
+                               descr->name, descr->name_size - 1)) != NULL) {
 
                        if (descr->from_zval == NULL) {
                                do_from_zval_err(ctx, "No information on how to convert value "
@@ -265,7 +265,7 @@ static void from_zval_write_aggregation(const zval *container,
                        }
 
                        zend_llist_add_element(&ctx->keys, (void*)&descr->name);
-                       descr->from_zval(*elem, ((char*)structure) + descr->field_offset, ctx);
+                       descr->from_zval(elem, ((char*)structure) + descr->field_offset, ctx);
                        zend_llist_remove_tail(&ctx->keys);
 
                } else if (descr->required) {
@@ -285,7 +285,7 @@ static void to_zval_read_aggregation(const char *structure,
        assert(Z_ARRVAL_P(zarr) != NULL);
 
        for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
-               zval *new_zv;
+               zval *new_zv, tmp;
 
                if (descr->to_zval == NULL) {
                        do_to_zval_err(ctx, "No information on how to convert native "
@@ -293,8 +293,8 @@ static void to_zval_read_aggregation(const char *structure,
                        break;
                }
 
-               ALLOC_INIT_ZVAL(new_zv);
-               add_assoc_zval_ex(zarr, descr->name, descr->name_size, new_zv);
+               ZVAL_NULL(&tmp);
+               new_zv = zend_symtable_str_update(Z_ARRVAL_P(zarr), descr->name, descr->name_size - 1, &tmp);
 
                zend_llist_add_element(&ctx->keys, (void*)&descr->name);
                descr->to_zval(structure + descr->field_offset, new_zv, ctx);
@@ -306,11 +306,10 @@ static void to_zval_read_aggregation(const char *structure,
 static long from_zval_integer_common(const zval *arr_value, ser_context *ctx)
 {
        long ret = 0;
-       zval lzval = zval_used_for_init;
+       zval lzval;
 
        if (Z_TYPE_P(arr_value) != IS_LONG) {
-               ZVAL_COPY_VALUE(&lzval, arr_value);
-               zval_copy_ctor(&lzval);
+               ZVAL_COPY(&lzval, arr_value);
                arr_value = &lzval;
        }
 
@@ -336,14 +335,12 @@ double_case:
                switch (is_numeric_string(Z_STRVAL(lzval), Z_STRLEN(lzval), &lval, &dval, 0)) {
                case IS_DOUBLE:
                        zval_dtor(&lzval);
-                       Z_TYPE(lzval) = IS_DOUBLE;
-                       Z_DVAL(lzval) = dval;
+                       ZVAL_DOUBLE(&lzval, dval);
                        goto double_case;
 
                case IS_LONG:
                        zval_dtor(&lzval);
-                       Z_TYPE(lzval) = IS_LONG;
-                       Z_LVAL(lzval) = lval;
+                       ZVAL_LONG(&lzval, lval);
                        goto long_case;
                }
 
@@ -542,12 +539,12 @@ static void from_zval_write_sin_addr(const zval *zaddr_str, char *inaddr, ser_co
 {
        int                                     res;
        struct sockaddr_in      saddr = {0};
-       zval                            lzval = zval_used_for_init;
+       zval                            lzval;
        TSRMLS_FETCH();
 
+       ZVAL_NULL(&lzval);
        if (Z_TYPE_P(zaddr_str) != IS_STRING) {
-               ZVAL_COPY_VALUE(&lzval, zaddr_str);
-               zval_copy_ctor(&lzval);
+               ZVAL_COPY(&lzval, zaddr_str);
                convert_to_string(&lzval);
                zaddr_str = &lzval;
        }
@@ -567,10 +564,10 @@ static void to_zval_read_sin_addr(const char *data, zval *zv, res_context *ctx)
 {
        const struct in_addr *addr = (const struct in_addr *)data;
        socklen_t size = INET_ADDRSTRLEN;
+       zend_string *str = STR_ALLOC(size - 1, 0);
+       memset(str->val, '\0', size);
 
-       Z_TYPE_P(zv) = IS_STRING;
-       Z_STRVAL_P(zv) = ecalloc(1, size);
-       Z_STRLEN_P(zv) = 0;
+       ZVAL_STR(zv, str);
 
        if (inet_ntop(AF_INET, addr, Z_STRVAL_P(zv), size) == NULL) {
                do_to_zval_err(ctx, "could not convert IPv4 address to string "
@@ -599,12 +596,12 @@ static void from_zval_write_sin6_addr(const zval *zaddr_str, char *addr6, ser_co
 {
        int                                     res;
        struct sockaddr_in6     saddr6 = {0};
-       zval                            lzval = zval_used_for_init;
+       zval                            lzval;
        TSRMLS_FETCH();
 
+       ZVAL_NULL(&lzval);
        if (Z_TYPE_P(zaddr_str) != IS_STRING) {
-               ZVAL_COPY_VALUE(&lzval, zaddr_str);
-               zval_copy_ctor(&lzval);
+               ZVAL_COPY(&lzval, zaddr_str);
                convert_to_string(&lzval);
                zaddr_str = &lzval;
        }
@@ -625,10 +622,11 @@ static void to_zval_read_sin6_addr(const char *data, zval *zv, res_context *ctx)
 {
        const struct in6_addr *addr = (const struct in6_addr *)data;
        socklen_t size = INET6_ADDRSTRLEN;
+       zend_string *str = STR_ALLOC(size - 1, 0);
 
-       Z_TYPE_P(zv) = IS_STRING;
-       Z_STRVAL_P(zv) = ecalloc(1, size);
-       Z_STRLEN_P(zv) = 0;
+       memset(str->val, '\0', size);
+
+       ZVAL_STR(zv, str);
 
        if (inet_ntop(AF_INET6, addr, Z_STRVAL_P(zv), size) == NULL) {
                do_to_zval_err(ctx, "could not convert IPv6 address to string "
@@ -657,12 +655,12 @@ static void to_zval_read_sockaddr_in6(const char *data, zval *zv, res_context *c
 #endif /* HAVE_IPV6 */
 static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_context *ctx)
 {
-       zval                            lzval = zval_used_for_init;
+       zval                            lzval;
        struct sockaddr_un      *saddr = (struct sockaddr_un*)sockaddr_un_c;
 
+       ZVAL_NULL(&lzval);
        if (Z_TYPE_P(path) != IS_STRING) {
-               ZVAL_COPY_VALUE(&lzval, path);
-               zval_copy_ctor(&lzval);
+               ZVAL_COPY(&lzval, path);
                convert_to_string(&lzval);
                path = &lzval;
        }
@@ -695,7 +693,7 @@ static void to_zval_read_sun_path(const char *data, zval *zv, res_context *ctx)
                return;
        }
 
-       ZVAL_STRINGL(zv, saddr->sun_path, nul_pos - (char*)&saddr->sun_path, 1);
+       ZVAL_STRINGL(zv, saddr->sun_path, nul_pos - (char*)&saddr->sun_path);
 }
 static const field_descriptor descriptors_sockaddr_un[] = {
                {"family", sizeof("family"), 0, offsetof(struct sockaddr_un, sun_family), from_zval_write_sa_family, to_zval_read_sa_family},
@@ -716,7 +714,7 @@ static void from_zval_write_sockaddr_aux(const zval *container,
                                                                                 ser_context *ctx)
 {
        int             family;
-       zval    **elem;
+       zval    *elem;
        int             fill_sockaddr;
 
        if (Z_TYPE_P(container) != IS_ARRAY) {
@@ -726,11 +724,11 @@ static void from_zval_write_sockaddr_aux(const zval *container,
 
        fill_sockaddr = param_get_bool(ctx, KEY_FILL_SOCKADDR, 1);
 
-       if (zend_hash_find(Z_ARRVAL_P(container), "family", sizeof("family"), (void**)&elem) == SUCCESS
-                       && Z_TYPE_PP(elem) != IS_NULL) {
+       if ((elem = zend_hash_str_find(Z_ARRVAL_P(container), "family", sizeof("family") - 1)) != NULL
+                       && Z_TYPE_P(elem) != IS_NULL) {
                const char *node = "family";
                zend_llist_add_element(&ctx->keys, &node);
-               from_zval_write_int(*elem, (char*)&family, ctx);
+               from_zval_write_int(elem, (char*)&family, ctx);
                zend_llist_remove_tail(&ctx->keys);
        } else {
                family = ctx->sock->type;
@@ -889,14 +887,13 @@ static void from_zval_write_control(const zval                    *arr,
        }
 
        if (entry->calc_space) {
-               zval **data_elem;
+               zval *data_elem;
                /* arr must be an array at this point */
-               if (zend_hash_find(Z_ARRVAL_P(arr), "data", sizeof("data"),
-                               (void**)&data_elem) == FAILURE) {
+               if ((data_elem = zend_hash_str_find(Z_ARRVAL_P(arr), "data", sizeof("data") - 1)) == NULL) {
                        do_from_zval_err(ctx, "cmsghdr should have a 'data' element here");
                        return;
                }
-               data_len = entry->calc_space(*data_elem, ctx);
+               data_len = entry->calc_space(data_elem, ctx);
                if (ctx->err.has_error) {
                        return;
                }
@@ -926,10 +923,9 @@ static void from_zval_write_control(const zval                     *arr,
 }
 static void from_zval_write_control_array(const zval *arr, char *msghdr_c, ser_context *ctx)
 {
-       HashPosition            pos;
        char                            buf[sizeof("element #4294967295")];
        char                            *bufp = buf;
-       zval                            **elem;
+       zval                            *elem;
        uint32_t                        i;
        int                                     num_elems;
        void                            *control_buf;
@@ -954,21 +950,20 @@ static void from_zval_write_control_array(const zval *arr, char *msghdr_c, ser_c
        control_len = (size_t)num_elems * CMSG_SPACE(20);
        cur_offset      = 0;
 
-    for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 0;
-                       !ctx->err.has_error
-                       && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
-                       zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos)) {
+       ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), elem) {
+               if (ctx->err.has_error) {
+                       break;
+               }
 
                if (snprintf(buf, sizeof(buf), "element #%u", (unsigned)i++) >= sizeof(buf)) {
                        memcpy(buf, "element", sizeof("element"));
                }
                zend_llist_add_element(&ctx->keys, &bufp);
 
-               from_zval_write_control(*elem, &control_buf, alloc, &control_len,
-                               &cur_offset, ctx);
+               from_zval_write_control(elem, &control_buf, alloc, &control_len, &cur_offset, ctx);
 
                zend_llist_remove_tail(&ctx->keys);
-    }
+       } ZEND_HASH_FOREACH_END();
 
     msg->msg_control = control_buf;
     msg->msg_controllen = cur_offset; /* not control_len, which may be larger */
@@ -994,15 +989,15 @@ static void to_zval_read_cmsg_data(const char *cmsghdr_c, zval *zv, res_context
        }
 
        len = (size_t)cmsg->cmsg_len; /* use another var because type of cmsg_len varies */
-       if (zend_hash_add(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN),
-                       &len_p, sizeof(len_p), NULL) == FAILURE) {
+       //????? len_p point to stack value len 
+       if (zend_hash_str_add_ptr(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN) - 1, len_p) == NULL) {
                do_to_zval_err(ctx, "%s", "could not set parameter " KEY_CMSG_LEN);
                return;
        }
 
        entry->to_array((const char *)CMSG_DATA(cmsg), zv, ctx);
 
-       zend_hash_del(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN));
+       zend_hash_str_del(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN) - 1);
 }
 static void to_zval_read_control(const char *cmsghdr_c, zval *zv, res_context *ctx)
 {
@@ -1037,10 +1032,10 @@ static void to_zval_read_control_array(const char *msghdr_c, zval *zv, res_conte
        for (cmsg = CMSG_FIRSTHDR(msg);
                        cmsg != NULL && !ctx->err.has_error;
                        cmsg = CMSG_NXTHDR(msg, cmsg)) {
-               zval *elem;
+               zval *elem, tmp;
 
-               ALLOC_INIT_ZVAL(elem);
-               add_next_index_zval(zv, elem);
+               ZVAL_NULL(&tmp);
+               elem = zend_hash_next_index_insert(Z_ARRVAL_P(zv), &tmp);
 
                if (snprintf(buf, sizeof(buf), "element #%u", (unsigned)i++) >= sizeof(buf)) {
                        memcpy(buf, "element", sizeof("element"));
@@ -1095,18 +1090,20 @@ static void from_zval_write_msghdr_buffer_size(const zval *elem, char *msghdr_c,
        msghdr->msg_iov[0].iov_base = accounted_emalloc((size_t)lval, ctx);
        msghdr->msg_iov[0].iov_len = (size_t)lval;
 }
-static void from_zval_write_iov_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
+static void from_zval_write_iov_array_aux(zval *elem, unsigned i, void **args, ser_context *ctx)
 {
        struct msghdr   *msg = args[0];
        size_t                  len;
 
-       zval_add_ref(elem);
+       if (Z_REFCOUNTED_P(elem)) {
+               Z_ADDREF_P(elem);
+       }
        convert_to_string_ex(elem);
 
-       len = Z_STRLEN_PP(elem);
+       len = Z_STRLEN_P(elem);
        msg->msg_iov[i - 1].iov_base = accounted_emalloc(len, ctx);
        msg->msg_iov[i - 1].iov_len = len;
-       memcpy(msg->msg_iov[i - 1].iov_base, Z_STRVAL_PP(elem), len);
+       memcpy(msg->msg_iov[i - 1].iov_base, Z_STRVAL_P(elem), len);
 
        zval_ptr_dtor(elem);
 }
@@ -1183,15 +1180,14 @@ void from_zval_write_msghdr_recv(const zval *container, char *msghdr_c, ser_cont
        const int               falsev = 0,
                                        *falsevp = &falsev;
 
-       if (zend_hash_add(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR),
-                       (void*)&falsevp, sizeof(falsevp), NULL) == FAILURE) {
+       if (zend_hash_str_add_ptr(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR) - 1, (void *)falsevp) == NULL) {
                do_from_zval_err(ctx, "could not add fill_sockaddr; this is a bug");
                return;
        }
 
        from_zval_write_aggregation(container, msghdr_c, descriptors, ctx);
 
-       zend_hash_del(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR));
+       zend_hash_str_del(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR) - 1);
        if (ctx->err.has_error) {
                return;
        }
@@ -1208,7 +1204,7 @@ static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx)
 {
        const struct msghdr     *msghdr = (const struct msghdr *)msghdr_c;
        size_t                          iovlen = msghdr->msg_iovlen;
-       ssize_t                         **recvmsg_ret,
+       ssize_t                         *recvmsg_ret,
                                                bytes_left;
        uint                            i;
 
@@ -1218,24 +1214,22 @@ static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx)
        }
        array_init_size(zv, (uint)iovlen);
 
-       if (zend_hash_find(&ctx->params, KEY_RECVMSG_RET, sizeof(KEY_RECVMSG_RET),
-                       (void**)&recvmsg_ret) == FAILURE) {
+       if ((recvmsg_ret = zend_hash_str_find_ptr(&ctx->params, KEY_RECVMSG_RET, sizeof(KEY_RECVMSG_RET) - 1)) == NULL) {
                do_to_zval_err(ctx, "recvmsg_ret not found in params. This is a bug");
                return;
        }
-       bytes_left = **recvmsg_ret;
+       bytes_left = *recvmsg_ret;
 
        for (i = 0; bytes_left > 0 && i < (uint)iovlen; i++) {
-               zval    *elem;
-               size_t  len             = MIN(msghdr->msg_iov[i].iov_len, (size_t)bytes_left);
-               char    *buf    = safe_emalloc(1, len, 1);
+               zval elem;
+               size_t len = MIN(msghdr->msg_iov[i].iov_len, (size_t)bytes_left);
+               zend_string     *buf = STR_ALLOC(len, 0);
 
-               MAKE_STD_ZVAL(elem);
-               memcpy(buf, msghdr->msg_iov[i].iov_base, len);
-               buf[len] = '\0';
+               memcpy(buf->val, msghdr->msg_iov[i].iov_base, buf->len);
+               buf->val[buf->len] = '\0';
 
-               ZVAL_STRINGL(elem, buf, len, 0);
-               add_next_index_zval(zv, elem);
+               ZVAL_STR(&elem, buf);
+               add_next_index_zval(zv, &elem);
                bytes_left -= len;
        }
 }
@@ -1258,7 +1252,9 @@ void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx)
 static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context *ctx)
 {
        unsigned        ret = 0;
-       zval            lzval = zval_used_for_init;
+       zval            lzval;
+
+       ZVAL_NULL(&lzval);
 
        if (Z_TYPE_P(zv) == IS_LONG) {
                if (Z_LVAL_P(zv) < 0 || Z_LVAL_P(zv) > UINT_MAX) { /* allow 0 (unspecified interface) */
@@ -1374,12 +1370,12 @@ size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx)
 
        return zend_hash_num_elements(Z_ARRVAL_P(arr)) * sizeof(int);
 }
-static void from_zval_write_fd_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
+static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, ser_context *ctx)
 {
        int *iarr = args[0];
        TSRMLS_FETCH();
 
-       if (Z_TYPE_PP(elem) == IS_RESOURCE) {
+       if (Z_TYPE_P(elem) == IS_RESOURCE) {
                php_stream *stream;
                php_socket *sock;
 
@@ -1417,7 +1413,7 @@ void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx)
 }
 void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
 {
-       size_t                  **cmsg_len;
+       size_t                  *cmsg_len;
        int                             num_elems,
                                        i;
        struct cmsghdr  *dummy_cmsg = 0;
@@ -1427,46 +1423,42 @@ void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
        data_offset = (unsigned char *)CMSG_DATA(dummy_cmsg)
                        - (unsigned char *)dummy_cmsg;
 
-       if (zend_hash_find(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN),
-                       (void **)&cmsg_len) == FAILURE) {
+       if ((cmsg_len = zend_hash_str_find_ptr(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN) - 1)) == NULL) {
                do_to_zval_err(ctx, "could not get value of parameter " KEY_CMSG_LEN);
                return;
        }
 
-       if (**cmsg_len < data_offset) {
+       if (*cmsg_len < data_offset) {
                do_to_zval_err(ctx, "length of cmsg is smaller than its data member "
-                               "offset (%ld vs %ld)", (long)**cmsg_len, (long)data_offset);
+                               "offset (%ld vs %ld)", (long)*cmsg_len, (long)data_offset);
                return;
        }
-       num_elems = (**cmsg_len - data_offset) / sizeof(int);
+       num_elems = (*cmsg_len - data_offset) / sizeof(int);
 
        array_init_size(zv, num_elems);
 
        for (i = 0; i < num_elems; i++) {
-               zval            *elem;
+               zval            elem;
                int                     fd;
                struct stat     statbuf;
 
-               MAKE_STD_ZVAL(elem);
-
                fd = *((int *)data + i);
 
                /* determine whether we have a socket */
                if (fstat(fd, &statbuf) == -1) {
                        do_to_zval_err(ctx, "error creating resource for received file "
                                        "descriptor %d: fstat() call failed with errno %d", fd, errno);
-                       efree(elem);
                        return;
                }
                if (S_ISSOCK(statbuf.st_mode)) {
                        php_socket *sock = socket_import_file_descriptor(fd TSRMLS_CC);
-                       zend_register_resource(elem, sock, php_sockets_le_socket() TSRMLS_CC);
+                       zend_register_resource(&elem, sock, php_sockets_le_socket() TSRMLS_CC);
                } else {
                        php_stream *stream = php_stream_fopen_from_fd(fd, "rw", NULL);
-                       php_stream_to_zval(stream, elem);
+                       php_stream_to_zval(stream, &elem);
                }
 
-               add_next_index_zval(zv, elem);
+               add_next_index_zval(zv, &elem);
        }
 }
 #endif
@@ -1524,38 +1516,35 @@ zval *to_zval_run_conversions(const char *structure,
                                                          to_zval_read_field *reader,
                                                          const char *top_name,
                                                          const struct key_value *key_value_pairs,
-                                                         struct err_s *err)
+                                                         struct err_s *err, zval *zv)
 {
        res_context                             ctx = {{0}, {0}};
        const struct key_value  *kv;
-       zval                                    *zv = NULL;
 
        if (err->has_error) {
                return NULL;
        }
 
-       ALLOC_INIT_ZVAL(zv);
-
        zend_llist_init(&ctx.keys, sizeof(const char *), NULL, 0);
        zend_llist_add_element(&ctx.keys, &top_name);
 
        zend_hash_init(&ctx.params, 8, NULL, NULL, 0);
        for (kv = key_value_pairs; kv->key != NULL; kv++) {
-               zend_hash_update(&ctx.params, kv->key, kv->key_size,
-                               (void*)&kv->value, sizeof(kv->value), NULL);
+               zend_hash_str_update_ptr(&ctx.params, kv->key, kv->key_size - 1, kv->value);
        }
 
+       ZVAL_NULL(zv);
        /* main call */
        reader(structure, zv, &ctx);
 
        if (ctx.err.has_error) {
-               zval_ptr_dtor(&zv);
-               zv = NULL;
+               zval_ptr_dtor(zv);
+               ZVAL_UNDEF(zv);
                *err = ctx.err;
        }
 
        zend_llist_destroy(&ctx.keys);
        zend_hash_destroy(&ctx.params);
 
-       return zv;
+       return Z_ISUNDEF_P(zv)? NULL : zv;
 }
index 7d515246a0bc66c08e407463420d0a3bed40e9c2..42e98882f4f0b35c919fc9bcb0d6a12fb68adb29 100644 (file)
@@ -79,6 +79,6 @@ zval *to_zval_run_conversions(const char                              *structure,
                                                          to_zval_read_field            *reader,
                                                          const char                            *top_name,
                                                          const struct key_value        *key_value_pairs,
-                                                         struct err_s                          *err);
+                                                         struct err_s                          *err, zval *zv);
 
 #endif
index ec8e16ce45f31893b6e5f660760462811c1a5ea0..2bc86b1dba90345b74f24ab6d912b67642ef3c85 100644 (file)
@@ -100,10 +100,12 @@ static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
                        ret = SUCCESS;
                }
        } else {
-               zval_add_ref(&val);
-               convert_to_string_ex(&val);
+               if (Z_REFCOUNTED_P(val)) {
+                       Z_ADDREF_P(val);
+               }
+               convert_to_string_ex(val);
                ret = php_string_to_if_index(Z_STRVAL_P(val), out TSRMLS_CC);
-               zval_ptr_dtor(&val);
+               zval_ptr_dtor(val);
        }
 
        return ret;
@@ -114,38 +116,38 @@ static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
 static int php_get_if_index_from_array(const HashTable *ht, const char *key,
        php_socket *sock, unsigned int *if_index TSRMLS_DC)
 {
-       zval **val;
+       zval *val;
 
-       if (zend_hash_find(ht, key, strlen(key) + 1, (void **)&val) == FAILURE) {
+       if ((val = zend_hash_str_find(ht, key, strlen(key))) == NULL) {
                *if_index = 0; /* default: 0 */
                return SUCCESS;
        }
 
-       return php_get_if_index_from_zval(*val, if_index TSRMLS_CC);
+       return php_get_if_index_from_zval(val, if_index TSRMLS_CC);
 }
 
 static int php_get_address_from_array(const HashTable *ht, const char *key,
        php_socket *sock, php_sockaddr_storage *ss, socklen_t *ss_len TSRMLS_DC)
 {
-       zval **val,
-                *valcp;
+       zval *val;
 
-       if (zend_hash_find(ht, key, strlen(key) + 1, (void **)&val) == FAILURE) {
+       if ((val = zend_hash_str_find(ht, key, strlen(key))) == NULL) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", key);
                return FAILURE;
        }
-       valcp = *val;
-       zval_add_ref(&valcp);
+       if (Z_REFCOUNTED_P(val)) {
+               Z_ADDREF_P(val);
+       }
        convert_to_string_ex(val);
-       if (!php_set_inet46_addr(ss, ss_len, Z_STRVAL_P(valcp), sock TSRMLS_CC)) {
-               zval_ptr_dtor(&valcp);
+       if (!php_set_inet46_addr(ss, ss_len, Z_STRVAL_P(val), sock TSRMLS_CC)) {
+               zval_ptr_dtor(val);
                return FAILURE;
        }
-       zval_ptr_dtor(&valcp);
+       zval_ptr_dtor(val);
        return SUCCESS;
 }
 
-static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC)
+static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval *arg4 TSRMLS_DC)
 {
        HashTable                               *opt_ht;
        unsigned int                    if_index;
@@ -169,7 +171,7 @@ static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval *
                        mcast_req_fun = &php_mcast_leave;
 mcast_req_fun:
                        convert_to_array_ex(arg4);
-                       opt_ht = HASH_OF(*arg4);
+                       opt_ht = HASH_OF(arg4);
 
                        if (php_get_address_from_array(opt_ht, "group", php_sock, &group,
                                &glen TSRMLS_CC) == FAILURE) {
@@ -205,7 +207,7 @@ mcast_req_fun:
                        mcast_sreq_fun = &php_mcast_leave_source;
                mcast_sreq_fun:
                        convert_to_array_ex(arg4);
-                       opt_ht = HASH_OF(*arg4);
+                       opt_ht = HASH_OF(arg4);
 
                        if (php_get_address_from_array(opt_ht, "group", php_sock, &group,
                                        &glen TSRMLS_CC) == FAILURE) {
@@ -244,7 +246,7 @@ mcast_req_fun:
 int php_do_setsockopt_ip_mcast(php_socket *php_sock,
                                                           int level,
                                                           int optname,
-                                                          zval **arg4 TSRMLS_DC)
+                                                          zval *arg4 TSRMLS_DC)
 {
        unsigned int    if_index;
        struct in_addr  if_addr;
@@ -269,7 +271,7 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock,
                }
 
        case IP_MULTICAST_IF:
-               if (php_get_if_index_from_zval(*arg4, &if_index TSRMLS_CC) == FAILURE) {
+               if (php_get_if_index_from_zval(arg4, &if_index TSRMLS_CC) == FAILURE) {
                        return FAILURE;
                }
 
@@ -282,17 +284,17 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock,
 
        case IP_MULTICAST_LOOP:
                convert_to_boolean_ex(arg4);
-               ipv4_mcast_ttl_lback = (unsigned char) (Z_TYPE_PP(arg4) == IS_TRUE);
+               ipv4_mcast_ttl_lback = (unsigned char) (Z_TYPE_P(arg4) == IS_TRUE);
                goto ipv4_loop_ttl;
 
        case IP_MULTICAST_TTL:
                convert_to_long_ex(arg4);
-               if (Z_LVAL_PP(arg4) < 0L || Z_LVAL_PP(arg4) > 255L) {
+               if (Z_LVAL_P(arg4) < 0L || Z_LVAL_P(arg4) > 255L) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING,
                                        "Expected a value between 0 and 255");
                        return FAILURE;
                }
-               ipv4_mcast_ttl_lback = (unsigned char) Z_LVAL_PP(arg4);
+               ipv4_mcast_ttl_lback = (unsigned char) Z_LVAL_P(arg4);
 ipv4_loop_ttl:
                opt_ptr = &ipv4_mcast_ttl_lback;
                optlen  = sizeof(ipv4_mcast_ttl_lback);
@@ -314,7 +316,7 @@ dosockopt:
 int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
                                                                 int level,
                                                                 int optname,
-                                                                zval **arg4 TSRMLS_DC)
+                                                                zval *arg4 TSRMLS_DC)
 {
        unsigned int    if_index;
        void                    *opt_ptr;
@@ -338,7 +340,7 @@ int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
                }
 
        case IPV6_MULTICAST_IF:
-               if (php_get_if_index_from_zval(*arg4, &if_index TSRMLS_CC) == FAILURE) {
+               if (php_get_if_index_from_zval(arg4, &if_index TSRMLS_CC) == FAILURE) {
                        return FAILURE;
                }
 
@@ -348,16 +350,16 @@ int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
 
        case IPV6_MULTICAST_LOOP:
                convert_to_boolean_ex(arg4);
-               ov = (int) Z_TYPE_PP(arg4) == IS_TRUE;
+               ov = (int) Z_TYPE_P(arg4) == IS_TRUE;
                goto ipv6_loop_hops;
        case IPV6_MULTICAST_HOPS:
                convert_to_long_ex(arg4);
-               if (Z_LVAL_PP(arg4) < -1L || Z_LVAL_PP(arg4) > 255L) {
+               if (Z_LVAL_P(arg4) < -1L || Z_LVAL_P(arg4) > 255L) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING,
                                        "Expected a value between -1 and 255");
                        return FAILURE;
                }
-               ov = (int) Z_LVAL_PP(arg4);
+               ov = (int) Z_LVAL_P(arg4);
 ipv6_loop_hops:
                opt_ptr = &ov;
                optlen  = sizeof(ov);
index f89f56ed390587194b419f2dd3216ae207de01cb..29eb54efd81dd72ebd1117dbf96b20f13def0ca1 100644 (file)
 int php_do_setsockopt_ip_mcast(php_socket *php_sock,
                                                           int level,
                                                           int optname,
-                                                          zval **arg4 TSRMLS_DC);
+                                                          zval *arg4 TSRMLS_DC);
 
 int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
                                                                 int level,
                                                                 int optname,
-                                                                zval **arg4 TSRMLS_DC);
+                                                                zval *arg4 TSRMLS_DC);
 
 int php_if_index_to_addr4(
         unsigned if_index,
index e872635f9aeb445cf2d856534636b36d6ae3fd4f..86729650e4dfd25cff5e1e5912b9f429327fa6cb 100644 (file)
@@ -59,7 +59,7 @@ typedef struct {
        int                     type;
        int                     error;
        int                     blocking;
-       zval            *zstream;
+       zval            zstream;
 } php_socket;
 
 #ifdef PHP_WIN32
index d9a8190736543ae340fc0e86b8aa628494532427..5b57124cb899e9eac7d244ec268be26e7fca6c7b 100644 (file)
@@ -83,6 +83,10 @@ static struct {
 } ancillary_registry;
 
 
+static void ancillary_registery_free_elem(zval *el) {
+       pefree(Z_PTR_P(el), 1);
+}
+
 #ifdef ZTS
 static MUTEX_T ancillary_mutex;
 #endif
@@ -92,7 +96,7 @@ static void init_ancillary_registry(void)
        anc_reg_key key;
        ancillary_registry.initialized = 1;
 
-       zend_hash_init(&ancillary_registry.ht, 32, NULL, NULL, 1);
+       zend_hash_init(&ancillary_registry.ht, 32, NULL, ancillary_registery_free_elem, 1);
 
 #define PUT_ENTRY(sizev, var_size, calc, from, to, level, type) \
        entry.size                      = sizev; \
@@ -102,8 +106,7 @@ static void init_ancillary_registry(void)
        entry.to_array          = to; \
        key.cmsg_level          = level; \
        key.cmsg_type           = type; \
-       zend_hash_update(&ancillary_registry.ht, (char*)&key, sizeof(key), \
-                       (void*)&entry, sizeof(entry), NULL)
+       zend_hash_str_update_mem(&ancillary_registry.ht, (char*)&key, sizeof(key) - 1, (void*)&entry, sizeof(entry))
 
 #if defined(IPV6_PKTINFO) && HAVE_IPV6
        PUT_ENTRY(sizeof(struct in6_pktinfo), 0, 0, from_zval_write_in6_pktinfo,
@@ -153,8 +156,7 @@ ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type)
        tsrm_mutex_unlock(ancillary_mutex);
 #endif
 
-       if (zend_hash_find(&ancillary_registry.ht, (char*)&key, sizeof(key),
-                       (void**)&entry) == SUCCESS) {
+       if ((entry = zend_hash_str_find_ptr(&ancillary_registry.ht, (char*)&key, sizeof(key) - 1)) != NULL) {
                return entry;
        } else {
                return NULL;
@@ -179,7 +181,7 @@ PHP_FUNCTION(socket_sendmsg)
 
        LONG_CHECK_VALID_INT(flags);
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &zsocket, -1,
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, zsocket, -1,
                        php_sockets_le_socket_name, php_sockets_le_socket());
 
        msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_send,
@@ -222,7 +224,7 @@ PHP_FUNCTION(socket_recvmsg)
 
        LONG_CHECK_VALID_INT(flags);
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &zsocket, -1,
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, zsocket, -1,
                        php_sockets_le_socket_name, php_sockets_le_socket());
 
        msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_recv,
@@ -236,7 +238,7 @@ PHP_FUNCTION(socket_recvmsg)
        res = recvmsg(php_sock->bsd_socket, msghdr, (int)flags);
 
        if (res != -1) {
-               zval *zres;
+               zval *zres, tmp;
                struct key_value kv[] = {
                                {KEY_RECVMSG_RET, sizeof(KEY_RECVMSG_RET), &res},
                                {0}
@@ -244,7 +246,7 @@ PHP_FUNCTION(socket_recvmsg)
 
 
                zres = to_zval_run_conversions((char *)msghdr, to_zval_read_msghdr,
-                               "msghdr", kv, &err);
+                               "msghdr", kv, &err, &tmp);
 
                /* we don;t need msghdr anymore; free it */
                msghdr = NULL;
@@ -253,7 +255,6 @@ PHP_FUNCTION(socket_recvmsg)
                zval_dtor(zmsg);
                if (!err.has_error) {
                        ZVAL_COPY_VALUE(zmsg, zres);
-                       efree(zres); /* only shallow destruction */
                } else {
                        err_msg_dispose(&err TSRMLS_CC);
                        ZVAL_FALSE(zmsg);
@@ -311,7 +312,7 @@ PHP_FUNCTION(socket_cmsg_space)
 }
 
 #if HAVE_IPV6
-int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC)
+int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *arg4 TSRMLS_DC)
 {
        struct err_s    err = {0};
        zend_llist              *allocations = NULL;
@@ -336,7 +337,7 @@ int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname,
                        return 1;
                }
 #endif
-               opt_ptr = from_zval_run_conversions(*arg4, php_sock, from_zval_write_in6_pktinfo,
+               opt_ptr = from_zval_run_conversions(arg4, php_sock, from_zval_write_in6_pktinfo,
                                sizeof(struct in6_pktinfo),     "in6_pktinfo", &allocations, &err);
                if (err.has_error) {
                        err_msg_dispose(&err TSRMLS_CC);
@@ -388,14 +389,14 @@ int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname,
        if (res != 0) {
                PHP_SOCKET_ERROR(php_sock, "unable to get socket option", errno);
        } else {
+               zval tmp;
                zval *zv = to_zval_run_conversions(buffer, reader, "in6_pktinfo",
-                               empty_key_value_list, &err);
+                               empty_key_value_list, &err, &tmp);
                if (err.has_error) {
                        err_msg_dispose(&err TSRMLS_CC);
                        res = -1;
                } else {
                        ZVAL_COPY_VALUE(result, zv);
-                       efree(zv);
                }
        }
        efree(buffer);
index 5a3798274fd7e058e4c2ff35f9d801c301ac5bee..db099ed65eff015f36df099a75bc74e3c38419c3 100644 (file)
@@ -12,7 +12,7 @@ PHP_FUNCTION(socket_cmsg_space);
 void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS);
 void php_socket_sendrecvmsg_shutdown(SHUTDOWN_FUNC_ARGS);
 
-int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC);
+int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *arg4 TSRMLS_DC);
 int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result TSRMLS_DC);
 
 /* for conversions.c */
index bd0a8f2f70d2df8938947f61963e76f68bcd4639..1237b6c39e0a1b911baa53d06db94f35a010b14a 100644 (file)
@@ -386,23 +386,23 @@ PHP_SOCKETS_API int php_sockets_le_socket(void) /* {{{ */
  * less likely */
 static php_socket *php_create_socket(void) /* {{{ */
 {
-       php_socket *php_sock = emalloc(sizeof *php_sock);
+       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;
-       php_sock->zstream        = NULL;
+       ZVAL_UNDEF(&php_sock->zstream);
 
        return php_sock;
 }
 /* }}} */
 
-static void php_destroy_socket(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
+static void php_destroy_socket(zend_resource *rsrc TSRMLS_DC) /* {{{ */
 {
        php_socket *php_sock = rsrc->ptr;
 
-       if (php_sock->zstream == NULL) {
+       if (Z_ISUNDEF(php_sock->zstream)) {
                if (!IS_INVALID_SOCKET(php_sock)) {
                        close(php_sock->bsd_socket);
                }
@@ -765,16 +765,13 @@ static PHP_RSHUTDOWN_FUNCTION(sockets)
 
 static int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, PHP_SOCKET *max_fd TSRMLS_DC) /* {{{ */
 {
-       zval            **element;
+       zval            *element;
        php_socket      *php_sock;
        int                     num = 0;
 
        if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0;
 
-       for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(sock_array));
-                zend_hash_get_current_data(Z_ARRVAL_P(sock_array), (void **) &element) == SUCCESS;
-                zend_hash_move_forward(Z_ARRVAL_P(sock_array))) {
-
+       ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(sock_array), element) {
                php_sock = (php_socket*) zend_fetch_resource(element TSRMLS_CC, -1, le_socket_name, NULL, 1, le_socket);
                if (!php_sock) continue; /* If element is not a resource, skip it */
 
@@ -783,7 +780,7 @@ static int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, PHP_SOCKET *m
                        *max_fd = php_sock->bsd_socket;
                }
                num++;
-       }
+       } ZEND_HASH_FOREACH_END();
 
        return num ? 1 : 0;
 }
@@ -791,53 +788,45 @@ static int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, PHP_SOCKET *m
 
 static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) /* {{{ */
 {
-       zval            **element;
-       zval            **dest_element;
+       zval            *element;
+       zval            *dest_element;
        php_socket      *php_sock;
-       HashTable       *new_hash;
-       char            *key;
+       zval            new_hash;
        int                     num = 0;
        ulong       num_key;
-       uint            key_len;
+       zend_string *key;
 
        if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0;
 
-       ALLOC_HASHTABLE(new_hash);
-       zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(sock_array)), NULL, ZVAL_PTR_DTOR, 0);
-       for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(sock_array));
-                zend_hash_get_current_data(Z_ARRVAL_P(sock_array), (void **) &element) == SUCCESS;
-                zend_hash_move_forward(Z_ARRVAL_P(sock_array))) {
-
+       array_init(&new_hash);
+       ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(sock_array), num_key, key, element) {
                php_sock = (php_socket*) zend_fetch_resource(element TSRMLS_CC, -1, le_socket_name, NULL, 1, le_socket);
                if (!php_sock) continue; /* If element is not a resource, skip it */
 
                if (PHP_SAFE_FD_ISSET(php_sock->bsd_socket, fds)) {
                        /* Add fd to new array */
-                       switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(sock_array), &key, &key_len, &num_key, 0, NULL)) {
-                               case HASH_KEY_IS_STRING:
-                                       zend_hash_add(new_hash, key, key_len, (void *)element, sizeof(zval *), (void **)&dest_element);
-                                       break;
-                               case HASH_KEY_IS_LONG:
-                                       zend_hash_index_update(new_hash, num_key, (void *)element, sizeof(zval *), (void **)&dest_element);
-                                       break;
+                       if (key) {
+                               dest_element = zend_hash_add(Z_ARRVAL(new_hash), key, element);
+                       } else {
+                               dest_element = zend_hash_index_update(Z_ARRVAL(new_hash), num_key, element);
+                       }
+                       if (dest_element) {
+                               Z_ADDREF_P(dest_element);
                        }
-                       if (dest_element) zval_add_ref(dest_element);
                }
                num++;
-       }
+       } ZEND_HASH_FOREACH_END();
 
        /* Destroy old array, add new one */
-       zend_hash_destroy(Z_ARRVAL_P(sock_array));
-       efree(Z_ARRVAL_P(sock_array));
+       zval_ptr_dtor(sock_array);
 
-       zend_hash_internal_pointer_reset(new_hash);
-       Z_ARRVAL_P(sock_array) = new_hash;
+       ZVAL_COPY_VALUE(sock_array, &new_hash);
 
        return num ? 1 : 0;
 }
 /* }}} */
 
-/* {{{ proto int socket_select(array &read_fds, array &write_fds, array &except_fds, int tv_sec[, int tv_usec]) U
+/* {{{ proto int socket_select(array &read_fds, array &write_fds, array &except_fds, int tv_sec[, int tv_usec]) 
    Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec */
 PHP_FUNCTION(socket_select)
 {
@@ -911,7 +900,7 @@ PHP_FUNCTION(socket_select)
 }
 /* }}} */
 
-/* {{{ proto resource socket_create_listen(int port[, int backlog]) U
+/* {{{ proto resource socket_create_listen(int port[, int backlog]) 
    Opens a socket on port to accept connections */
 PHP_FUNCTION(socket_create_listen)
 {
@@ -933,7 +922,7 @@ PHP_FUNCTION(socket_create_listen)
 }
 /* }}} */
 
-/* {{{ proto resource socket_accept(resource socket) U
+/* {{{ proto resource socket_accept(resource socket)
    Accepts a connection on the listening socket fd */
 PHP_FUNCTION(socket_accept)
 {
@@ -946,7 +935,7 @@ PHP_FUNCTION(socket_accept)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        if (!php_accept_connect(php_sock, &new_sock, (struct sockaddr*)&sa, &php_sa_len TSRMLS_CC)) {
                RETURN_FALSE;
@@ -956,7 +945,7 @@ PHP_FUNCTION(socket_accept)
 }
 /* }}} */
 
-/* {{{ proto bool socket_set_nonblock(resource socket) U
+/* {{{ proto bool socket_set_nonblock(resource socket)
    Sets nonblocking mode on a socket resource */
 PHP_FUNCTION(socket_set_nonblock)
 {
@@ -967,9 +956,9 @@ PHP_FUNCTION(socket_set_nonblock)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
-       if (php_sock->zstream != NULL) {
+       if (!Z_ISUNDEF(php_sock->zstream)) {
                php_stream *stream;
                /* omit notice if resource doesn't exist anymore */
                stream = zend_fetch_resource(&php_sock->zstream TSRMLS_CC, -1,
@@ -993,7 +982,7 @@ PHP_FUNCTION(socket_set_nonblock)
 }
 /* }}} */
 
-/* {{{ proto bool socket_set_block(resource socket) U
+/* {{{ proto bool socket_set_block(resource socket)
    Sets blocking mode on a socket resource */
 PHP_FUNCTION(socket_set_block)
 {
@@ -1004,12 +993,12 @@ PHP_FUNCTION(socket_set_block)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        /* 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
         * state */
-       if (php_sock->zstream != NULL) {
+       if (!Z_ISUNDEF(php_sock->zstream)) {
                php_stream *stream;
                stream = zend_fetch_resource(&php_sock->zstream TSRMLS_CC, -1,
                        NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream());
@@ -1032,7 +1021,7 @@ PHP_FUNCTION(socket_set_block)
 }
 /* }}} */
 
-/* {{{ proto bool socket_listen(resource socket[, int backlog]) U
+/* {{{ proto bool socket_listen(resource socket[, int backlog])
    Sets the maximum number of connections allowed to be waited for on the socket specified by fd */
 PHP_FUNCTION(socket_listen)
 {
@@ -1044,7 +1033,7 @@ PHP_FUNCTION(socket_listen)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        if (listen(php_sock->bsd_socket, backlog) != 0) {
                PHP_SOCKET_ERROR(php_sock, "unable to listen on socket", errno);
@@ -1054,7 +1043,7 @@ PHP_FUNCTION(socket_listen)
 }
 /* }}} */
 
-/* {{{ proto void socket_close(resource socket) U
+/* {{{ proto void socket_close(resource socket)
    Closes a file descriptor */
 PHP_FUNCTION(socket_close)
 {
@@ -1065,8 +1054,8 @@ PHP_FUNCTION(socket_close)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
-       if (php_sock->zstream != NULL) {
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
+       if (!Z_ISUNDEF(php_sock->zstream)) {
                php_stream *stream = NULL;
                php_stream_from_zval_no_verify(stream, &php_sock->zstream);
                if (stream != NULL) {
@@ -1076,7 +1065,7 @@ PHP_FUNCTION(socket_close)
                                        (stream->is_persistent?PHP_STREAM_FREE_CLOSE_PERSISTENT:0));
                }
        }
-       zend_list_delete(Z_RESVAL_P(arg1));
+       zend_list_close(Z_RES_P(arg1));
 }
 /* }}} */
 
@@ -1094,7 +1083,7 @@ PHP_FUNCTION(socket_write)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        if (ZEND_NUM_ARGS() < 3) {
                length = str_len;
@@ -1115,13 +1104,13 @@ PHP_FUNCTION(socket_write)
 }
 /* }}} */
 
-/* {{{ proto string socket_read(resource socket, int length [, int type]) U
+/* {{{ proto string socket_read(resource socket, int length [, int type]) 
    Reads a maximum of length bytes from socket */
 PHP_FUNCTION(socket_read)
 {
        zval            *arg1;
        php_socket      *php_sock;
-       char            *tmpbuf;
+       zend_string     *tmpbuf;
        int                     retval;
        long            length, type = PHP_BINARY_READ;
 
@@ -1134,14 +1123,14 @@ PHP_FUNCTION(socket_read)
                RETURN_FALSE;
        }
 
-       tmpbuf = emalloc(length + 1);
+       tmpbuf = STR_ALLOC(length, 0);
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        if (type == PHP_NORMAL_READ) {
-               retval = php_read(php_sock, tmpbuf, length, 0);
+               retval = php_read(php_sock, tmpbuf->val, length, 0);
        } else {
-               retval = recv(php_sock->bsd_socket, tmpbuf, length, 0);
+               retval = recv(php_sock->bsd_socket, tmpbuf->val, length, 0);
        }
 
        if (retval == -1) {
@@ -1158,17 +1147,18 @@ PHP_FUNCTION(socket_read)
                        PHP_SOCKET_ERROR(php_sock, "unable to read from socket", errno);
                }
 
-               efree(tmpbuf);
+               STR_FREE(tmpbuf);
                RETURN_FALSE;
        } else if (!retval) {
-               efree(tmpbuf);
+               STR_FREE(tmpbuf);
                RETURN_EMPTY_STRING();
        }
 
-       tmpbuf = erealloc(tmpbuf, retval + 1);
-       tmpbuf[retval] = '\0' ;
+       tmpbuf = STR_REALLOC(tmpbuf, retval, 0);
+       tmpbuf->len = retval;
+       tmpbuf->val[tmpbuf->len] = '\0' ;
 
-       RETURN_STRINGL(tmpbuf, retval, 0);
+       RETURN_STR(tmpbuf);
 }
 /* }}} */
 
@@ -1193,7 +1183,7 @@ PHP_FUNCTION(socket_getsockname)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        sa = (struct sockaddr *) &sa_storage;
 
@@ -1208,7 +1198,7 @@ PHP_FUNCTION(socket_getsockname)
                        sin6 = (struct sockaddr_in6 *) sa;
                        inet_ntop(AF_INET6, &sin6->sin6_addr, addr6, INET6_ADDRSTRLEN);
                        zval_dtor(addr);
-                       ZVAL_STRING(addr, addr6, 1);
+                       ZVAL_STRING(addr, addr6);
 
                        if (port != NULL) {
                                zval_dtor(port);
@@ -1225,7 +1215,7 @@ PHP_FUNCTION(socket_getsockname)
                        inet_ntoa_lock = 0;
 
                        zval_dtor(addr);
-                       ZVAL_STRING(addr, addr_string, 1);
+                       ZVAL_STRING(addr, addr_string);
 
                        if (port != NULL) {
                                zval_dtor(port);
@@ -1238,7 +1228,7 @@ PHP_FUNCTION(socket_getsockname)
                        s_un = (struct sockaddr_un *) sa;
 
                        zval_dtor(addr);
-                       ZVAL_STRING(addr, s_un->sun_path, 1);
+                       ZVAL_STRING(addr, s_un->sun_path);
                        RETURN_TRUE;
                        break;
 
@@ -1270,7 +1260,7 @@ PHP_FUNCTION(socket_getpeername)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        sa = (struct sockaddr *) &sa_storage;
 
@@ -1279,13 +1269,15 @@ PHP_FUNCTION(socket_getpeername)
                RETURN_FALSE;
        }
 
+       ZVAL_DEREF(arg2);
+       ZVAL_DEREF(arg3);
        switch (sa->sa_family) {
 #if HAVE_IPV6
                case AF_INET6:
                        sin6 = (struct sockaddr_in6 *) sa;
                        inet_ntop(AF_INET6, &sin6->sin6_addr, addr6, INET6_ADDRSTRLEN);
                        zval_dtor(arg2);
-                       ZVAL_STRING(arg2, addr6, 1);
+                       ZVAL_STRING(arg2, addr6);
 
                        if (arg3 != NULL) {
                                zval_dtor(arg3);
@@ -1303,7 +1295,7 @@ PHP_FUNCTION(socket_getpeername)
                        inet_ntoa_lock = 0;
 
                        zval_dtor(arg2);
-                       ZVAL_STRING(arg2, addr_string, 1);
+                       ZVAL_STRING(arg2, addr_string);
 
                        if (arg3 != NULL) {
                                zval_dtor(arg3);
@@ -1317,7 +1309,7 @@ PHP_FUNCTION(socket_getpeername)
                        s_un = (struct sockaddr_un *) sa;
 
                        zval_dtor(arg2);
-                       ZVAL_STRING(arg2, s_un->sun_path, 1);
+                       ZVAL_STRING(arg2, s_un->sun_path);
                        RETURN_TRUE;
                        break;
 
@@ -1328,7 +1320,7 @@ PHP_FUNCTION(socket_getpeername)
 }
 /* }}} */
 
-/* {{{ proto resource socket_create(int domain, int type, int protocol) U
+/* {{{ proto resource socket_create(int domain, int type, int protocol) 
    Creates an endpoint for communication in the domain specified by domain, of type specified by type */
 PHP_FUNCTION(socket_create)
 {
@@ -1386,7 +1378,7 @@ PHP_FUNCTION(socket_connect)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        switch(php_sock->type) {
 #if HAVE_IPV6
@@ -1469,7 +1461,7 @@ PHP_FUNCTION(socket_strerror)
                return;
        }
 
-       RETURN_STRING(sockets_strerror(arg1 TSRMLS_CC), 1);
+       RETURN_STRING(sockets_strerror(arg1 TSRMLS_CC));
 }
 /* }}} */
 
@@ -1490,7 +1482,7 @@ PHP_FUNCTION(socket_bind)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        switch(php_sock->type) {
                case AF_UNIX:
@@ -1561,7 +1553,7 @@ PHP_FUNCTION(socket_bind)
 PHP_FUNCTION(socket_recv)
 {
        zval            *php_sock_res, *buf;
-       char            *recv_buf;
+       zend_string     *recv_buf;
        php_socket      *php_sock;
        int                     retval;
        long            len, flags;
@@ -1570,30 +1562,28 @@ PHP_FUNCTION(socket_recv)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &php_sock_res, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, php_sock_res, -1, le_socket_name, le_socket);
 
        /* overflow check */
        if ((len + 1) < 2) {
                RETURN_FALSE;
        }
 
-       recv_buf = emalloc(len + 1);
-       memset(recv_buf, 0, len + 1);
+       recv_buf = STR_ALLOC(len, 0);
 
-       if ((retval = recv(php_sock->bsd_socket, recv_buf, len, flags)) < 1) {
+       ZVAL_DEREF(buf);
+       if ((retval = recv(php_sock->bsd_socket, recv_buf->val, len, flags)) < 1) {
                efree(recv_buf);
 
                zval_dtor(buf);
-               Z_TYPE_P(buf) = IS_NULL;
+               ZVAL_NULL(buf);
        } else {
-               recv_buf[retval] = '\0';
+               recv_buf->len = retval;
+               recv_buf->val[recv_buf->len] = '\0';
 
                /* Rebuild buffer zval */
                zval_dtor(buf);
-
-               Z_STRVAL_P(buf) = recv_buf;
-               Z_STRLEN_P(buf) = retval;
-               Z_TYPE_P(buf) = IS_STRING;
+               ZVAL_STR(buf, recv_buf);
        }
 
        if (retval == -1) {
@@ -1619,7 +1609,7 @@ PHP_FUNCTION(socket_send)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        retval = send(php_sock->bsd_socket, buf, (buf_len < len ? buf_len : len), flags);
 
@@ -1647,39 +1637,43 @@ PHP_FUNCTION(socket_recvfrom)
        socklen_t                       slen;
        int                                     retval;
        long                            arg3, arg4;
-       char                            *recv_buf, *address;
+       char                            *address;
+       zend_string                     *recv_buf;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzllz|z", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) {
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        /* overflow check */
        if ((arg3 + 2) < 3) {
                RETURN_FALSE;
        }
 
-       recv_buf = emalloc(arg3 + 2);
-       memset(recv_buf, 0, arg3 + 2);
+       recv_buf = STR_ALLOC(arg3 + 1, 0);
 
        switch (php_sock->type) {
                case AF_UNIX:
                        slen = sizeof(s_un);
                        s_un.sun_family = AF_UNIX;
-                       retval = recvfrom(php_sock->bsd_socket, recv_buf, arg3, arg4, (struct sockaddr *)&s_un, (socklen_t *)&slen);
+                       retval = recvfrom(php_sock->bsd_socket, recv_buf->val, arg3, arg4, (struct sockaddr *)&s_un, (socklen_t *)&slen);
 
                        if (retval < 0) {
                                PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno);
-                               efree(recv_buf);
+                               STR_FREE(recv_buf);
                                RETURN_FALSE;
                        }
+                       recv_buf->len = retval;
+                       recv_buf->val[recv_buf->len] = '\0';
 
+                       ZVAL_DEREF(arg2);
+                       ZVAL_DEREF(arg5);
                        zval_dtor(arg2);
                        zval_dtor(arg5);
 
-                       ZVAL_STRINGL(arg2, recv_buf, retval, 0);
-                       ZVAL_STRING(arg5, s_un.sun_path, 1);
+                       ZVAL_STR(arg2, recv_buf);
+                       ZVAL_STRING(arg5, s_un.sun_path);
                        break;
 
                case AF_INET:
@@ -1688,26 +1682,31 @@ PHP_FUNCTION(socket_recvfrom)
                        sin.sin_family = AF_INET;
 
                        if (arg6 == NULL) {
-                               efree(recv_buf);
+                               STR_FREE(recv_buf);
                                WRONG_PARAM_COUNT;
                        }
 
-                       retval = recvfrom(php_sock->bsd_socket, recv_buf, arg3, arg4, (struct sockaddr *)&sin, (socklen_t *)&slen);
+                       retval = recvfrom(php_sock->bsd_socket, recv_buf->val, arg3, arg4, (struct sockaddr *)&sin, (socklen_t *)&slen);
 
                        if (retval < 0) {
                                PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno);
-                               efree(recv_buf);
+                               STR_FREE(recv_buf);
                                RETURN_FALSE;
                        }
+                       recv_buf->len = retval;
+                       recv_buf->val[recv_buf->len] = '\0';
 
+                       ZVAL_DEREF(arg2);
+                       ZVAL_DEREF(arg5);
+                       ZVAL_DEREF(arg6);
                        zval_dtor(arg2);
                        zval_dtor(arg5);
                        zval_dtor(arg6);
 
                        address = inet_ntoa(sin.sin_addr);
 
-                       ZVAL_STRINGL(arg2, recv_buf, retval, 0);
-                       ZVAL_STRING(arg5, address ? address : "0.0.0.0", 1);
+                       ZVAL_STR(arg2, recv_buf);
+                       ZVAL_STRING(arg5, address ? address : "0.0.0.0");
                        ZVAL_LONG(arg6, ntohs(sin.sin_port));
                        break;
 #if HAVE_IPV6
@@ -1721,14 +1720,19 @@ PHP_FUNCTION(socket_recvfrom)
                                WRONG_PARAM_COUNT;
                        }
 
-                       retval = recvfrom(php_sock->bsd_socket, recv_buf, arg3, arg4, (struct sockaddr *)&sin6, (socklen_t *)&slen);
+                       retval = recvfrom(php_sock->bsd_socket, recv_buf->val, arg3, arg4, (struct sockaddr *)&sin6, (socklen_t *)&slen);
 
                        if (retval < 0) {
                                PHP_SOCKET_ERROR(php_sock, "unable to recvfrom", errno);
-                               efree(recv_buf);
+                               STR_FREE(recv_buf);
                                RETURN_FALSE;
                        }
+                       recv_buf->len = retval;
+                       recv_buf->val[recv_buf->len] = '\0';
 
+                       ZVAL_DEREF(arg2);
+                       ZVAL_DEREF(arg5);
+                       ZVAL_DEREF(arg6);
                        zval_dtor(arg2);
                        zval_dtor(arg5);
                        zval_dtor(arg6);
@@ -1736,8 +1740,8 @@ PHP_FUNCTION(socket_recvfrom)
                        memset(addr6, 0, INET6_ADDRSTRLEN);
                        inet_ntop(AF_INET6, &sin6.sin6_addr, addr6, INET6_ADDRSTRLEN);
 
-                       ZVAL_STRINGL(arg2, recv_buf, retval, 0);
-                       ZVAL_STRING(arg5, addr6[0] ? addr6 : "::", 1);
+                       ZVAL_STR(arg2, recv_buf);
+                       ZVAL_STRING(arg5, addr6[0] ? addr6 : "::");
                        ZVAL_LONG(arg6, ntohs(sin6.sin6_port));
                        break;
 #endif
@@ -1770,7 +1774,7 @@ PHP_FUNCTION(socket_sendto)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        switch (php_sock->type) {
                case AF_UNIX:
@@ -1827,7 +1831,7 @@ PHP_FUNCTION(socket_sendto)
 }
 /* }}} */
 
-/* {{{ proto mixed socket_get_option(resource socket, int level, int optname) U
+/* {{{ proto mixed socket_get_option(resource socket, int level, int optname) 
    Gets socket options for the socket */
 PHP_FUNCTION(socket_get_option)
 {
@@ -1846,7 +1850,7 @@ PHP_FUNCTION(socket_get_option)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        if (level == IPPROTO_IP) {
                switch (optname) {
@@ -1939,7 +1943,7 @@ PHP_FUNCTION(socket_get_option)
    Sets socket options for the socket */
 PHP_FUNCTION(socket_set_option)
 {
-       zval                                    *arg1, **arg4;
+       zval                                    *arg1, *arg4;
        struct linger                   lv;
        php_socket                              *php_sock;
        int                                             ov, optlen, retval;
@@ -1951,15 +1955,15 @@ PHP_FUNCTION(socket_set_option)
        long                                    level, optname;
        void                                    *opt_ptr;
        HashTable                               *opt_ht;
-       zval                                    **l_onoff, **l_linger;
-       zval                                    **sec, **usec;
+       zval                                    *l_onoff, *l_linger;
+       zval                                    *sec, *usec;
 
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllZ", &arg1, &level, &optname, &arg4) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllz", &arg1, &level, &optname, &arg4) == FAILURE) {
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name, le_socket);
 
        set_errno(0);
 
@@ -1992,13 +1996,13 @@ PHP_FUNCTION(socket_set_option)
                        const char l_linger_key[] = "l_linger";
 
                        convert_to_array_ex(arg4);
-                       opt_ht = HASH_OF(*arg4);
+                       opt_ht = HASH_OF(arg4);
 
-                       if (zend_hash_find(opt_ht, l_onoff_key, sizeof(l_onoff_key), (void **)&l_onoff) == FAILURE) {
+                       if ((l_onoff = zend_hash_str_find(opt_ht, l_onoff_key, sizeof(l_onoff_key) - 1)) == NULL) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", l_onoff_key);
                                RETURN_FALSE;
                        }
-                       if (zend_hash_find(opt_ht, l_linger_key, sizeof(l_linger_key), (void **)&l_linger) == FAILURE) {
+                       if ((l_linger = zend_hash_str_find(opt_ht, l_linger_key, sizeof(l_linger_key) - 1)) == NULL) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", l_linger_key);
                                RETURN_FALSE;
                        }
@@ -2006,8 +2010,8 @@ PHP_FUNCTION(socket_set_option)
                        convert_to_long_ex(l_onoff);
                        convert_to_long_ex(l_linger);
 
-                       lv.l_onoff = (unsigned short)Z_LVAL_PP(l_onoff);
-                       lv.l_linger = (unsigned short)Z_LVAL_PP(l_linger);
+                       lv.l_onoff = (unsigned short)Z_LVAL_P(l_onoff);
+                       lv.l_linger = (unsigned short)Z_LVAL_P(l_linger);
 
                        optlen = sizeof(lv);
                        opt_ptr = &lv;
@@ -2020,13 +2024,13 @@ PHP_FUNCTION(socket_set_option)
                        const char usec_key[] = "usec";
 
                        convert_to_array_ex(arg4);
-                       opt_ht = HASH_OF(*arg4);
+                       opt_ht = HASH_OF(arg4);
 
-                       if (zend_hash_find(opt_ht, sec_key, sizeof(sec_key), (void **)&sec) == FAILURE) {
+                       if ((sec = zend_hash_str_find(opt_ht, sec_key, sizeof(sec_key) - 1)) == NULL) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", sec_key);
                                RETURN_FALSE;
                        }
-                       if (zend_hash_find(opt_ht, usec_key, sizeof(usec_key), (void **)&usec) == FAILURE) {
+                       if ((usec = zend_hash_str_find(opt_ht, usec_key, sizeof(usec_key) - 1)) == NULL) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", usec_key);
                                RETURN_FALSE;
                        }
@@ -2034,12 +2038,12 @@ PHP_FUNCTION(socket_set_option)
                        convert_to_long_ex(sec);
                        convert_to_long_ex(usec);
 #ifndef PHP_WIN32
-                       tv.tv_sec = Z_LVAL_PP(sec);
-                       tv.tv_usec = Z_LVAL_PP(usec);
+                       tv.tv_sec = Z_LVAL_P(sec);
+                       tv.tv_usec = Z_LVAL_P(usec);
                        optlen = sizeof(tv);
                        opt_ptr = &tv;
 #else
-                       timeout = Z_LVAL_PP(sec) * 1000 + Z_LVAL_PP(usec) / 1000;
+                       timeout = Z_LVAL_P(sec) * 1000 + Z_LVAL_P(usec) / 1000;
                        optlen = sizeof(int);
                        opt_ptr = &timeout;
 #endif
@@ -2047,9 +2051,9 @@ PHP_FUNCTION(socket_set_option)
                }
 #ifdef SO_BINDTODEVICE
                case SO_BINDTODEVICE: {
-                       if (Z_TYPE_PP(arg4) == IS_STRING) {
-                               opt_ptr = Z_STRVAL_PP(arg4);
-                               optlen = Z_STRLEN_PP(arg4);
+                       if (Z_TYPE_P(arg4) == IS_STRING) {
+                               opt_ptr = Z_STRVAL_P(arg4);
+                               optlen = Z_STRLEN_P(arg4);
                        } else {
                                opt_ptr = "";
                                optlen = 0;
@@ -2061,7 +2065,7 @@ PHP_FUNCTION(socket_set_option)
                default:
 default_case:
                        convert_to_long_ex(arg4);
-                       ov = Z_LVAL_PP(arg4);
+                       ov = Z_LVAL_P(arg4);
 
                        optlen = sizeof(ov);
                        opt_ptr = &ov;
@@ -2079,11 +2083,11 @@ default_case:
 /* }}} */
 
 #ifdef HAVE_SOCKETPAIR
-/* {{{ proto bool socket_create_pair(int domain, int type, int protocol, array &fd) U
+/* {{{ proto bool socket_create_pair(int domain, int type, int protocol, array &fd) 
    Creates a pair of indistinguishable sockets and stores them in fds. */
 PHP_FUNCTION(socket_create_pair)
 {
-       zval            *retval[2], *fds_array_zval;
+       zval            retval[2], *fds_array_zval;
        php_socket      *php_sock[2];
        PHP_SOCKET      fds_array[2];
        long            domain, type, protocol;
@@ -2120,9 +2124,6 @@ PHP_FUNCTION(socket_create_pair)
        zval_dtor(fds_array_zval);
        array_init(fds_array_zval);
 
-       MAKE_STD_ZVAL(retval[0]);
-       MAKE_STD_ZVAL(retval[1]);
-
        php_sock[0]->bsd_socket = fds_array[0];
        php_sock[1]->bsd_socket = fds_array[1];
        php_sock[0]->type               = domain;
@@ -2132,11 +2133,11 @@ PHP_FUNCTION(socket_create_pair)
        php_sock[0]->blocking   = 1;
        php_sock[1]->blocking   = 1;
 
-       ZEND_REGISTER_RESOURCE(retval[0], php_sock[0], le_socket);
-       ZEND_REGISTER_RESOURCE(retval[1], php_sock[1], le_socket);
+       ZEND_REGISTER_RESOURCE(&retval[0], php_sock[0], le_socket);
+       ZEND_REGISTER_RESOURCE(&retval[1], php_sock[1], le_socket);
 
-       add_index_zval(fds_array_zval, 0, retval[0]);
-       add_index_zval(fds_array_zval, 1, retval[1]);
+       add_index_zval(fds_array_zval, 0, &retval[0]);
+       add_index_zval(fds_array_zval, 1, &retval[1]);
 
        RETURN_TRUE;
 }
@@ -2144,7 +2145,7 @@ PHP_FUNCTION(socket_create_pair)
 #endif
 
 #ifdef HAVE_SHUTDOWN
-/* {{{ proto bool socket_shutdown(resource socket[, int how]) U
+/* {{{ proto bool socket_shutdown(resource socket[, int how]) 
    Shuts down a socket for receiving, sending, or both. */
 PHP_FUNCTION(socket_shutdown)
 {
@@ -2156,7 +2157,7 @@ PHP_FUNCTION(socket_shutdown)
                return;
        }
 
-       ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket);
+       ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, le_socket_name, le_socket);
 
        if (shutdown(php_sock->bsd_socket, how_shutdown) != 0) {
                PHP_SOCKET_ERROR(php_sock, "unable to shutdown socket", errno);
@@ -2168,7 +2169,7 @@ PHP_FUNCTION(socket_shutdown)
 /* }}} */
 #endif
 
-/* {{{ proto int socket_last_error([resource socket]) U
+/* {{{ proto int socket_last_error([resource socket]) 
    Returns the last socket error (either the last used or the provided socket resource) */
 PHP_FUNCTION(socket_last_error)
 {
@@ -2180,7 +2181,7 @@ PHP_FUNCTION(socket_last_error)
        }
 
        if (arg1) {
-               ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket);
+               ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, le_socket_name, le_socket);
                RETVAL_LONG(php_sock->error);
        } else {
                RETVAL_LONG(SOCKETS_G(last_error));
@@ -2188,7 +2189,7 @@ PHP_FUNCTION(socket_last_error)
 }
 /* }}} */
 
-/* {{{ proto void socket_clear_error([resource socket]) U
+/* {{{ proto void socket_clear_error([resource socket]) 
    Clears the error on the socket or the last error code. */
 PHP_FUNCTION(socket_clear_error)
 {
@@ -2200,7 +2201,7 @@ PHP_FUNCTION(socket_clear_error)
        }
 
        if (arg1) {
-               ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket);
+               ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, le_socket_name, le_socket);
                php_sock->error = 0;
        } else {
                SOCKETS_G(last_error) = 0;
@@ -2269,7 +2270,7 @@ PHP_FUNCTION(socket_import_stream)
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream) == FAILURE) {
                return;
        }
-       php_stream_from_zval(stream, &zstream);
+       php_stream_from_zval(stream, zstream);
 
        if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void**)&socket, 1)) {
                /* error supposedly already shown */
@@ -2295,11 +2296,7 @@ PHP_FUNCTION(socket_import_stream)
        /* hold a zval reference to the stream (holding a php_stream* directly could
         * also be done, but this might be slightly better if in the future we want
         * to provide a socket_export_stream) */
-       MAKE_STD_ZVAL(retsock->zstream);
-       *retsock->zstream = *zstream;
-       zval_copy_ctor(retsock->zstream);
-       Z_UNSET_ISREF_P(retsock->zstream);
-       Z_SET_REFCOUNT_P(retsock->zstream, 1);
+       ZVAL_COPY(&retsock->zstream, zstream);
 
        php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER,
                PHP_STREAM_BUFFER_NONE, NULL);