]> granicus.if.org Git - php/commitdiff
A Whole buncha stuff, mostly bug fixing...
authorSterling Hughes <sterling@php.net>
Sun, 20 Aug 2000 10:31:27 +0000 (10:31 +0000)
committerSterling Hughes <sterling@php.net>
Sun, 20 Aug 2000 10:31:27 +0000 (10:31 +0000)
- Make constants case-sensitive, conforming with the rest of PHP &
the C API.
- Make module compatible with thread safety features.
- open_listen_sok() -> open_listen_sock()
- Remove ext_skel comments
- Get rid of the ZVAL macro and replace with the correct Z_*_*
macros
- declare all functions local to the file as static.
- Remove empty PHP_MSHUTDOWN() function.
- Removed confirm_sockets_compiled()
- Changed RETVAL_* macro's to RETURN_* macro's eliminating errors
with incorrect return values and a potential leak/crash or two.
- functions that return void, actually return void
- Replaced 'long' in the prototypes with 'int'
- Fixed fd_zero() function, it gave a WRONG_PARAM_COUNT when you
gave it the proper parameter count.
- Changed the way an arbitrary number of parameters were accessed
from build_iovec() to use the Zend API.
- Added socketpair() and shutdown() functions.

ext/sockets/php_sockets.h
ext/sockets/sockets.c

index 832ad01d7d9218acbefdcd47e4e5e9477137c81b..ba968b51954629261cbb910a24d85a715488e361 100644 (file)
@@ -12,8 +12,7 @@
    | obtain it through the world-wide-web, please send a note to          |
    | license@php.net so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
-   | Authors:                                                             |
-   |                                                                      |
+   | Authors: Chris Vandomelen <chrisv@b0rked.dhs.org>                    |
    +----------------------------------------------------------------------+
  */
 
@@ -22,9 +21,6 @@
 
 /* $Id$ */
 
-/* You should tweak config.m4 so this symbol (or some else suitable)
-   gets defined.
-*/
 #if HAVE_SOCKETS
 
 extern zend_module_entry sockets_module_entry;
@@ -37,12 +33,8 @@ extern zend_module_entry sockets_module_entry;
 #endif
 
 PHP_MINIT_FUNCTION(sockets);
-PHP_MSHUTDOWN_FUNCTION(sockets);
-PHP_RINIT_FUNCTION(sockets);
-PHP_RSHUTDOWN_FUNCTION(sockets);
 PHP_MINFO_FUNCTION(sockets);
 
-PHP_FUNCTION(confirm_sockets_compiled);
 PHP_FUNCTION(fd_alloc);
 PHP_FUNCTION(fd_dealloc);
 PHP_FUNCTION(fd_set);
@@ -50,7 +42,7 @@ PHP_FUNCTION(fd_isset);
 PHP_FUNCTION(fd_clear);
 PHP_FUNCTION(fd_zero);
 PHP_FUNCTION(select);
-PHP_FUNCTION(open_listen_sok);
+PHP_FUNCTION(open_listen_sock);
 PHP_FUNCTION(accept_connect);
 PHP_FUNCTION(set_nonblock);
 PHP_FUNCTION(listen);
@@ -79,29 +71,23 @@ PHP_FUNCTION(readv);
 PHP_FUNCTION(writev);
 PHP_FUNCTION(getsockopt);
 PHP_FUNCTION(setsockopt);
+PHP_FUNCTION(socketpair);
+PHP_FUNCTION(shutdown);
+
+typedef struct php_iovec {
+       struct iovec *iov_array;
+       unsigned int count;
+} php_iovec_t;
 
-/* Fill in this structure and use entries in it
-   for thread safety instead of using true globals.
-*/
 typedef struct {
-       /* You can use the next one as type if your module registers any
-          resources. Oh, you can of course rename it to something more
-          suitable, add list entry types or remove it if it not needed.
-          It's just an example.
-       */
-       int le_sockets;
+       int le_destroy;
+       int le_iov;
 } php_sockets_globals;
 
-/* In every function that needs to use variables in php_sockets_globals,
-   do call SOCKETSLS_FETCH(); after declaring other variables used by
-   that function, and always refer to them as SOCKETSG(variable).
-   You are encouraged to rename these macros something shorter, see
-   examples in any other php module directory.
-*/
 
 #ifdef ZTS
 #define SOCKETSG(v) (sockets_globals->v)
-#define SOCKETSLS_FETCH() php_sockets_globals *sockets_globals = ts_resource(gd_sockets_id)
+#define SOCKETSLS_FETCH() php_sockets_globals *sockets_globals = ts_resource(sockets_global_id)
 #else
 #define SOCKETSG(v) (sockets_globals.v)
 #define SOCKETSLS_FETCH()
index bf6acf9cb68da35284beb480bdc079c3a27ae366..759f2c7b0e185bf6a3035ce94d3fb11b0ee3ebf1 100644 (file)
    | obtain it through the world-wide-web, please send a note to          |
    | license@php.net so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
-   | Authors:                                                             |
-   | Chris Vandomelen <chrisv@b0rked.dhs.org>                             |
+   | Authors: Chris Vandomelen <chrisv@b0rked.dhs.org>                    |
+   |          Sterling Hughes <sterling@php.net>                          |
    +----------------------------------------------------------------------+
  */
 
 /* $Id$ */
 
 #include "php.h"
-#include "php_ini.h"
-#include "php_sockets.h"
 
-#include "../standard/info.h"
+
+#if HAVE_SOCKETS
+
+#include "ext/standard/info.h"
+#include "php_sockets.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <signal.h>
 #include <sys/uio.h>
 
-/* You should tweak config.m4 so this symbol (or some else suitable)
-   gets defined.
- */
-#if HAVE_SOCKETS
-
 #ifdef ZTS
 int sockets_globals_id;
-
 #else
 php_sockets_globals sockets_globals;
-
 #endif
 
-#define ZVAL(arg, type) ((*(arg))->value.type)
-
 /* Perform convert_to_long_ex on a list of items */
-
-void v_convert_to_long_ex(int items,...)
+static void v_convert_to_long_ex(int items,...)
 {
        va_list ap;
        zval **arg;
@@ -71,7 +63,8 @@ void v_convert_to_long_ex(int items,...)
        va_end(ap);
 
 }
-/* *INDENT-OFF* */
+
+
 static unsigned char second_and_third_args_force_ref[] =
 {3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
 
@@ -84,11 +77,7 @@ static unsigned char fourth_arg_force_ref[] =
 static unsigned char third_through_seventh_args_force_ref[] =
 {7, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE};
 
-/* Every user visible function must have an entry in sockets_functions[].
- */
-function_entry sockets_functions[] =
-{
-       PHP_FE(confirm_sockets_compiled,        NULL)   /* For testing, remove later. */
+function_entry sockets_functions[] = {
        PHP_FE(fd_alloc,                        NULL)   /* OK */
        PHP_FE(fd_dealloc,                      NULL)   /* OK */
        PHP_FE(fd_set,                          NULL)   /* OK */
@@ -96,7 +85,7 @@ function_entry sockets_functions[] =
        PHP_FE(fd_clear,                        NULL)   /* OK */
        PHP_FE(fd_zero,                         NULL)   /* OK */
        PHP_FE(select,                          NULL)   /* OK */
-       PHP_FE(open_listen_sok,                 NULL)   /* OK */
+       PHP_FE(open_listen_sock,                NULL)   /* OK */
        PHP_FE(accept_connect,                  NULL)   /* OK */
        PHP_FE(set_nonblock,                    NULL)   /* OK */
        PHP_FE(listen,                          NULL)   /* OK */
@@ -104,11 +93,17 @@ function_entry sockets_functions[] =
        PHP_FE(write,                           NULL)   /* OK */
        PHP_FE(read,                            second_arg_force_ref)   /* OK */
 #if 0
-/* If and when asynchronous context switching is avaliable, this will work. Otherwise, forget it. */
+/* 
+ * If and when asynchronous context switching is avaliable, 
+ * this will work. Otherwise, forget it. 
+ */
        PHP_FE(signal,                          NULL)
 #endif
 #if 0
-/* These are defined elsewhere.. would these be more appropriate? */
+/* 
+ * These are defined elsewhere.. 
+ * would these be more appropriate?
+ */
        PHP_FE(gethostbyname,                   second_arg_force_ref)   /* OK */
        PHP_FE(gethostbyaddr,                   second_arg_force_ref)   /* OK */
 #endif
@@ -126,7 +121,7 @@ function_entry sockets_functions[] =
        PHP_FE(fetch_iovec,                     NULL)
        PHP_FE(free_iovec,                      NULL)
        PHP_FE(add_iovec,                       NULL)
-       PHP_FE(delete_iovec,                    NULL)
+       PHP_FE(delete_iovec,            NULL)
        PHP_FE(set_iovec,                       NULL)
        PHP_FE(recvmsg,                         third_through_seventh_args_force_ref)
        PHP_FE(sendmsg,                         NULL)
@@ -134,49 +129,36 @@ function_entry sockets_functions[] =
        PHP_FE(writev,                          NULL)
        PHP_FE(getsockopt,                      fourth_arg_force_ref)
        PHP_FE(setsockopt,                      NULL)
-       {NULL, NULL, NULL}      /* Must be the last line in sockets_functions[] */
+       PHP_FE(socketpair,                      NULL)
+       PHP_FE(shutdown,            NULL)
+       {NULL, NULL, NULL}
 };
 
-/* *INDENT-ON* */
-
-
-
-
-zend_module_entry sockets_module_entry =
-{
+zend_module_entry sockets_module_entry = {
        "sockets",
        sockets_functions,
        PHP_MINIT(sockets),
-       PHP_MSHUTDOWN(sockets),
+       NULL,
        NULL,
        NULL,
        PHP_MINFO(sockets),
        STANDARD_MODULE_PROPERTIES
 };
 
-int le_destroy;
-int le_iov;
-
 #ifdef COMPILE_DL_SOCKETS
 ZEND_GET_MODULE(sockets)
 #endif
 
-/* Remove comments and fill if you need to have entries in php.ini
-   PHP_INI_BEGIN()
-   PHP_INI_END()
- */
+static void destroy_fd_sets(fd_set *set);
+static void destroy_iovec(php_iovec_t *iov);
 
-typedef struct php_iovec {
-       struct iovec *iov_array;
-       unsigned int count;
-} php_iovec_t;
 
-static void destroy_fd_sets(fd_set * set)
+static void destroy_fd_sets(fd_set *set)
 {
        efree(set);
 }
 
-static void destroy_iovec(php_iovec_t * iov)
+static void destroy_iovec(php_iovec_t *iov)
 {
        int i;
 
@@ -192,54 +174,51 @@ static void destroy_iovec(php_iovec_t * iov)
 
 PHP_MINIT_FUNCTION(sockets)
 {
-/* Remove comments if you have entries in php.ini
-   REGISTER_INI_ENTRIES();
- */
-       le_destroy = register_list_destructors(destroy_fd_sets, NULL);
-       le_iov = register_list_destructors(destroy_iovec, NULL);
-
-       REGISTER_LONG_CONSTANT("AF_UNIX",               AF_UNIX,        CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("AF_INET",               AF_INET,        CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SOCK_STREAM",           SOCK_STREAM,    CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SOCK_DGRAM",            SOCK_DGRAM,     CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SOCK_RAW",              SOCK_RAW,       CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SOCK_SEQPACKET",        SOCK_SEQPACKET, CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SOCK_RDM",              SOCK_RDM,       CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("MSG_OOB",               MSG_OOB,        CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("MSG_WAITALL",           MSG_WAITALL,    CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("MSG_PEEK",              MSG_PEEK,       CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("MSG_DONTROUTE",         MSG_DONTROUTE,  CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_DEBUG",              SO_DEBUG,       CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_REUSEADDR",          SO_REUSEADDR,   CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_KEEPALIVE",          SO_KEEPALIVE,   CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_DONTROUTE",          SO_DONTROUTE,   CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_LINGER",             SO_LINGER,      CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_BROADCAST",          SO_BROADCAST,   CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_OOBINLINE",          SO_OOBINLINE,   CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_SNDBUF",             SO_SNDBUF,      CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_RCVBUF",             SO_RCVBUF,      CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_SNDLOWAT",           SO_SNDLOWAT,    CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_RCVLOWAT",           SO_RCVLOWAT,    CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_SNDTIMEO",           SO_SNDTIMEO,    CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_RCVTIMEO",           SO_RCVTIMEO,    CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_TYPE",               SO_TYPE,        CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("SO_ERROR",              SO_ERROR,       CONST_PERSISTENT);
-
-       REGISTER_LONG_CONSTANT("SOL_SOCKET",            SOL_SOCKET,     CONST_PERSISTENT);
+       SOCKETSLS_FETCH();
+       SOCKETSG(le_destroy) = register_list_destructors(destroy_fd_sets, NULL);
+       SOCKETSG(le_iov)     = register_list_destructors(destroy_iovec,   NULL);
+
+       REGISTER_LONG_CONSTANT("AF_UNIX", AF_UNIX, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("AF_INET", AF_INET, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SOCK_STREAM", SOCK_STREAM, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SOCK_DGRAM", SOCK_DGRAM, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SOCK_RAW", SOCK_RAW, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SOCK_SEQPACKET", SOCK_SEQPACKET, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SOCK_RDM", SOCK_RDM, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("MSG_OOB", MSG_OOB, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("MSG_WAITALL", MSG_WAITALL, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("MSG_PEEK", MSG_PEEK, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("MSG_DONTROUTE", MSG_DONTROUTE, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_DEBUG", SO_DEBUG, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_REUSEADDR", SO_REUSEADDR, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_KEEPALIVE", SO_KEEPALIVE, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_DONTROUTE", SO_DONTROUTE, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_LINGER", SO_LINGER, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_BROADCAST", SO_BROADCAST, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_OOBINLINE", SO_OOBINLINE, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_SNDBUF", SO_SNDBUF, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_RCVBUF", SO_RCVBUF, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_SNDLOWAT", SO_SNDLOWAT, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_RCVLOWAT", SO_RCVLOWAT, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_SNDTIMEO", SO_SNDTIMEO, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_RCVTIMEO", SO_RCVTIMEO, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_TYPE", SO_TYPE, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SO_ERROR", SO_ERROR, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SOL_SOCKET", SOL_SOCKET, CONST_CS | CONST_PERSISTENT);
+       
        {
                struct protoent *pe;
                pe = getprotobyname("tcp");
-               if (pe)
-                       REGISTER_LONG_CONSTANT("SOL_TCP",       pe->p_proto,    CONST_PERSISTENT);
+               if (pe) {
+                       REGISTER_LONG_CONSTANT("SOL_TCP", pe->p_proto, CONST_CS | CONST_PERSISTENT);
+               }
+               
                pe = getprotobyname("udp");
-               if (pe)
-                       REGISTER_LONG_CONSTANT("SOL_UDP",       pe->p_proto,    CONST_PERSISTENT);
+               if (pe) {
+                       REGISTER_LONG_CONSTANT("SOL_UDP", pe->p_proto, CONST_CS | CONST_PERSISTENT);
+               }
        }
-       return SUCCESS;
-}
-
-PHP_MSHUTDOWN_FUNCTION(sockets)
-{
+       
        return SUCCESS;
 }
 
@@ -248,53 +227,22 @@ PHP_MINFO_FUNCTION(sockets)
        php_info_print_table_start();
        php_info_print_table_header(2, "sockets support", "enabled");
        php_info_print_table_end();
-
-       /* Remove comments if you have entries in php.ini
-          DISPLAY_INI_ENTRIES();
-        */
-}
-
-/* Remove the following function when you have succesfully modified config.m4
-   so that your module can be compiled into PHP, it exists only for testing
-   purposes. */
-
-/* Every user-visible function in PHP should document itself in the source */
-/* {{{ proto string confirm_sockets_compiled(string arg)
-   Return a string to confirm that the module is compiled in */
-PHP_FUNCTION(confirm_sockets_compiled)
-{
-       zval **arg;
-       int len;
-       char string[256];
-
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       }
-       convert_to_string_ex(arg);
-
-       len = sprintf(string, "Congratulations, you have successfully modified ext/sockets/config.m4, module %s is compiled in PHP", Z_STRVAL_PP(arg));
-       RETVAL_STRINGL(string, len, 1);
 }
-/* }}} */
-/* The previous line is meant for emacs, so it can correctly fold and unfold
-   functions in source code. See the corresponding marks just before function
-   definition, where the functions purpose is also documented. Please follow
-   this convention for the convenience of others editing your code.
- */
 
 /* {{{ proto resource fd_alloc(void)
    Allocate a file descriptor set */
 PHP_FUNCTION(fd_alloc)
 {
        fd_set *set;
-       int ret;
+       SOCKETSLS_FETCH();
 
-       set = emalloc(sizeof(fd_set));
+       set = (fd_set *)emalloc(sizeof(fd_set));
        if (!set) {
-               zend_error(E_ERROR, "Can't allocate memory for fd_set");
-               RETVAL_FALSE;
+               php_error(E_WARNING, "Can't allocate memory for fd_set");
+               RETURN_FALSE;
        }
-       ret = ZEND_REGISTER_RESOURCE(return_value, set, le_destroy);
+       
+       ZEND_REGISTER_RESOURCE(return_value, set, SOCKETSG(le_destroy));
 }
 /* }}} */
 
@@ -303,30 +251,29 @@ PHP_FUNCTION(fd_alloc)
 /*   ** BUG: This is currently a no-op! */
 PHP_FUNCTION(fd_dealloc)
 {
-       RETVAL_TRUE;
+       RETURN_NULL();
 }
 /* }}} */
 
-/* {{{ proto bool fd_set(long fd, resource set)
+/* {{{ proto bool fd_set(int fd, resource set)
    Add a file descriptor to a set */
 PHP_FUNCTION(fd_set)
 {
        zval **set, **fd;
        fd_set *the_set;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       v_convert_to_long_ex(2, set, fd);
+       convert_to_long_ex(fd);
 
-       if ((*set)->type != IS_RESOURCE) {
-               (*set)->type = IS_RESOURCE;
-       }
-       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
+       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", SOCKETSG(le_destroy));
 
-       FD_SET((*fd)->value.lval, the_set);
+       FD_SET(Z_LVAL_PP(fd), the_set);
 
-       RETVAL_TRUE;
+       RETURN_TRUE;
 }
 /* }}} */
 
@@ -336,19 +283,19 @@ PHP_FUNCTION(fd_clear)
 {
        zval **set, **fd;
        fd_set *the_set;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       v_convert_to_long_ex(2, set, fd);
-
-       (*set)->type = IS_RESOURCE;
+       convert_to_long_ex(fd);
 
-       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
+       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", SOCKETSG(le_destroy));
 
-       FD_CLR((*fd)->value.lval, the_set);
+       FD_CLR(Z_LVAL_PP(fd), the_set);
 
-       RETVAL_TRUE;
+       RETURN_TRUE;
 }
 /* }}} */
 
@@ -358,20 +305,21 @@ PHP_FUNCTION(fd_isset)
 {
        zval **set, **fd;
        fd_set *the_set;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       v_convert_to_long_ex(2, set, fd);
-
-       (*set)->type = IS_RESOURCE;
+       convert_to_long_ex(fd);
 
-       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
+       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", SOCKETSG(le_destroy));
 
-       if (FD_ISSET((*fd)->value.lval, the_set)) {
-               RETVAL_TRUE;
+       if (FD_ISSET(Z_LVAL_PP(fd), the_set)) {
+               RETURN_TRUE;
        }
-       RETVAL_FALSE;
+       
+       RETURN_FALSE;
 }
 /* }}} */
 
@@ -381,19 +329,18 @@ PHP_FUNCTION(fd_zero)
 {
        zval **set;
        fd_set *the_set;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(2, &set) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 1 || 
+           zend_get_parameters_ex(1, &set) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_long_ex(set);
 
-       (*set)->type = IS_RESOURCE;
-
-       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
+       ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", SOCKETSG(le_destroy));
 
        FD_ZERO(the_set);
 
-       RETVAL_TRUE;
+       RETURN_TRUE;
 }
 /* }}} */
 
@@ -417,57 +364,48 @@ PHP_FUNCTION(fd_zero)
 
 PHP_FUNCTION(select)
 {
-       zval **max_fd, **readfds, **writefds, **exceptfds, **tv_sec, 
-             **tv_usec;
+       zval **max_fd, **readfds, **writefds, 
+            **exceptfds, **tv_sec, **tv_usec;
+
        struct timeval tv;
        fd_set *rfds, *wfds, *xfds;
        int ret = 0;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_ex(6, &max_fd, &readfds, &writefds, &exceptfds,
-                                          &tv_sec, &tv_usec) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 6 || 
+           zend_get_parameters_ex(6, &max_fd, &readfds, &writefds, &exceptfds, &tv_sec, &tv_usec) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       v_convert_to_long_ex(6, max_fd, readfds, writefds, exceptfds, tv_sec, tv_usec);
-
-       tv.tv_sec = ZVAL(tv_sec, lval);
-       tv.tv_usec = ZVAL(tv_usec, lval);
+       v_convert_to_long_ex(3, max_fd, tv_sec, tv_usec);
 
-       (*readfds)->type = IS_RESOURCE;
-       (*writefds)->type = IS_RESOURCE;
-       (*exceptfds)->type = IS_RESOURCE;
+       tv.tv_sec  = Z_LVAL_PP(tv_sec);
+       tv.tv_usec = Z_LVAL_PP(tv_usec);
 
-       if (ZVAL(readfds, lval) == 0) {
-               rfds = NULL;
+       if (Z_LVAL_PP(readfds) != 0) {
+               ZEND_FETCH_RESOURCE(rfds, fd_set *, readfds, -1, "File descriptor set", SOCKETSG(le_destroy));
        } else {
-               ZEND_FETCH_RESOURCE(rfds, fd_set *, readfds, -1, "File descriptor set", le_destroy);
+               rfds = NULL;
        }
-
-       if (ZVAL(writefds, lval) == 0) {
-               wfds = NULL;
+       
+       if (Z_LVAL_PP(writefds) != 0) {
+               ZEND_FETCH_RESOURCE(wfds, fd_set *, writefds, -1, "File descriptor set", SOCKETSG(le_destroy));
        } else {
-               ZEND_FETCH_RESOURCE(wfds, fd_set *, writefds, -1, "File descriptor set", le_destroy);
+               wfds = NULL;
        }
-
-       if (ZVAL(exceptfds, lval) == 0) {
-               xfds = NULL;
+       
+       if (Z_LVAL_PP(exceptfds) != 0) {
+               ZEND_FETCH_RESOURCE(xfds, fd_set *, exceptfds, -1, "File descriptor set", SOCKETSG(le_destroy));
        } else {
-               ZEND_FETCH_RESOURCE(xfds, fd_set *, exceptfds, -1, "File descriptor set", le_destroy);
+               xfds = NULL;
        }
 
-       ret = select(ZVAL(max_fd, lval), rfds, wfds, xfds, &tv);
+       ret = select(Z_LVAL_PP(max_fd), rfds, wfds, xfds, &tv);
 
-       if (ret < 0) {
-               RETVAL_LONG(-errno);
-       } else {
-               RETVAL_LONG(ret);
-       }
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto long open_listen_sok(long port)
-   Opens a socket on port to accept connections */
-
-int open_listen_sok(int port)
+static int open_listen_sock(int port)
 {
        int fd;
        struct sockaddr_in la;
@@ -476,96 +414,91 @@ int open_listen_sok(int port)
        if ((hp = gethostbyname("0.0.0.0")) == NULL) {
                return -1;
        }
-       bcopy(hp->h_addr, (char *) &la.sin_addr, hp->h_length);
+       
+       bcopy(hp->h_addr, (char *)&la.sin_addr, hp->h_length);
        la.sin_family = hp->h_addrtype;
        la.sin_port = htons(port);
 
        if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                return -1;
        }
-       if ((bind(fd, (struct sockaddr *) &la, sizeof(la)) < 0)) {
+       if ((bind(fd, (struct sockaddr *)&la, sizeof(la)) < 0)) {
                return -1;
        }
        listen(fd, 128);
        return fd;
 }
 
-PHP_FUNCTION(open_listen_sok)
+/* {{{ proto long open_listen_sock(long port)
+   Opens a socket on port to accept connections */
+PHP_FUNCTION(open_listen_sock)
 {
        zval **port;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &port) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 1 || 
+           zend_get_parameters_ex(1, &port) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        convert_to_long_ex(port);
 
-       ret = open_listen_sok(ZVAL(port, lval));
+       ret = open_listen_sock(Z_LVAL_PP(port));
 
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto int accept_connect(long fd)
-   Accepts a connection on the listening socket fd */
-int accept_connect(int fd, struct sockaddr *la)
+static int accept_connect(int fd, struct sockaddr *la)
 {
-       int foo, m;
+       int ret, m;
 
        m = sizeof(*la);
-       if ((foo = accept(fd, la, &m)) < 0) {
+       if ((ret = accept(fd, la, &m)) < 0) {
                return -1;
        }
-       return foo;
+       return ret;
 }
 
+/* {{{ proto int accept_connect(int fd)
+   Accepts a connection on the listening socket fd */
 PHP_FUNCTION(accept_connect)
 {
        zval **fd;
        int ret;
        struct sockaddr_in sa;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &fd) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 1 || 
+           zend_get_parameters_ex(1, &fd) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        convert_to_long_ex(fd);
 
-       ret = accept_connect(ZVAL(fd, lval), (struct sockaddr *) &sa);
-
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ret = accept_connect(Z_LVAL_PP(fd), (struct sockaddr *)&sa);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto bool set_nonblock(long fd)
+/* {{{ proto bool set_nonblock(int fd)
    Sets nonblocking mode for file descriptor fd */
 PHP_FUNCTION(set_nonblock)
 {
        zval **fd;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &fd) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 1 ||
+           zend_get_parameters_ex(1, &fd) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        convert_to_long_ex(fd);
 
-       ret = fcntl(ZVAL(fd, lval), F_SETFL, O_NONBLOCK);
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ret = fcntl(Z_LVAL_PP(fd), F_SETFL, O_NONBLOCK);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto bool listen(long fd, long backlog)
+/* {{{ proto bool listen(int fd, int backlog)
    Sets the maximum number of connections allowed to be waited for on the socket specified by fd */
 PHP_FUNCTION(listen)
 {
@@ -577,93 +510,94 @@ PHP_FUNCTION(listen)
        }
        v_convert_to_long_ex(2, fd, backlog);
 
-       ret = listen(ZVAL(fd, lval), ZVAL(backlog, lval));
-
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ret = listen(Z_LVAL_PP(fd), Z_LVAL_PP(backlog));
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto bool close(long fd)
+/* {{{ proto bool close(int fd)
    Close a file descriptor */
 PHP_FUNCTION(close)
 {
-       zval **arg;
+       zval **fd;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 1 || 
+           zend_get_parameters_ex(1, &fd) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_long_ex(arg);
-       ret = close(ZVAL(arg, lval));
-
+       convert_to_long_ex(fd);
+       ret = close(Z_LVAL_PP(fd));
+       
        if (ret == -1) {
-               zend_error(E_WARNING, "Invalid file descriptor");
-               RETVAL_FALSE;
+               php_error(E_WARNING, "Invalid file descriptor");
+               RETURN_FALSE;
        }
-       RETVAL_TRUE;
+       RETURN_TRUE;
 }
 /* }}} */
 
-/* {{{ proto long write(long fd, string buf, long length)
+/* {{{ proto int write(int fd, string buf, int length)
    Writes length bytes of buf to the file descriptor fd */
 PHP_FUNCTION(write)
 {
        zval **fd, **buf, **length;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
+       
        v_convert_to_long_ex(2, fd, length);
        convert_to_string_ex(buf);
 
-       if (ZVAL(buf, str.len) < ZVAL(length, lval)) {
-               ret = write(ZVAL(fd, lval), (void *) ZVAL(buf, str.val), ZVAL(buf, str.len));
+       if (Z_STRLEN_PP(buf) < Z_LVAL_PP(length)) {
+               ret = write(Z_LVAL_PP(fd), (void *)Z_STRVAL_PP(buf), Z_STRLEN_PP(buf));
        } else {
-               ret = write(ZVAL(fd, lval), (void *) ZVAL(buf, str.val), ZVAL(length, lval));
-       }
-
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
+               ret = write(Z_LVAL_PP(fd), (void *)Z_STRVAL_PP(buf), Z_LVAL_PP(length));
        }
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto long read(long fd, string &buf, long length)
+/* {{{ proto int read(int fd, string &buf, int length)
    Reads length bytes from fd into buf */
 PHP_FUNCTION(read)
 {
        zval **fd, **buf, **length;
-       char *tmp;
+       char *tmpbuf;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(2, fd, length);
        convert_to_string_ex(buf);
 
-       tmp = emalloc(ZVAL(length, lval));
-       ret = read(ZVAL(fd, lval), tmp, ZVAL(length, lval));
-
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               ZVAL(buf, str.val) = tmp;
-               ZVAL(buf, str.len) = ret;
-
+       tmpbuf = emalloc(Z_LVAL_PP(length)*sizeof(char));
+       if (tmpbuf == NULL) {
+               php_error(E_WARNING, "Couldn't allocate memory from %s()", get_active_function_name());
+               RETURN_FALSE;
+       }
+       
+       ret = read(Z_LVAL_PP(fd), tmpbuf, Z_LVAL_PP(length));
+       
+       if (ret >= 0) {
+               Z_STRVAL_PP(buf) = tmpbuf;
+               Z_STRLEN_PP(buf) = ret;
+               
                RETURN_LONG(ret);
+       } else {
+               RETURN_LONG(-errno);
        }
 }
 /* }}} */
 
-/* {{{ proto long getsockname(long fd, string &addr, long &port)
+/* {{{ proto int getsockname(int fd, string &addr, int &port)
    Given an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the local side of a socket */
 
 /* A lock to prevent inet_ntoa() from causing problems in threading */
@@ -677,13 +611,14 @@ PHP_FUNCTION(getsockname)
        int salen = sizeof(struct sockaddr_in);
        int ret;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &fd, &addr, &port) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &fd, &addr, &port) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(2, fd, port);
        convert_to_string_ex(addr);
 
-       ret = getsockname(ZVAL(fd, lval), &sa, &salen);
+       ret = getsockname(Z_LVAL_PP(fd), &sa, &salen);
        if (ret < 0) {
                RETURN_LONG(-errno);
        } else {
@@ -696,10 +631,10 @@ PHP_FUNCTION(getsockname)
                bzero(tmp, strlen(addr_string) + 1);
                strncpy(tmp, addr_string, strlen(addr_string));
                inet_ntoa_lock = 0;
-
-               ZVAL(addr, str.val) = tmp;
-               ZVAL(addr, str.len) = strlen(tmp);
-               ZVAL(port, lval) = htons(sa.sin_port);
+               
+               Z_STRVAL_PP(addr) = tmp;
+               Z_STRLEN_PP(addr) = strlen(tmp);
+               Z_LVAL_PP(port)   = htons(sa.sin_port);
 
                RETURN_LONG(ret);
        }
@@ -707,7 +642,7 @@ PHP_FUNCTION(getsockname)
 /* }}} */
 
 #if 0
-/* {{{ proto long gethostbyname(string name, string &addr)
+/* {{{ proto int gethostbyname(string name, string &addr)
    Given a hostname, sets addr to be a human-readable version of the host's address */
 
 /* Another lock to prevent multiple threads from grabbing gethostbyname() */
@@ -720,7 +655,8 @@ PHP_FUNCTION(gethostbyname)
        char *tmp, *addr_string;
        struct hostent *host_struct;
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &name, &addr) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &name, &addr) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        convert_to_string_ex(name);
@@ -729,7 +665,7 @@ PHP_FUNCTION(gethostbyname)
        while (gethostbyname_lock == 1);
        gethostbyname_lock = 1;
 
-       host_struct = gethostbyname(ZVAL(name, str.val));
+       host_struct = gethostbyname(Z_STRVAL_PP(name));
        if (!host_struct) {
                gethostbyname_lock = 0;
                RETURN_LONG(-(h_errno) - 10000);        /* return a value that is out of range for errno */
@@ -748,9 +684,9 @@ PHP_FUNCTION(gethostbyname)
        inet_ntoa_lock = 0;
        gethostbyname_lock = 0;
 
-       ZVAL(addr, str.val) = tmp;
-       ZVAL(addr, str.len) = strlen(tmp);
-
+       Z_STRVAL_PP(addr) = tmp;
+       Z_STRLEN_PP(addr) = strlen(tmp);
+       
        RETURN_LONG(0);
 }
 
@@ -769,13 +705,15 @@ PHP_FUNCTION(getpeername)
        int salen = sizeof(struct sockaddr_in);
        int ret;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &fd, &addr, &port) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &fd, &addr, &port) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(2, fd, port);
        convert_to_string_ex(addr);
 
-       ret = getpeername(ZVAL(fd, lval), &sa, &salen);
+       ret = getpeername(Z_LVAL_PP(fd), &sa, &salen);
+       
        if (ret < 0) {
                RETURN_LONG(-errno);
        } else {
@@ -788,10 +726,10 @@ PHP_FUNCTION(getpeername)
                bzero(tmp, strlen(addr_string) + 1);
                strncpy(tmp, addr_string, strlen(addr_string));
                inet_ntoa_lock = 0;
-
-               ZVAL(addr, str.val) = tmp;
-               ZVAL(addr, str.len) = strlen(tmp);
-               ZVAL(port, lval) = htons(sa.sin_port);
+               
+               Z_STRVAL_PP(addr) = tmp;
+               Z_STRLEN_PP(addr) = strlen(tmp);
+               Z_LVAL_PP(addr) = htons(sa.sin_port);
 
                RETURN_LONG(ret);
        }
@@ -799,7 +737,7 @@ PHP_FUNCTION(getpeername)
 /* }}} */
 
 #if 0
-/* {{{ proto long gethostbyaddr(string addr, string &name)
+/* {{{ proto int gethostbyaddr(string addr, string &name)
    Given a human-readable address, sets name to be the host's name */
 
 /* Another lock to prevent multiple threads from grabbing gethostbyname() */
@@ -813,20 +751,24 @@ PHP_FUNCTION(gethostbyaddr)
        struct hostent *host_struct;
        struct in_addr addr_buf;
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &addr, &name) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &addr, &name) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_string_ex(name);
        convert_to_string_ex(addr);
+       convert_to_string_ex(name);
 
-       ret = inet_aton(ZVAL(addr, str.val), &addr_buf);
+       ret = inet_aton(Z_STRVAL_PP(addr), &addr_buf);
+       
        if (ret < 0) {
                RETURN_LONG(-EINVAL);
        }
+       
        while (gethostbyaddr_lock == 1);
        gethostbyaddr_lock = 1;
 
-       host_struct = gethostbyname((char *) &addr_buf, sizeof(addr_buf), AF_INET);
+       host_struct = gethostbyname((char *)&addr_buf, sizeof(addr_buf), AF_INET);
+
        if (!host_struct) {
                gethostbyaddr_lock = 0;
                RETURN_LONG(-(h_errno) - 10000);
@@ -835,14 +777,15 @@ PHP_FUNCTION(gethostbyaddr)
                gethostbyaddr_lock = 0;
                RETURN_LONG(-EINVAL);
        }
+       
        addr_string = host_struct->h_name;
        tmp = emalloc(strlen(addr_string) + 1);
        strncpy(tmp, addr_string, strlen(addr_string));
 
        gethostbyaddr_lock = 0;
 
-       ZVAL(addr, str.val) = tmp;
-       ZVAL(addr, str.len) = strlen(tmp);
+       Z_STRVAL_PP(addr) = tmp;
+       Z_STRLEN_PP(addr) = strlen(tmp);
 
        RETURN_LONG(0);
 }
@@ -850,36 +793,36 @@ PHP_FUNCTION(gethostbyaddr)
 
 #endif
 
-/* {{{ proto long socket(long domain, long type, long protocol)
+/* {{{ proto int socket(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)
 {
        zval **domain, **type, **protocol;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &domain, &type, &protocol) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &domain, &type, &protocol) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(3, domain, type, protocol);
 
-       if (ZVAL(domain, lval) != AF_INET && ZVAL(domain, lval) != AF_UNIX) {
-               zend_error(E_WARNING, "invalid socket domain specified - assuming AF_INET");
-               ZVAL(domain, lval) = AF_INET;
+       if (Z_LVAL_PP(domain) != AF_INET && Z_LVAL_PP(domain) != AF_UNIX) {
+               php_error(E_WARNING, "invalid socket domain specified - assuming AF_INET");
+               Z_LVAL_PP(domain) = AF_INET;
        }
-       if (ZVAL(type, lval) > 10) {
-               zend_error(E_WARNING, "invalid socket type specified - assuming SOCK_STREAM");
-               ZVAL(type, lval) = SOCK_STREAM;
-       }
-       ret = socket(ZVAL(domain, lval), ZVAL(type, lval), ZVAL(protocol, lval));
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
+       
+       if (Z_LVAL_PP(type) > 10) {
+               php_error(E_WARNING, "invalid socket type specified - assuming SOCK_STREAM");
+               Z_LVAL_PP(type) = SOCK_STREAM;
        }
+       
+       ret = socket(Z_LVAL_PP(domain), Z_LVAL_PP(type), Z_LVAL_PP(protocol));
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto long connect(long sockfd, string addr, long port)
+/* {{{ proto int connect(int sockfd, string addr, int port)
    Opens a connection to addr:port on the socket specified by sockfd */
 PHP_FUNCTION(connect)
 {
@@ -890,35 +833,33 @@ PHP_FUNCTION(connect)
        struct in_addr addr_buf;
        struct hostent *host_struct;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &sockfd, &addr, &port) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &sockfd, &addr, &port) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(2, sockfd, port);
        convert_to_string_ex(addr);
 
        bzero(&sa, sizeof(sa));
-       sa.sin_port = ZVAL(port, lval);
+       sa.sin_port = Z_LVAL_PP(port);
 
-       if (inet_aton(ZVAL(addr, str.val), &addr_buf) == 0) {
+       if (inet_aton(Z_STRVAL_PP(addr), &addr_buf) == 0) {
                sa.sin_addr.s_addr = addr_buf.s_addr;
        } else {
-               host_struct = gethostbyname(ZVAL(addr, str.val));
+               host_struct = gethostbyname(Z_STRVAL_PP(addr));
                if (host_struct->h_addrtype != AF_INET) {
                        RETURN_LONG(-EINVAL);
                }
                sa.sin_addr.s_addr = (int) *(host_struct->h_addr_list[0]);
        }
 
-       ret = connect(ZVAL(sockfd, lval), (struct sockaddr *) &sa, salen);
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *)&sa, salen);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto string strerror(long errno)
+/* {{{ proto string strerror(int errno)
    Returns a string describing an error */
 PHP_FUNCTION(strerror)
 {
@@ -926,24 +867,22 @@ PHP_FUNCTION(strerror)
        const char *buf;
        char *obuf;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &error) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 1 || 
+           zend_get_parameters_ex(1, &error) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       if (ZVAL(error, lval) < -10000) {
-               ZVAL(error, lval) += 10000;
-               buf = hstrerror(-(ZVAL(error, lval)));
+       if (Z_LVAL_PP(error) < -10000) {
+               Z_LVAL_PP(error) += 10000;
+               buf = hstrerror(-(Z_LVAL_PP(error)));
        } else {
-               buf = strerror(-(ZVAL(error, lval)));
+               buf = strerror(-(Z_LVAL_PP(error)));
        }
-
-       obuf = estrndup(buf, strlen(buf));
-       ZVAL(&return_value, str.val) = obuf;
-       ZVAL(&return_value, str.len) = strlen(buf);
-       return_value->type = IS_STRING;
+       
+       RETURN_STRING((char *)buf, 1);
 }
 /* }}} */
 
-/* {{{ proto long bind(long sockfd, long addr [, long port])
+/* {{{ proto int bind(int sockfd, string addr [, int port])
    Binds an open socket to a listening port */
 /* Port is only specified if sockfd is in the AF_INET family. */
 PHP_FUNCTION(bind)
@@ -952,39 +891,33 @@ PHP_FUNCTION(bind)
        long ret;
        struct sockaddr sock_type;
        socklen_t length = sizeof(sock_type);
-
-       if (ZEND_NUM_ARGS() < 2) {
-               WRONG_PARAM_COUNT;
-       }
-       switch (ZEND_NUM_ARGS()) {
-       case 2:
-               if (zend_get_parameters_ex(2, &arg0, &arg1) == FAILURE) {
-                       WRONG_PARAM_COUNT;
-               }
-               break;
-       case 3:
-               if (zend_get_parameters_ex(3, &arg0, &arg1, &arg2) == FAILURE) {
+       
+       switch (ZEND_NUM_ARGS())
+       {
+               case 2:
+                       if (zend_get_parameters_ex(2, &arg0, &arg1) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               case 3:
+                       if (zend_get_parameters_ex(3, &arg0, &arg1, &arg2) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               default:
                        WRONG_PARAM_COUNT;
-               }
-               break;
-       default:
-               WRONG_PARAM_COUNT;
        }
 
        convert_to_long_ex(arg0);
 
-       ret = getsockname(ZVAL(arg0, lval), &sock_type, &length);
+       ret = getsockname(Z_LVAL_PP(arg0), &sock_type, &length);
        if (ret < 0) {
                RETURN_LONG(-errno);
        }
        if (sock_type.sa_family == AF_UNIX) {
                struct sockaddr_un sa;
-
-               if (ZEND_NUM_ARGS() < 2) {
-                       WRONG_PARAM_COUNT;
-               }
-               snprintf(sa.sun_path, 108, "%s", ZVAL(arg1, str.val));
-               ret = bind(ZVAL(arg0, lval), &sa, SUN_LEN(&sa));
+               snprintf(sa.sun_path, 108, "%s", Z_STRVAL_PP(arg1));
+               ret = bind(Z_LVAL_PP(arg0), &sa, SUN_LEN(&sa));
        } else if (sock_type.sa_family == AF_INET) {
                struct sockaddr_in sa;
                struct in_addr addr_buf;
@@ -992,27 +925,27 @@ PHP_FUNCTION(bind)
                if (ZEND_NUM_ARGS() != 3) {
                        WRONG_PARAM_COUNT;
                }
-               sa.sin_port = htons(ZVAL(arg2, lval));
-               if (inet_aton(ZVAL(arg1, str.val), &addr_buf) < 0) {
-                       struct hostent *host_struct = gethostbyname(ZVAL(arg1, str.val));
+               
+               sa.sin_port = htons(Z_LVAL_PP(arg2));
+
+               if (inet_aton(Z_STRVAL_PP(arg1), &addr_buf) < 0) {
+                       struct hostent *host_struct;
 
-                       if (host_struct == NULL) {
+                       if ((host_struct = gethostbyname(Z_STRVAL_PP(arg1))) == NULL) {
                                RETURN_LONG(-(h_errno) - 10000);
                        }
+                       
                        sa.sin_addr.s_addr = (int) *(host_struct->h_addr_list[0]);
                } else {
                        sa.sin_addr.s_addr = addr_buf.s_addr;
                }
-               ret = bind(ZVAL(arg0, lval), &sa, sizeof(sa));
-       } else {
-               RETURN_LONG(-EPROTONOSUPPORT);
-       }
 
-       if (ret < 0) {
-               RETURN_LONG(-errno);
+               ret = bind(Z_LVAL_PP(arg0), &sa, sizeof(sa));
        } else {
-               RETURN_LONG(ret);
+               RETURN_LONG(-EPROTONOSUPPORT);
        }
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
@@ -1024,44 +957,38 @@ PHP_FUNCTION(bind)
 
 PHP_FUNCTION(build_iovec)
 {
-       zval **num_vectors, **vector_len;
+       zval ***args = (zval ***)NULL;
        php_iovec_t *vector;
        struct iovec *vector_array;
-       void **p;
-       int arg_count;
-       int i;
-
-       ELS_FETCH();
-
-       if (ZEND_NUM_ARGS() < 1) {
+       int i, j, num_vectors, argcount = ZEND_NUM_ARGS();
+       SOCKETSLS_FETCH();
+       
+       args = emalloc(argcount * sizeof(zval *));
+
+       if (argcount < 1 ||
+           zend_get_parameters_array_ex(argcount, args) == FAILURE) {
+               if (args)
+                       efree(args);
                WRONG_PARAM_COUNT;
        }
-       p = EG(argument_stack).top_element - 2;
-       arg_count = (ulong) * p;
-
-       num_vectors = (zval **) p - (arg_count--);
-
-       convert_to_long_ex(num_vectors);
-
-       vector_array = emalloc(sizeof(struct iovec) * (ZVAL(num_vectors, lval) + 1));
-
-       for (i = 0; i < ZVAL(num_vectors, lval); i++) {
-               if (arg_count < 1) {
-                       WRONG_PARAM_COUNT;
-               }
-               vector_len = (zval **) p - (arg_count--);
+       
+       convert_to_long_ex(args[0]);
+       num_vectors = Z_LVAL_PP(args[0]);
+       
+       vector_array = emalloc(sizeof(struct iovec) * (num_vectors + 1));
 
-               convert_to_long_ex(vector_len);
-
-               vector_array[i].iov_base = emalloc(ZVAL(vector_len, lval));
-               vector_array[i].iov_len = ZVAL(vector_len, lval);
+       for (i = 0, j = 1; i < num_vectors; i++, j++) {
+               convert_to_long_ex(args[j]);
+               
+               vector_array[i].iov_base = emalloc(Z_LVAL_PP(args[j]));
+               vector_array[i].iov_len = Z_LVAL_PP(args[j]);
        }
 
        vector = emalloc(sizeof(php_iovec_t));
        vector->iov_array = vector_array;
-       vector->count = ZVAL(num_vectors, lval);
+       vector->count = num_vectors;
 
-       ZEND_REGISTER_RESOURCE(return_value, vector, le_iov);
+       ZEND_REGISTER_RESOURCE(return_value, vector, SOCKETSG(le_iov));
 }
 /* }}} */
 
@@ -1071,20 +998,21 @@ PHP_FUNCTION(fetch_iovec)
 {
        zval **iovec_id, **iovec_position;
        php_iovec_t *vector;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &iovec_id, &iovec_position) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &iovec_id, &iovec_position) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+       
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
 
-       if (ZVAL(iovec_position, lval) > vector->count) {
-               zend_error(E_WARNING, "Can't access a vector position past the amount of vectors set in the array");
+       if (Z_LVAL_PP(iovec_position) > vector->count) {
+               php_error(E_WARNING, "Can't access a vector position past the amount of vectors set in the array");
                RETURN_NULL();
        }
-       RETURN_STRINGL(vector->iov_array[ZVAL(iovec_position, lval)].iov_base,
-                      vector->iov_array[ZVAL(iovec_position, lval)].iov_len,
-                      1);
+       RETURN_STRINGL(vector->iov_array[Z_LVAL_PP(iovec_position)].iov_base,
+                      vector->iov_array[Z_LVAL_PP(iovec_position)].iov_len, 1);
 }
 /* }}} */
 
@@ -1094,22 +1022,26 @@ PHP_FUNCTION(set_iovec)
 {
        zval **iovec_id, **iovec_position, **new_val;
        php_iovec_t *vector;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &iovec_id, &iovec_position, &new_val) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 3 || 
+           zend_get_parameters_ex(3, &iovec_id, &iovec_position, &new_val) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+       
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
 
-       if (ZVAL(iovec_position, lval) > vector->count) {
-               zend_error(E_WARNING, "Can't access a vector position outside of the vector array bounds");
+       if (Z_LVAL_PP(iovec_position) > vector->count) {
+               php_error(E_WARNING, "Can't access a vector position outside of the vector array bounds");
                RETURN_FALSE;
        }
-       if (vector->iov_array[ZVAL(iovec_position, lval)].iov_base) {
-               efree(vector->iov_array[ZVAL(iovec_position, lval)].iov_base);
+       
+       if (vector->iov_array[Z_LVAL_PP(iovec_position)].iov_base) {
+               efree(vector->iov_array[Z_LVAL_PP(iovec_position)].iov_base);
        }
-       vector->iov_array[ZVAL(iovec_position, lval)].iov_base = estrdup(ZVAL(new_val, str.val));
-       vector->iov_array[ZVAL(iovec_position, lval)].iov_len = strlen(ZVAL(new_val, str.val));
+       
+       vector->iov_array[Z_LVAL_PP(iovec_position)].iov_base = estrdup(Z_STRVAL_PP(new_val));
+       vector->iov_array[Z_LVAL_PP(iovec_position)].iov_len = strlen(Z_STRVAL_PP(new_val));
 
        RETURN_TRUE;
 }
@@ -1122,18 +1054,20 @@ PHP_FUNCTION(add_iovec)
        zval **iovec_id, **iov_len;
        php_iovec_t *vector;
        struct iovec *vector_array;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &iovec_id, &iov_len) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &iovec_id, &iov_len) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
 
        vector_array = emalloc(sizeof(struct iovec) * (vector->count + 2));
        bcopy(vector->iov_array, vector_array, sizeof(struct iovec) * vector->count);
 
-       vector_array[vector->count].iov_base = emalloc(ZVAL(iov_len, lval));
-       vector_array[vector->count].iov_len = ZVAL(iov_len, lval);
+       vector_array[vector->count].iov_base = emalloc(Z_LVAL_PP(iov_len));
+       vector_array[vector->count].iov_len = Z_LVAL_PP(iov_len);
        efree(vector->iov_array);
        vector->iov_array = vector_array;
        vector->count++;
@@ -1151,23 +1085,25 @@ PHP_FUNCTION(delete_iovec)
        php_iovec_t *vector;
        struct iovec *vector_array;
        int i;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &iovec_id, &iov_pos) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &iovec_id, &iov_pos) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
 
-       if (ZVAL(iov_pos, lval) > vector->count) {
-               zend_error(E_WARNING, "Can't delete an IO vector that is out of array bounds");
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
+
+       if (Z_LVAL_PP(iov_pos) > vector->count) {
+               php_error(E_WARNING, "Can't delete an IO vector that is out of array bounds");
                RETURN_FALSE;
        }
        vector_array = emalloc(vector->count * sizeof(struct iovec));
 
        for (i = 0; i < vector->count; i++) {
-               if (i < ZVAL(iov_pos, lval)) {
+               if (i < Z_LVAL_PP(iov_pos)) {
                        bcopy(&(vector_array[i]), &(vector->iov_array[i]), sizeof(struct iovec));
-               } else if (i > ZVAL(iov_pos, lval)) {
+               } else if (i > Z_LVAL_PP(iov_pos)) {
                        bcopy(&(vector_array[i - 1]), &(vector->iov_array[i]), sizeof(struct iovec));
                }
        }
@@ -1187,21 +1123,15 @@ PHP_FUNCTION(free_iovec)
        zval **iovec_id;
        php_iovec_t *vector;
        int pos;
+       SOCKETSLS_FETCH();
 
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &iovec_id) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+       
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
 
-       for (pos = 0; pos < vector->count; pos++) {
-               efree(vector->iov_array[pos].iov_base);
-       }
-
-       efree(vector->iov_array);
-
-       vector->iov_array = NULL;
-       vector->count = 0;
+       zend_list_delete(Z_LVAL_PP(iovec_id));
 
        RETURN_TRUE;
 }
@@ -1214,46 +1144,44 @@ PHP_FUNCTION(readv)
        zval **fd, **iovec_id;
        php_iovec_t *vector;
        int ret;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fd, &iovec_id) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &fd, &iovec_id) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
 
-       ret = readv(ZVAL(fd, lval), vector->iov_array, vector->count);
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
+
+       ret = readv(Z_LVAL_PP(fd), vector->iov_array, vector->count);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto long writev(long fd, resource iovec_id)
-   Writes to a fd, using the scatter-gather array defined by iovec_id */
+/* {{{ proto int writev(int fd, resource iovec_id)
+   Writes to a file descriptor, fd, using the scatter-gather array defined by iovec_id */
 PHP_FUNCTION(writev)
 {
        zval **fd, **iovec_id;
        php_iovec_t *vector;
        int ret;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fd, &iovec_id) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 2 || 
+           zend_get_parameters_ex(2, &fd, &iovec_id) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       (*iovec_id)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+       
+       ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", SOCKETSG(le_iov));
 
-       ret = writev(ZVAL(fd, lval), vector->iov_array, vector->count);
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ret = writev(Z_LVAL_PP(fd), vector->iov_array, vector->count);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto long recv(long fd, string buf, long len, long flags)
+/* {{{ proto int recv(int fd, string buf, int len, long flags)
    Receive data from a connected socket */
 /* May be used with SOCK_DGRAM sockets. */
 PHP_FUNCTION(recv)
@@ -1262,25 +1190,27 @@ PHP_FUNCTION(recv)
        int ret;
        char *recv_buf;
 
-       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &fd, &buf, &len, &flags) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 4 || 
+           zend_get_parameters_ex(4, &fd, &buf, &len, &flags) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(3, fd, len, flags);
        convert_to_string_ex(buf);
 
-       recv_buf = emalloc(ZVAL(len, lval) + 2);
-       bzero(recv_buf, ZVAL(len, lval) + 2);
+       recv_buf = emalloc(Z_LVAL_PP(len) + 2);
+       bzero(recv_buf, Z_LVAL_PP(len) + 2);
 
-       ret = recv(ZVAL(fd, lval), recv_buf, ZVAL(len, lval), ZVAL(flags, lval));
+       ret = recv(Z_LVAL_PP(fd), recv_buf, Z_LVAL_PP(len), Z_LVAL_PP(flags));
+       
        if (ret < 0) {
                efree(recv_buf);
                RETURN_LONG(-errno);
        } else {
-               if (ZVAL(buf, str.val) != NULL) {
-                       efree(ZVAL(buf, str.val));
+               if (Z_STRVAL_PP(buf) != NULL) {
+                       efree(Z_STRVAL_PP(buf));
                }
-               ZVAL(buf, str.val) = estrndup(recv_buf, strlen(recv_buf));
-               ZVAL(buf, str.len) = strlen(recv_buf);
+               Z_STRVAL_PP(buf) = estrndup(recv_buf, strlen(recv_buf));
+               Z_STRLEN_PP(buf) = strlen(recv_buf);
 
                efree(recv_buf);
 
@@ -1289,7 +1219,7 @@ PHP_FUNCTION(recv)
 }
 /* }}} */
 
-/* {{{ proto long send(long fd, string buf, long len, long flags)
+/* {{{ proto int send(int fd, string buf, int len, int flags)
    Send data to a connected socket */
 /* May be used with SOCK_DGRAM sockets. */
 PHP_FUNCTION(send)
@@ -1297,24 +1227,22 @@ PHP_FUNCTION(send)
        zval **fd, **buf, **len, **flags;
        int ret;
 
-       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &fd, &buf, &len, &flags) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 4 || 
+           zend_get_parameters_ex(4, &fd, &buf, &len, &flags) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        v_convert_to_long_ex(3, fd, len, flags);
        convert_to_string_ex(buf);
 
-       ret = send(ZVAL(fd, lval), ZVAL(buf, str.val),
-                  (ZVAL(buf, str.len) < ZVAL(len, lval) ? ZVAL(buf, str.len) : ZVAL(len, lval)),
-                  ZVAL(flags, lval));
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
-       }
+       ret = send(Z_LVAL_PP(fd), Z_STRVAL_PP(buf),
+                  (Z_STRLEN_PP(buf) < Z_LVAL_PP(len) ? Z_STRLEN_PP(buf) : Z_LVAL_PP(len)),
+                  Z_LVAL_PP(flags));
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
 /* }}} */
 
-/* {{{ proto long recvfrom(long fd, string &buf, long len, long flags, string &name [, long &port])
+/* {{{ proto int recvfrom(int fd, string &buf, int len, int flags, string &name [, int &port])
    Receive data from a socket, connected or not */
 PHP_FUNCTION(recvfrom)
 {
@@ -1323,117 +1251,123 @@ PHP_FUNCTION(recvfrom)
        struct sockaddr sa;
        socklen_t salen;
 
-       if (ZEND_NUM_ARGS() < 5) {
-               WRONG_PARAM_COUNT;
-       }
-       switch (ZEND_NUM_ARGS()) {
-       case 5:
-               if (zend_get_parameters_ex(5, &fd, &buf, &len, &flags, &name) == FAILURE) {
-                       WRONG_PARAM_COUNT;
-               }
-               break;
-       case 6:
-               if (zend_get_parameters_ex(6, &fd, &buf, &len, &flags, &name, &port) == FAILURE) {
+       switch (ZEND_NUM_ARGS()) 
+       {
+               case 5:
+                       if (zend_get_parameters_ex(5, &fd, &buf, &len, &flags, &name) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               case 6:
+                       if (zend_get_parameters_ex(6, &fd, &buf, &len, &flags, &name, &port) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               default:
                        WRONG_PARAM_COUNT;
-               }
-               break;
-       default:
-               WRONG_PARAM_COUNT;
        }
 
        salen = sizeof(sa);
 
-       ret = getsockname(ZVAL(fd, lval), &sa, &salen);
+       ret = getsockname(Z_LVAL_PP(fd), &sa, &salen);
+       
        if (ret < 0) {
                RETURN_LONG(-errno);
        }
-       switch (sa.sa_family) {
-       case AF_UNIX:
-               {
-                       struct sockaddr_un sun;
-                       char *recv_buf = emalloc(ZVAL(len, lval) + 2);
-                       socklen_t sun_length = sizeof(sun);
+       
+       switch (sa.sa_family)
+       {
+               case AF_UNIX:
+                       {
+                               struct sockaddr_un sun;
+                               char *recv_buf = emalloc(Z_LVAL_PP(len) + 2);
+                               socklen_t sun_length = sizeof(sun);
+       
+                               if (ZEND_NUM_ARGS() != 5) {
+                                       WRONG_PARAM_COUNT;
+                               }
+                               bzero(recv_buf, Z_LVAL_PP(len) + 2);
 
-                       if (ZEND_NUM_ARGS() != 5) {
-                               WRONG_PARAM_COUNT;
-                       }
-                       bzero(recv_buf, ZVAL(len, lval) + 2);
+                               ret = recvfrom(Z_LVAL_PP(fd), recv_buf, Z_LVAL_PP(len), Z_LVAL_PP(flags),
+                                              (struct sockaddr *)&sun, (socklen_t *) & sun_length);
 
-                       ret = recvfrom(ZVAL(fd, lval), recv_buf, ZVAL(len, lval), ZVAL(flags, lval),
-                                      (struct sockaddr *) &sun, (socklen_t *) & sun_length);
+                               if (ret < 0) {
+                                       efree(recv_buf);
+                                       RETURN_LONG(-errno);
+                               }
+                               
+                               if (Z_STRVAL_PP(buf) != NULL) {
+                                       efree(Z_STRVAL_PP(buf));
+                               }
+                               
+                               Z_STRVAL_PP(buf) = estrndup(recv_buf, strlen(recv_buf));
+                               Z_STRLEN_PP(buf) = strlen(recv_buf);
+
+                               if (Z_STRVAL_PP(name) != NULL) {
+                                       efree(Z_STRVAL_PP(name));
+                               }
+                               
+                               Z_STRVAL_PP(name) = estrdup(sun.sun_path);
+                               Z_STRLEN_PP(name) = strlen(sun.sun_path);
 
-                       if (ret < 0) {
                                efree(recv_buf);
-                               RETURN_LONG(-errno);
-                       }
-                       if (ZVAL(buf, str.val) != NULL) {
-                               efree(ZVAL(buf, str.val));
-                       }
-                       ZVAL(buf, str.val) = estrndup(recv_buf, strlen(recv_buf));
-                       ZVAL(buf, str.len) = strlen(recv_buf);
 
-                       if (ZVAL(name, str.val) != NULL) {
-                               efree(ZVAL(name, str.val));
+                               RETURN_LONG(ret);
                        }
-                       ZVAL(name, str.val) = estrdup(sun.sun_path);
-                       ZVAL(name, str.len) = strlen(sun.sun_path);
-
-                       efree(recv_buf);
-
-                       RETURN_LONG(ret);
-               }
-               break;
-       case AF_INET:
-               {
-                       struct sockaddr_in sin;
-                       char *recv_buf = emalloc(ZVAL(len, lval) + 2);
-                       socklen_t sin_length = sizeof(sin);
-                       char *address;
+                       break;
+               case AF_INET:
+                       {
+                               struct sockaddr_in sin;
+                               char *recv_buf = emalloc(Z_LVAL_PP(len) + 2);
+                               socklen_t sin_length = sizeof(sin);
+                               char *address;
 
-                       if (ZEND_NUM_ARGS() != 6) {
-                               WRONG_PARAM_COUNT;
-                       }
-                       bzero(recv_buf, ZVAL(len, lval) + 2);
+                               if (ZEND_NUM_ARGS() != 6) {
+                                       WRONG_PARAM_COUNT;
+                               }
+                               bzero(recv_buf, Z_LVAL_PP(len) + 2);
 
-                       ret = recvfrom(ZVAL(fd, lval), recv_buf, ZVAL(len, lval), ZVAL(flags, lval),
-                                      (struct sockaddr *) &sin, (socklen_t *) & sin_length);
+                               ret = recvfrom(Z_LVAL_PP(fd), recv_buf, Z_LVAL_PP(len), Z_LVAL_PP(flags),
+                                              (struct sockaddr *)&sin, (socklen_t *) & sin_length);
+       
+                               if (ret < 0) {
+                                       efree(recv_buf);
+                                       RETURN_LONG(-errno);
+                               }
+                               
+                               if (Z_STRVAL_PP(buf) != NULL) {
+                                       efree(Z_STRVAL_PP(buf));
+                               }
+                               
+                               if (Z_STRVAL_PP(name) != NULL) {
+                                       efree(Z_STRVAL_PP(name));
+                               }
+                               
+                               Z_STRVAL_PP(buf) = estrdup(recv_buf);
+                               Z_STRLEN_PP(buf) = strlen(recv_buf);
 
-                       if (ret < 0) {
+                               address = inet_ntoa(sin.sin_addr);
+                               if (address == NULL) {
+                                       Z_STRVAL_PP(name) = estrdup("0.0.0.0");
+                                       Z_STRLEN_PP(name) = strlen(Z_STRVAL_PP(name));
+                               } else {
+                                       Z_STRVAL_PP(name) = estrdup(address);
+                                       Z_STRLEN_PP(name) = strlen(address);
+                               }
+                               
+                               Z_LVAL_PP(port) = ntohs(sin.sin_port);;
+       
                                efree(recv_buf);
-                               RETURN_LONG(-errno);
-                       }
-                       if (ZVAL(buf, str.val) != NULL) {
-                               efree(ZVAL(buf, str.val));
-                       }
-                       if (ZVAL(name, str.val) != NULL) {
-                               efree(ZVAL(name, str.val));
-                       }
-                       ZVAL(buf, str.val) = estrdup(recv_buf);
-                       ZVAL(buf, str.len) = strlen(recv_buf);
-
-                       address = inet_ntoa(sin.sin_addr);
-                       if (address == NULL) {
-                               ZVAL(name, str.val) = estrdup("0.0.0.0");
-                               ZVAL(name, str.len) = strlen(ZVAL(name, str.val));
-                       } else {
-                               ZVAL(name, str.val) = estrdup(address);
-                               ZVAL(name, str.len) = strlen(address);
+                               RETURN_LONG(ret);
                        }
-
-                       ZVAL(port, lval) = ntohs(sin.sin_port);
-
-                       efree(recv_buf);
-                       RETURN_LONG(ret);
-               }
-               break;
-       default:
-               RETURN_LONG(-EPROTONOSUPPORT);
-
+                       break;
+               default:
+                       RETURN_LONG(-EPROTONOSUPPORT);
        }
 }
 /* }}} */
 
-/* {{{ proto long sendto(long fd, string buf, long len, long flags, string addr [, long port])
+/* {{{ proto int sendto(int fd, string buf, int len, int flags, string addr [, int port])
    Sends a message to a socket, whether it is connected or not */
 PHP_FUNCTION(sendto)
 {
@@ -1442,15 +1376,16 @@ PHP_FUNCTION(sendto)
        socklen_t salen = sizeof(sa);
        int ret;
 
-       switch (ZEND_NUM_ARGS()) {
-       case 5:
-               ret = zend_get_parameters_ex(5, &fd, &buf, &len, &flags, &addr);
-               break;
-       case 6:
-               ret = zend_get_parameters_ex(6, &fd, &buf, &len, &flags, &addr, &port);
-               break;
-       default:
-               ret = FAILURE;
+       switch (ZEND_NUM_ARGS())
+       {
+               case 5:
+                       ret = zend_get_parameters_ex(5, &fd, &buf, &len, &flags, &addr);
+                       break;
+               case 6:
+                       ret = zend_get_parameters_ex(6, &fd, &buf, &len, &flags, &addr, &port);
+                       break;
+               default:
+                       ret = FAILURE;
        }
 
        if (ret == FAILURE) {
@@ -1462,72 +1397,69 @@ PHP_FUNCTION(sendto)
        if (ZEND_NUM_ARGS() == 6) {
                convert_to_long_ex(port);
        }
-       ret = getsockname(ZVAL(fd, lval), &sa, &salen);
+
+       ret = getsockname(Z_LVAL_PP(fd), &sa, &salen);
        if (ret < 0) {
                RETURN_LONG(-errno);
        }
-       switch (sa.sa_family) {
-       case AF_UNIX:
-               {
-                       struct sockaddr_un sun;
-
-                       if (ZEND_NUM_ARGS() != 5) {
-                               WRONG_PARAM_COUNT;
-                       }
-                       bzero(&sun, sizeof(sun));
-                       sun.sun_family = AF_UNIX;
-                       snprintf(sun.sun_path, 108, "%s", ZVAL(port, str.val));
-                       ret = sendto(ZVAL(fd, lval), ZVAL(buf, str.val),
-                                    (ZVAL(buf, str.len) > ZVAL(len, lval) ? ZVAL(len, lval) : ZVAL(buf, str.len)),
-                                    ZVAL(flags, lval), &sun, SUN_LEN(&sun));
-                       if (ret < 0) {
-                               RETURN_LONG(-errno);
-                       } else {
-                               RETURN_LONG(ret);
-                       }
-               }
-               break;
-       case AF_INET:
-               {
-                       struct sockaddr_in sin;
-                       struct in_addr addr_buf;
 
-                       if (ZEND_NUM_ARGS() != 6) {
-                               WRONG_PARAM_COUNT;
+       switch (sa.sa_family)
+       {
+               case AF_UNIX:
+                       {
+                               struct sockaddr_un sun;
+       
+                               if (ZEND_NUM_ARGS() != 5) {
+                                       WRONG_PARAM_COUNT;
+                               }
+                               bzero(&sun, sizeof(sun));
+                               sun.sun_family = AF_UNIX;
+                               snprintf(sun.sun_path, 108, "%s", Z_STRVAL_PP(port));
+                               ret = sendto(Z_LVAL_PP(fd), Z_STRVAL_PP(buf),
+                                            (Z_STRLEN_PP(buf) > Z_LVAL_PP(len) ? Z_LVAL_PP(len) : Z_STRLEN_PP(buf)),
+                                            Z_LVAL_PP(flags), &sun, SUN_LEN(&sun));
+
+                               RETURN_LONG(((ret < 0) ? -errno : ret));
                        }
-                       bzero(&sin, sizeof(sin));
-                       sin.sin_family = AF_INET;
+                       break;
+               case AF_INET:
+                       {
+                               struct sockaddr_in sin;
+                               struct in_addr addr_buf;
 
-                       if (inet_aton(ZVAL(addr, str.val), &addr_buf) == 0) {
-                               sin.sin_addr.s_addr = addr_buf.s_addr;
-                       } else {
-                               struct hostent *he;
+                               if (ZEND_NUM_ARGS() != 6) {
+                                       WRONG_PARAM_COUNT;
+                               }
+                               bzero(&sin, sizeof(sin));
+                               sin.sin_family = AF_INET;
+       
+                               if (inet_aton(Z_STRVAL_PP(addr), &addr_buf) == 0) {
+                                       sin.sin_addr.s_addr = addr_buf.s_addr;
+                               } else {
+                                       struct hostent *he;
 
-                               he = gethostbyname(ZVAL(addr, str.val));
-                               if (he == NULL) {
-                                       RETURN_LONG(-(h_errno) - 10000);
+                                       he = gethostbyname(Z_STRVAL_PP(addr));
+                                       if (he == NULL) {
+                                               RETURN_LONG(-(h_errno) - 10000);
+                                       }
+                                       sin.sin_addr.s_addr = *(int *) (he->h_addr_list[0]);
                                }
-                               sin.sin_addr.s_addr = *(int *) (he->h_addr_list[0]);
-                       }
-                       sin.sin_port = htons(ZVAL(port, lval));
-                       ret = sendto(ZVAL(fd, lval), ZVAL(buf, str.val),
-                                    (ZVAL(buf, str.len) > ZVAL(len, lval) ? ZVAL(len, lval) : ZVAL(buf, str.len)),
-                                    ZVAL(flags, lval), &sin, sizeof(sin));
-                       if (ret < 0) {
-                               RETURN_LONG(-errno);
-                       } else {
-                               RETURN_LONG(ret);
+                               sin.sin_port = htons(Z_LVAL_PP(port));
+                               ret = sendto(Z_LVAL_PP(fd), Z_STRVAL_PP(buf),
+                                            (Z_STRLEN_PP(buf) > Z_LVAL_PP(len) ? Z_LVAL_PP(len) : Z_STRLEN_PP(buf)),
+                                            Z_LVAL_PP(flags), &sin, sizeof(sin));
+                               
+                               RETURN_LONG(((ret < 0) ? -errno : ret));
                        }
-               }
-               break;
-       default:
-               RETURN_LONG(-EPROTONOSUPPORT);
-               break;
+                       break;
+               default:
+                       RETURN_LONG(-EPROTONOSUPPORT);
+                       break;
        }
 }
 /* }}} */
 
-/* {{{ proto long recvmsg(long fd, resource iovec, array &control, long &controllen, long &flags, string &addr [, long &port])
+/* {{{ proto int recvmsg(int fd, resource iovec, array &control, int &controllen, int &flags, string &addr [, int &port])
    Used to receive messages on a socket, whether connection-oriented or not */
 PHP_FUNCTION(recvmsg)
 {
@@ -1541,94 +1473,105 @@ PHP_FUNCTION(recvmsg)
        struct cmsghdr *ctl_buf;
        socklen_t salen = sizeof(sa);
        int ret;
+       SOCKETSLS_FETCH();
 
-       switch (ZEND_NUM_ARGS()) {
-       case 6:
-               ret = zend_get_parameters_ex(6, &fd, &iovec, &control, &controllen, &flags, &addr);
-               break;
-       case 7:
-               ret = zend_get_parameters_ex(7, &fd, &iovec, &control, &controllen, &flags, &addr, &port);
-               break;
-       default:
-               WRONG_PARAM_COUNT;
+       switch (ZEND_NUM_ARGS())
+       {
+               case 6:
+                       ret = zend_get_parameters_ex(6, &fd, &iovec, &control, &controllen, &flags, &addr);
+                       break;
+               case 7:
+                       ret = zend_get_parameters_ex(7, &fd, &iovec, &control, &controllen, &flags, &addr, &port);
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
        }
 
        if (ret == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       v_convert_to_long_ex(4, fd, iovec, controllen, flags);
+
+       v_convert_to_long_ex(3, fd, controllen, flags);
        convert_to_string_ex(control);
        convert_to_string_ex(addr);
        if (ZEND_NUM_ARGS() == 7) {
                convert_to_long_ex(port);
        }
-       (*iovec)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(iov, php_iovec_t *, iovec, -1, "IO vector table", le_iov);
 
-       ret = getsockname(ZVAL(fd, lval), &sa, &salen);
+       ZEND_FETCH_RESOURCE(iov, php_iovec_t *, iovec, -1, "IO vector table", SOCKETSG(le_iov));
+
+       ret = getsockname(Z_LVAL_PP(fd), &sa, &salen);
        if (ret < 0) {
                RETURN_LONG(-errno);
        }
-       if (ZVAL(controllen, lval) > sizeof(struct cmsghdr)) {
-               ctl_buf = emalloc(ZVAL(controllen, lval));
+       
+       if (Z_LVAL_PP(controllen) > sizeof(struct cmsghdr)) {
+               ctl_buf = emalloc(Z_LVAL_PP(controllen));
        } else {
                ctl_buf = NULL;
        }
 
-       switch (sa.sa_family) {
-       case AF_INET:
-               {
-                       if (ZEND_NUM_ARGS() != 7) {
-                               efree(ctl_buf);
-                               WRONG_PARAM_COUNT;
-                       }
-                       bzero(&sa, sizeof(sa));
-                       hdr.msg_name = sin;
-                       hdr.msg_namelen = sizeof(sa);
-                       hdr.msg_iov = iov->iov_array;
-                       hdr.msg_iovlen = iov->count;
-
-                       if (ctl_buf) {
-                               hdr.msg_control = ctl_buf;
-                               hdr.msg_controllen = ZVAL(controllen, lval);
-                       } else {
-                               hdr.msg_control = NULL;
-                               hdr.msg_controllen = 0;
-                       }
+       switch (sa.sa_family)
+       {
+               case AF_INET:
+                       {
+                               if (ZEND_NUM_ARGS() != 7) {
+                                       efree(ctl_buf);
+                                       WRONG_PARAM_COUNT;
+                               }
+                               bzero(&sa, sizeof(sa));
+                               hdr.msg_name = sin;
+                               hdr.msg_namelen = sizeof(sa);
+                               hdr.msg_iov = iov->iov_array;
+                               hdr.msg_iovlen = iov->count;
 
-                       hdr.msg_flags = 0;
+                               if (ctl_buf) {
+                                       hdr.msg_control = ctl_buf;
+                                       hdr.msg_controllen = Z_LVAL_PP(controllen);
+                               } else {
+                                       hdr.msg_control = NULL;
+                                       hdr.msg_controllen = 0;
+                               }
 
-                       ret = recvmsg(ZVAL(fd, lval), &hdr, ZVAL(flags, lval));
-                       if (ret < 0) {
-                               RETURN_LONG(-errno);
-                       } else {
-                               struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;
+                               hdr.msg_flags = 0;
+       
+                               ret = recvmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
+                               if (ret < 0) {
+                                       RETURN_LONG(-errno);
+                               } else {
+                                       struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;
 
-                               /* copy values as appropriate... */
-                               array_init(control_array);
-                               add_assoc_long(control_array, "cmsg_level", mhdr->cmsg_level);
-                               add_assoc_long(control_array, "cmsg_type", mhdr->cmsg_type);
-                               add_assoc_string(control_array, "cmsg_data", CMSG_DATA(mhdr), 1);
-                               *control = control_array;
-                               ZVAL(controllen, lval) = hdr.msg_controllen;
-                               ZVAL(flags, lval) = hdr.msg_flags;
-                               if (ZVAL(addr, str.val) != NULL) {
-                                       efree(ZVAL(addr, str.val));
-                               } {
-                                       char *tmp = inet_ntoa(sin->sin_addr);
-
-                                       if (tmp == NULL) {
-                                               ZVAL(addr, str.val) = estrdup("0.0.0.0");
-                                       } else {
-                                               ZVAL(addr, str.val) = estrdup(tmp);
+                                       /* copy values as appropriate... */
+                                       if (array_init(control_array) == FAILURE) {
+                                               php_error(E_WARNING, "Cannot intialize array");
+                                               RETURN_FALSE;
+                                       }
+                                       add_assoc_long(control_array, "cmsg_level", mhdr->cmsg_level);
+                                       add_assoc_long(control_array, "cmsg_type", mhdr->cmsg_type);
+                                       add_assoc_string(control_array, "cmsg_data", CMSG_DATA(mhdr), 1);
+                                       *control = control_array;
+                                       zval_copy_ctor(*control);
+                                       
+                                       Z_LVAL_PP(controllen) = hdr.msg_controllen;
+                                       Z_LVAL_PP(flags)      = hdr.msg_flags;
+                                       if (Z_STRVAL_PP(addr) != NULL) {
+                                               efree(Z_STRVAL_PP(addr));
+                                       } 
+                                       {
+                                               char *tmp = inet_ntoa(sin->sin_addr);
+       
+                                               if (tmp == NULL) {
+                                                       Z_STRVAL_PP(addr) = estrdup("0.0.0.0");
+                                               } else {
+                                                       Z_STRVAL_PP(addr) = estrdup(tmp);
+                                               }
                                        }
+                                       Z_STRLEN_PP(addr) = strlen(Z_STRVAL_PP(addr));
+                                       Z_LVAL_PP(port)   = ntohs(sin->sin_port);
+                                       RETURN_LONG(ret);
                                }
-                               ZVAL(addr, str.len) = strlen(ZVAL(addr, str.val));
-                               ZVAL(port, lval) = ntohs(sin->sin_port);
-                               RETURN_LONG(ret);
                        }
-               }
-               break;
+                       break;
        case AF_UNIX:
                {
                        if (ZEND_NUM_ARGS() != 6) {
@@ -1643,7 +1586,7 @@ PHP_FUNCTION(recvmsg)
 
                        if (ctl_buf) {
                                hdr.msg_control = ctl_buf;
-                               hdr.msg_controllen = ZVAL(controllen, lval);
+                               hdr.msg_controllen = Z_LVAL_PP(controllen);
                        } else {
                                hdr.msg_control = NULL;
                                hdr.msg_controllen = 0;
@@ -1651,24 +1594,27 @@ PHP_FUNCTION(recvmsg)
 
                        hdr.msg_flags = 0;
 
-                       ret = recvmsg(ZVAL(fd, lval), &hdr, ZVAL(flags, lval));
+                       ret = recvmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
                        if (ret < 0) {
                                RETURN_LONG(-errno);
                        } else {
                                struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;
 
                                /* copy values as appropriate... */
-                               array_init(control_array);
+                               if (array_init(control_array) == FAILURE) {
+                                       php_error(E_WARNING, "Cannot initialize return value from recvmsg()");
+                                       RETURN_FALSE;
+                               }
                                add_assoc_long(control_array, "cmsg_level", mhdr->cmsg_level);
                                add_assoc_long(control_array, "cmsg_type", mhdr->cmsg_type);
                                add_assoc_string(control_array, "cmsg_data", CMSG_DATA(mhdr), 1);
                                *control = control_array;
-                               ZVAL(controllen, lval) = hdr.msg_controllen;
-                               ZVAL(flags, lval) = hdr.msg_flags;
-                               if (ZVAL(addr, str.val) != NULL) {
-                                       efree(ZVAL(addr, str.val));
+                               Z_LVAL_PP(controllen) = hdr.msg_controllen;
+                               Z_LVAL_PP(flags)      = hdr.msg_flags;
+                               if (Z_STRVAL_PP(addr) != NULL) {
+                                       efree(Z_STRVAL_PP(addr));
                                }
-                               ZVAL(addr, str.val) = estrdup(sun->sun_path);
+                               Z_STRVAL_PP(addr) = estrdup(sun->sun_path);
                                RETURN_LONG(ret);
                        }
                }
@@ -1679,34 +1625,29 @@ PHP_FUNCTION(recvmsg)
 }
 /* }}} */
 
-/* {{{ proto long sendmsg(long fd, resource iovec, long flags, string addr [, long port])
+/* {{{ proto int sendmsg(int fd, resource iovec, int flags, string addr [, int port])
    Sends a message to a socket, regardless of whether it is connection-oriented or not */
 PHP_FUNCTION(sendmsg)
 {
        zval **fd, **iovec, **flags, **addr, **port;
        php_iovec_t *iov;
-       int ret;
+       int ret, argc = ZEND_NUM_ARGS();
        struct sockaddr sa;
        int salen;
+       SOCKETSLS_FETCH();
 
-       if (ZEND_NUM_ARGS() == 4) {
-               ret = zend_get_parameters_ex(4, &fd, &iovec, &flags, &addr);
-       } else if (ZEND_NUM_ARGS() == 5) {
-               ret = zend_get_parameters_ex(5, &fd, &iovec, &flags, &addr, &port);
-       }
-
-       if (ret == FAILURE) {
+       if (argc < 4 || argc > 5 ||
+           zend_get_parameters_ex(argc, &fd, &iovec, &flags, &addr, &port) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
        salen = sizeof(sa);
-       ret = getsockname(ZVAL(fd, lval), &sa, &salen);
+       ret = getsockname(Z_LVAL_PP(fd), &sa, &salen);
        if (ret < 0) {
                RETURN_LONG(-errno);
        }
 
-       (*iovec)->type = IS_RESOURCE;
-       ZEND_FETCH_RESOURCE(iov, php_iovec_t *, iovec, -1, "IO vector table", le_iov);
+       ZEND_FETCH_RESOURCE(iov, php_iovec_t *, iovec, -1, "IO vector table", SOCKETSG(le_iov));
 
        switch(sa.sa_family)
        {
@@ -1722,21 +1663,18 @@ PHP_FUNCTION(sendmsg)
                                hdr.msg_iov = iov->iov_array;
                                hdr.msg_iovlen = iov->count;
                                
-                               if (inet_aton(ZVAL(addr, str.val), &sin->sin_addr) != 0) {
-                                       struct hostent *he = gethostbyname(ZVAL(addr, str.val));
+                               if (inet_aton(Z_STRVAL_PP(addr), &sin->sin_addr) != 0) {
+                                       struct hostent *he = gethostbyname(Z_STRVAL_PP(addr));
                                        if (!he) {
                                                RETURN_LONG(h_errno > 0 ? -(h_errno) - 10000 : -errno)
                                        }
                                        sin->sin_addr.s_addr = *(int *)(he->h_addr_list[0]);
                                }
 
-                               sin->sin_port = htons(ZVAL(port, lval));
-                               ret = sendmsg(ZVAL(fd, lval), &hdr, ZVAL(flags, lval));
-                               if (ret < 0) {
-                                       RETURN_LONG(-errno);
-                               } else {
-                                       RETURN_LONG(ret);
-                               }
+                               sin->sin_port = htons(Z_LVAL_PP(port));
+                               ret = sendmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
+                               
+                               RETURN_LONG(((ret < 0) ? -errno : ret));
                        }
                        break;
                case AF_UNIX:
@@ -1748,16 +1686,13 @@ PHP_FUNCTION(sendmsg)
                                hdr.msg_iov = iov->iov_array;
                                hdr.msg_iovlen = iov->count;
 
-                               snprintf(sun->sun_path, 108, "%s", ZVAL(addr, str.val));
+                               snprintf(sun->sun_path, 108, "%s", Z_STRVAL_PP(addr));
 
                                hdr.msg_namelen = SUN_LEN(sun);
 
-                               ret = sendmsg(ZVAL(fd, lval), &hdr, ZVAL(flags, lval));
-                               if (ret < 0) {
-                                       RETURN_LONG(-errno);
-                               } else {
-                                       RETURN_LONG(ret);
-                               }
+                               ret = sendmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
+                               
+                               RETURN_LONG(((ret < 0) ? -errno : ret));
                        }
                        break;
                default:
@@ -1766,7 +1701,7 @@ PHP_FUNCTION(sendmsg)
 }
 /* }}} */
 
-/* {{{ proto long getsockopt(long fd, long level, long optname, array|long &optval)
+/* {{{ proto int getsockopt(int fd, int level, int optname, array|int &optval)
    Gets socket options for the socket */
 /* If optname is SO_LINGER, optval is returned as an array with members 
    "l_onoff" and "l_linger", otherwise it is an integer.
@@ -1781,23 +1716,27 @@ PHP_FUNCTION(getsockopt)
 
        fd = level = optname = optval = NULL;
 
-       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &fd, &level, &optname, &optval) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 4 || 
+           zend_get_parameters_ex(4, &fd, &level, &optname, &optval) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
        v_convert_to_long_ex(3, fd, level, optname);
        /* optname is set on the way out .. */
 
-       if (ZVAL(level, lval) == SO_LINGER) {
+       if (Z_LVAL_PP(level) == SO_LINGER) {
                zval *optval_array = NULL;
                optlen = sizeof(struct linger);
-               ret = getsockopt(ZVAL(fd, lval), ZVAL(level, lval), ZVAL(optname, lval), &linger_val, &optlen);
+               ret = getsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &linger_val, &optlen);
 
                if (ret < 0) {
                        RETURN_LONG(-errno);
                }
 
-               array_init(optval_array);
+               if (array_init(optval_array) == FAILURE) {
+                       php_error(E_WARNING, "Cannot initialize array from getsockopt()");
+                       RETURN_FALSE;
+               }
                add_assoc_long(optval_array, "l_onoff", linger_val.l_onoff);
                add_assoc_long(optval_array, "l_linger", linger_val.l_linger);
 
@@ -1805,18 +1744,18 @@ PHP_FUNCTION(getsockopt)
                RETURN_LONG(ret);
        } else {
                optlen = sizeof(other_val);
-               ret = getsockopt(ZVAL(fd, lval), ZVAL(level, lval), ZVAL(optname, lval), &other_val, &optlen);
+               ret = getsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &other_val, &optlen);
                if (ret < 0) {
                        RETURN_LONG(-errno);
                }
 
-               ZVAL_LONG(*optval, other_val);
+               Z_LVAL_PP(optval) = other_val;
                RETURN_LONG(ret);
        }
 }
 /* }}} */
 
-/* {{{ proto long setsockopt(long fd, long level, long optname, long|array optval)
+/* {{{ proto int setsockopt(int fd, int level, int optname, int|array optval)
    Sets socket options for the socket */
 /* If optname is SO_LINGER, optval is expected to be an array
    with members "l_onoff" and "l_linger", otherwise it should be an integer. */
@@ -1830,13 +1769,14 @@ PHP_FUNCTION(setsockopt)
 
        errno = 0;
 
-       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &fd, &level, &optname, &optval) == FAILURE) {
+       if (ZEND_NUM_ARGS() != 4 || 
+           zend_get_parameters_ex(4, &fd, &level, &optname, &optval) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
        v_convert_to_long_ex(3, fd, level, optname);
 
-       if (ZVAL(optname, lval) == SO_LINGER) {
+       if (Z_LVAL_PP(optname) == SO_LINGER) {
                HashTable *ht;
                zval **l_onoff;
                zval **l_linger;
@@ -1844,39 +1784,105 @@ PHP_FUNCTION(setsockopt)
                convert_to_array_ex(optval);
                ht = HASH_OF(*optval);
 
-               if (zend_hash_find(ht, "l_onoff", strlen("l_onoff") + 1, (void **) &l_onoff) == FAILURE) {
-                       zend_error(E_ERROR, "No key \"l_onoff\" passed in optval");
-                       return;
+               if (zend_hash_find(ht, "l_onoff", strlen("l_onoff") + 1, (void **)&l_onoff) == FAILURE) {
+                       php_error(E_WARNING, "No key \"l_onoff\" passed in optval");
+                       RETURN_FALSE;
                }
                if (zend_hash_find(ht, "l_linger", strlen("l_linger") + 1, (void **) &l_linger) == FAILURE) {
-                       zend_error(E_ERROR, "No key \"l_linger\" passed in optval");
-                       return;
+                       php_error(E_WARNING, "No key \"l_linger\" passed in optval");
+                       RETURN_FALSE;
                }
 
                convert_to_long_ex(l_onoff);
                convert_to_long_ex(l_linger);
 
-               lv.l_onoff = ZVAL(l_onoff, lval);
-               lv.l_linger = ZVAL(l_linger, lval);
+               lv.l_onoff = Z_LVAL_PP(l_onoff);
+               lv.l_linger = Z_LVAL_PP(l_linger);
 
                optlen = sizeof(lv);
-               ret = setsockopt(ZVAL(fd, lval), ZVAL(level, lval), ZVAL(optname, lval), &lv, optlen);
+               ret = setsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &lv, optlen);
        } else {
                convert_to_long_ex(optval);
 
                optlen = sizeof(ov);
-               ov = ZVAL(optval, lval);
+               ov = Z_LVAL_PP(optval);
 
-               ret = setsockopt(ZVAL(fd, lval), ZVAL(level, lval), ZVAL(optname, lval), &ov, optlen);
+               ret = setsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &ov, optlen);
        }
 
-       printf("returning: ret = %i, errno = %i\n", ret, errno);
-       if (ret < 0) {
-               RETURN_LONG(-errno);
-       } else {
-               RETURN_LONG(ret);
+       RETURN_LONG(((ret < 0) ? -errno : ret));
+}
+
+PHP_FUNCTION(socketpair)
+{
+       zval **domain, **type, **protocol, **fds, **fd;
+       int ret, fds_ar[2];
+       HashTable *fd_ar;
+       
+       if (ZEND_NUM_ARGS() != 4 ||
+           zend_get_parameters_ex(4, &domain, &type, &protocol, &fds) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       v_convert_to_long_ex(3, domain, type, protocol);
+
+       if (Z_LVAL_PP(domain) != AF_INET && Z_LVAL_PP(domain) != AF_UNIX) {
+               php_error(E_WARNING, "invalid socket domain specified -- assuming AF_INET");
+               Z_LVAL_PP(domain) = AF_INET;
+       }
+       
+       if (Z_LVAL_PP(type) > 10) {
+               php_error(E_WARNING, "Invalid socket type specified - assuming SOCK_STREAM");
+               Z_LVAL_PP(type) = SOCK_STREAM;
+       }
+       
+       fd_ar = HASH_OF(*fds);
+       zend_hash_internal_pointer_reset(fd_ar);
+       
+       if (zend_hash_get_current_data(fd_ar, (void **)&fd) == FAILURE) {
+               php_error(E_WARNING, "Can't access data from fds array");
+               RETURN_FALSE;
        }
+       SEPARATE_ZVAL(fd);
+       
+       convert_to_long_ex(fd);
+       fds_ar[0] = Z_LVAL_PP(fd);
+       
+       zend_hash_move_forward(fd_ar);
+       if (zend_hash_get_current_data(fd_ar, (void **)&fd) == FAILURE) {
+               php_error(E_WARNING, "Can't access data from fds array");
+               RETURN_FALSE;
+       }
+       SEPARATE_ZVAL(fd);
+       
+       convert_to_long_ex(fd);
+       fds_ar[1] = Z_LVAL_PP(fd);      
+       
+       ret = socketpair(Z_LVAL_PP(domain), Z_LVAL_PP(type), Z_LVAL_PP(protocol), fds_ar);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
 }
+
+PHP_FUNCTION(shutdown)
+{
+       zval **fd, **how;
+       int how_shutdown = 0, argc = ZEND_NUM_ARGS(), ret;
+       
+       if (argc < 1 || argc > 2 ||
+           zend_get_parameters_ex(argc, &fd, &how) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long_ex(fd);
+       
+       if (argc > 1) {
+               convert_to_long_ex(how);
+               how_shutdown = Z_LVAL_PP(how);
+       }
+       
+       ret = shutdown(Z_LVAL_PP(fd), how_shutdown);
+       
+       RETURN_LONG(((ret < 0) ? -errno : ret));
+}
+
 /* }}} */
 
 #endif                         /* HAVE_SOCKETS */