summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/sockets/CREDITS2
-rw-r--r--ext/sockets/php_sockets.h95
-rw-r--r--ext/sockets/php_sockets_win.c175
-rw-r--r--ext/sockets/php_sockets_win.h83
-rw-r--r--ext/sockets/sockets.c2264
-rw-r--r--ext/sockets/sockets.dsp116
6 files changed, 1499 insertions, 1236 deletions
diff --git a/ext/sockets/CREDITS b/ext/sockets/CREDITS
index 674a9cebad..cd36000982 100644
--- a/ext/sockets/CREDITS
+++ b/ext/sockets/CREDITS
@@ -1,2 +1,2 @@
Sockets
-Chris Vandomelen, Sterling Hughes
+Chris Vandomelen, Sterling Hughes, Daniel Beulshausen
diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h
index 66055b8ee0..422451793d 100644
--- a/ext/sockets/php_sockets.h
+++ b/ext/sockets/php_sockets.h
@@ -13,6 +13,9 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Chris Vandomelen <chrisv@b0rked.dhs.org> |
+ | Sterling Hughes <sterling@php.net> |
+ | |
+ | WinSock: Daniel Beulshausen <daniel@php4win.de> |
+----------------------------------------------------------------------+
*/
@@ -35,44 +38,44 @@ extern zend_module_entry sockets_module_entry;
PHP_MINIT_FUNCTION(sockets);
PHP_MINFO_FUNCTION(sockets);
-PHP_FUNCTION(fd_alloc);
-PHP_FUNCTION(fd_dealloc);
-PHP_FUNCTION(fd_set);
-PHP_FUNCTION(fd_isset);
-PHP_FUNCTION(fd_clear);
-PHP_FUNCTION(fd_zero);
-PHP_FUNCTION(select);
-PHP_FUNCTION(open_listen_sock);
-PHP_FUNCTION(accept_connect);
-PHP_FUNCTION(set_nonblock);
-PHP_FUNCTION(listen);
-PHP_FUNCTION(close);
-PHP_FUNCTION(write);
-PHP_FUNCTION(read);
-PHP_FUNCTION(getsockname);
-PHP_FUNCTION(getpeername);
-PHP_FUNCTION(socket);
-PHP_FUNCTION(connect);
-PHP_FUNCTION(strerror);
-PHP_FUNCTION(bind);
-PHP_FUNCTION(recv);
-PHP_FUNCTION(send);
-PHP_FUNCTION(recvfrom);
-PHP_FUNCTION(sendto);
-PHP_FUNCTION(build_iovec);
-PHP_FUNCTION(fetch_iovec);
-PHP_FUNCTION(free_iovec);
-PHP_FUNCTION(add_iovec);
-PHP_FUNCTION(delete_iovec);
-PHP_FUNCTION(set_iovec);
-PHP_FUNCTION(recvmsg);
-PHP_FUNCTION(sendmsg);
-PHP_FUNCTION(readv);
-PHP_FUNCTION(writev);
-PHP_FUNCTION(getsockopt);
-PHP_FUNCTION(setsockopt);
-PHP_FUNCTION(socketpair);
-PHP_FUNCTION(shutdown);
+PHP_FUNCTION(socket_fd_alloc);
+PHP_FUNCTION(socket_fd_free);
+PHP_FUNCTION(socket_fd_set);
+PHP_FUNCTION(socket_fd_isset);
+PHP_FUNCTION(socket_fd_clear);
+PHP_FUNCTION(socket_fd_zero);
+PHP_FUNCTION(socket_iovec_alloc);
+PHP_FUNCTION(socket_iovec_free);
+PHP_FUNCTION(socket_iovec_set);
+PHP_FUNCTION(socket_iovec_fetch);
+PHP_FUNCTION(socket_iovec_add);
+PHP_FUNCTION(socket_iovec_delete);
+PHP_FUNCTION(socket_select);
+PHP_FUNCTION(socket_create_listen);
+PHP_FUNCTION(socket_create_pair);
+PHP_FUNCTION(socket_accept);
+PHP_FUNCTION(socket_set_nonblock);
+PHP_FUNCTION(socket_listen);
+PHP_FUNCTION(socket_close);
+PHP_FUNCTION(socket_write);
+PHP_FUNCTION(socket_read);
+PHP_FUNCTION(socket_getsockname);
+PHP_FUNCTION(socket_getpeername);
+PHP_FUNCTION(socket_create);
+PHP_FUNCTION(socket_connect);
+PHP_FUNCTION(socket_strerror);
+PHP_FUNCTION(socket_bind);
+PHP_FUNCTION(socket_recv);
+PHP_FUNCTION(socket_send);
+PHP_FUNCTION(socket_recvfrom);
+PHP_FUNCTION(socket_sendto);
+PHP_FUNCTION(socket_recvmsg);
+PHP_FUNCTION(socket_sendmsg);
+PHP_FUNCTION(socket_readv);
+PHP_FUNCTION(socket_writev);
+PHP_FUNCTION(socket_getopt);
+PHP_FUNCTION(socket_setopt);
+PHP_FUNCTION(socket_shutdown);
typedef struct php_iovec {
struct iovec *iov_array;
@@ -80,6 +83,15 @@ typedef struct php_iovec {
} php_iovec_t;
typedef struct {
+#ifdef PHP_WIN32
+ SOCKET socket;
+#else
+ int socket;
+#endif
+ int type;
+} php_socket;
+
+typedef struct {
zend_bool use_system_read;
} php_sockets_globals;
@@ -93,17 +105,14 @@ typedef struct {
#endif
#else
-
#define phpext_sockets_ptr NULL
-
#endif
-#endif /* PHP_SOCKETS_H */
-
+#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
- */
+ */ \ No newline at end of file
diff --git a/ext/sockets/php_sockets_win.c b/ext/sockets/php_sockets_win.c
new file mode 100644
index 0000000000..5956781310
--- /dev/null
+++ b/ext/sockets/php_sockets_win.c
@@ -0,0 +1,175 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | 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> |
+ | Sterling Hughes <sterling@php.net> |
+ | |
+ | WinSock: Daniel Beulshausen <daniel@php4win.de> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifdef PHP_WIN32
+
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "php.h"
+#include "php_sockets.h"
+#include "php_sockets_win.h"
+
+ssize_t readv(SOCKET sock, const struct iovec *iov, int iovcnt) {
+ size_t bytes, remain, len, pos = 0;
+ ssize_t retval;
+ int i;
+ char *buffer = NULL;
+
+ for(bytes=0, i=0; i<iovcnt; i++) {
+ bytes += iov[i].iov_len;
+ }
+
+ buffer = (char*)emalloc(bytes);
+ if (buffer == NULL) {
+ return -1;
+ }
+
+ retval = recv(sock, buffer, bytes, 0);
+ if(retval < 0) {
+ efree(buffer);
+ return retval;
+ }
+
+ remain = bytes = (size_t) retval;
+
+ for(i=0; i<iovcnt; i++) {
+ len = (iov[i].iov_len < remain) ? iov[i].iov_len : remain;
+ memcpy(iov[i].iov_base, buffer+pos, len);
+ pos += len;
+ remain -= len;
+ }
+
+ efree(buffer);
+ return bytes;
+}
+
+ssize_t writev(SOCKET sock, const struct iovec *iov, int iovcnt) {
+ size_t bytes, pos = 0;
+ ssize_t retval;
+ int i;
+ char *buffer = NULL;
+
+ for(bytes=0, i=0; i<iovcnt; i++) {
+ bytes += iov[i].iov_len;
+ }
+
+ buffer = (char*)emalloc(bytes);
+
+ if(buffer == NULL) {
+ return -1;
+ }
+
+ for(i=0; i<iovcnt; i++) {
+ memcpy(buffer+pos, iov[i].iov_base, iov[i].iov_len);
+ pos += iov[i].iov_len;
+ }
+
+ retval = send(sock, buffer, bytes, 0);
+ efree(buffer);
+
+ return retval;
+}
+
+ssize_t recvmsg(SOCKET sock, struct msghdr *msg, int flags) {
+ set_errno(WSAEOPNOTSUPP);
+ return -1;
+}
+
+ssize_t sendmsg(SOCKET sock, struct msghdr *msg, int flags) {
+ set_errno(WSAEOPNOTSUPP);
+ return -1;
+}
+
+int socketpair(int domain, int type, int protocol, SOCKET sock[2]) {
+ struct sockaddr_in address;
+ SOCKET redirect;
+ int size = sizeof(address);
+
+ if(domain != AF_INET) {
+ set_errno(WSAENOPROTOOPT);
+ return -1;
+ }
+
+
+ sock[0] = socket(domain, type, protocol);
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_family = AF_INET;
+ address.sin_port = 0;
+
+ bind(sock[0], (struct sockaddr*)&address, sizeof(address));
+ if(getsockname(sock[0], (struct sockaddr *)&address, &size) != 0) {
+
+ }
+
+ listen(sock[0], 2);
+ sock[1] = socket(domain, type, protocol);
+ address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ connect(sock[1], (struct sockaddr*)&address, sizeof(address));
+ redirect = accept(sock[0],(struct sockaddr*)&address, &size);
+
+ close(sock[0]);
+ sock[0] = redirect;
+
+ if(sock[0] == INVALID_SOCKET ) {
+ close(sock[0]);
+ close(sock[1]);
+ set_errno(WSAECONNABORTED);
+ return -1;
+ }
+
+ return 0;
+}
+
+int inet_aton(const char *cp, struct in_addr *inp) {
+ inp->s_addr = inet_addr(cp);
+
+ if (inp->s_addr == INADDR_NONE) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int fcntl(int fd, int cmd, ...) {
+ va_list va;
+ int retval;
+
+ va_start(va, cmd);
+
+ switch(cmd) {
+ case F_GETFL:
+ case F_SETFD:
+ case F_GETFD:
+ default:
+ retval = -1;
+ break;
+
+ case F_SETFL:
+ retval = ioctlsocket(fd, cmd, va_arg(va, int*));
+ break;
+ }
+
+ va_end(va);
+ return retval;
+}
+#endif \ No newline at end of file
diff --git a/ext/sockets/php_sockets_win.h b/ext/sockets/php_sockets_win.h
new file mode 100644
index 0000000000..cbb225b911
--- /dev/null
+++ b/ext/sockets/php_sockets_win.h
@@ -0,0 +1,83 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | 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> |
+ | Sterling Hughes <sterling@php.net> |
+ | |
+ | WinSock: Daniel Beulshausen <daniel@php4win.de> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifdef PHP_WIN32
+
+#define F_SETFL 0
+#define F_GETFL 1
+#define F_SETFD 2
+#define F_GETFD 3
+
+#define O_NONBLOCK FIONBIO
+
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ECONNRESET WSAECONNRESET
+
+#ifdef errno
+#undef errno
+#endif
+
+#define errno WSAGetLastError()
+#define h_errno WSAGetLastError()
+#define set_errno(a) WSASetLastError(a)
+#define set_h_errno(a) WSASetLastError(a)
+#define close(a) closesocket(a)
+#define CMSG_DATA(cmsg) ((cmsg)->cmsg_data)
+#define IS_INVALID_SOCKET(a) (a->socket == INVALID_SOCKET)
+
+typedef long ssize_t;
+
+struct sockaddr_un {
+ short sun_family;
+ char sun_path[108];
+};
+
+struct iovec {
+ char * iov_base;
+ int iov_len;
+};
+
+struct msghdr {
+ void* msg_name;
+ socklen_t msg_namelen;
+ struct iovec* msg_iov;
+ int msg_iovlen;
+ void* msg_control;
+ socklen_t msg_controllen;
+ int msg_flags;
+};
+
+struct cmsghdr {
+ socklen_t cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+ unsigned char cmsg_data[];
+};
+
+ssize_t readv(SOCKET sock, const struct iovec *iov, int iovcnt);
+ssize_t writev(SOCKET sock, const struct iovec *iov, int iovcnt);
+ssize_t recvmsg(SOCKET sock, struct msghdr *msg, int flags);
+ssize_t sendmsg(SOCKET sock, struct msghdr *msg, int flags);
+int socketpair(int domain, int type, int protocol, SOCKET sock[2]);
+int inet_aton(const char *cp, struct in_addr *inp);
+int fcntl(int fd, int cmd, ...);
+
+#endif
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index 67666e523e..6de3e454e2 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -13,7 +13,9 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Chris Vandomelen <chrisv@b0rked.dhs.org> |
- | Sterling Hughes <sterling@php.net> |
+ | Sterling Hughes <sterling@php.net> |
+ | |
+ | WinSock: Daniel Beulshausen <daniel@php4win.de> |
+----------------------------------------------------------------------+
*/
@@ -21,16 +23,8 @@
#include "php.h"
-
#if HAVE_SOCKETS
-/* This hopefully will fix some compile errors on other platforms --
- * the usage of msg_control/msg_controllen are X/Open Extended attributes,
- * or so it seems, by reading HP/UX 10.20 manual pages.
- *
- * The second two defines are for Solaris 8 with the Sun WorkShop compiler.
- */
-
#define _XOPEN_SOURCE_EXTENDED
#define _XPG4_2
#define __EXTENSIONS__
@@ -40,22 +34,31 @@
#endif
#include "ext/standard/info.h"
-#include "php_sockets.h"
#include "php_ini.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/un.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/uio.h>
+#ifndef PHP_WIN32
+# include "php_sockets.h"
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <sys/un.h>
+# include <arpa/inet.h>
+# include <sys/time.h>
+# include <unistd.h>
+# include <errno.h>
+# include <fcntl.h>
+# include <signal.h>
+# include <sys/uio.h>
+# define IS_INVALID_SOCKET(a) (a->socket < 0)
+# define set_errno(a) (errno = a)
+# define set_h_errno(a) (h_errno = a)
+#else /* windows */
+# include <winsock.h>
+# include "php_sockets.h"
+# include "php_sockets_win.h"
+#endif
#ifdef ZTS
int sockets_globals_id;
@@ -63,38 +66,29 @@ int sockets_globals_id;
php_sockets_globals sockets_globals;
#endif
-/* It seems some platforms don't have this... */
#ifndef MSG_WAITALL
#ifdef LINUX
-/* Well, it's defined on linux to this, and on a few
- * distributions, it doesn't get included... */
#define MSG_WAITALL 0x00000100
#else
#define MSG_WAITALL 0x00000000
#endif
#endif
-/* Solaris 8 doesn't appear to define SUN_LEN in <sys/un.h> */
#ifndef SUN_LEN
-#define SUN_LEN(su) \
- (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
-/* Use the read() wrapper, stopping at '\n', '\r', or '\0'. */
#define PHP_NORMAL_READ 0x0001
-/* Use the read() wrapper, but read until the entire buffer is filled. */
#define PHP_BINARY_READ 0x0002
-/* Use the system read() function. */
#define PHP_SYSTEM_READ 0x0004
typedef struct {
- unsigned char info[128];
+ unsigned char info[256];
} php_sockaddr_storage;
-static int le_iov;
-static int le_destroy;
+static int le_iov, le_destroy, le_socket;
static unsigned char second_and_third_args_force_ref[] =
{3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
@@ -102,69 +96,53 @@ static unsigned char second_and_third_args_force_ref[] =
static unsigned char second_fifth_and_sixth_args_force_ref[] =
{6, BYREF_NONE, BYREF_FORCE, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};
-static unsigned char fourth_arg_force_ref[] =
-{4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE};
-
static unsigned char third_through_seventh_args_force_ref[] =
{7, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE};
+
function_entry sockets_functions[] = {
- PHP_FE(fd_alloc, NULL) /* OK */
- PHP_FE(fd_dealloc, NULL) /* OK */
- PHP_FE(fd_set, NULL) /* OK */
- PHP_FE(fd_isset, NULL) /* OK */
- PHP_FE(fd_clear, NULL) /* OK */
- PHP_FE(fd_zero, NULL) /* OK */
- PHP_FE(select, 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 */
- PHP_FE(close, NULL) /* OK */
- 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.
- */
- PHP_FE(signal, NULL)
-#endif
-/*
- * These are defined elsewhere..
- * would these be more appropriate?
- */
-#if 0
- PHP_FE(gethostbyname, second_arg_force_ref) /* OK */
- PHP_FE(gethostbyaddr, second_arg_force_ref) /* OK */
-#endif
- PHP_FE(getsockname, second_and_third_args_force_ref) /* OK */
- PHP_FE(getpeername, second_and_third_args_force_ref) /* OK */
- PHP_FE(socket, NULL) /* OK */
- PHP_FE(connect, NULL) /* OK */
- PHP_FE(strerror, NULL) /* OK */
- PHP_FE(bind, NULL)
- PHP_FE(recv, second_arg_force_ref)
- PHP_FE(send, NULL)
- PHP_FE(recvfrom, second_fifth_and_sixth_args_force_ref)
- PHP_FE(sendto, NULL)
- PHP_FE(build_iovec, NULL)
- PHP_FE(fetch_iovec, NULL)
- PHP_FE(free_iovec, NULL)
- PHP_FE(add_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)
- PHP_FE(readv, NULL)
- PHP_FE(writev, NULL)
- PHP_FE(getsockopt, fourth_arg_force_ref)
- PHP_FE(setsockopt, NULL)
- PHP_FE(socketpair, NULL)
- PHP_FE(shutdown, NULL)
+ PHP_FE(socket_fd_alloc, NULL)
+ PHP_FE(socket_fd_free, NULL)
+ PHP_FE(socket_fd_set, NULL)
+ PHP_FE(socket_fd_isset, NULL)
+ PHP_FE(socket_fd_clear, NULL)
+ PHP_FE(socket_fd_zero, NULL)
+ PHP_FE(socket_iovec_alloc, NULL)
+ PHP_FE(socket_iovec_free, NULL)
+ PHP_FE(socket_iovec_set, NULL)
+ PHP_FE(socket_iovec_fetch, NULL)
+ PHP_FE(socket_iovec_add, NULL)
+ PHP_FE(socket_iovec_delete, NULL)
+ PHP_FE(socket_select, NULL)
+ PHP_FE(socket_create, NULL)
+ PHP_FE(socket_create_listen, NULL)
+ PHP_FE(socket_create_pair, NULL)
+ PHP_FE(socket_accept, NULL)
+ PHP_FE(socket_set_nonblock, NULL)
+ PHP_FE(socket_listen, NULL)
+ PHP_FE(socket_close, NULL)
+ PHP_FE(socket_write, NULL)
+ PHP_FE(socket_read, NULL)
+ PHP_FE(socket_getsockname, second_and_third_args_force_ref)
+ PHP_FE(socket_getpeername, second_and_third_args_force_ref)
+ PHP_FE(socket_connect, NULL)
+ PHP_FE(socket_strerror, NULL)
+ PHP_FE(socket_bind, NULL)
+ PHP_FE(socket_recv, NULL)
+ PHP_FE(socket_send, NULL)
+ PHP_FE(socket_recvfrom, second_fifth_and_sixth_args_force_ref)
+ PHP_FE(socket_sendto, NULL)
+ PHP_FE(socket_recvmsg, third_through_seventh_args_force_ref)
+ PHP_FE(socket_sendmsg, NULL)
+ PHP_FE(socket_readv, NULL)
+ PHP_FE(socket_writev, NULL)
+ PHP_FE(socket_getopt, NULL)
+ PHP_FE(socket_setopt, NULL)
+ PHP_FE(socket_shutdown, NULL)
{NULL, NULL, NULL}
};
+
zend_module_entry sockets_module_entry = {
"sockets",
sockets_functions,
@@ -176,20 +154,24 @@ zend_module_entry sockets_module_entry = {
STANDARD_MODULE_PROPERTIES
};
+
#ifdef COMPILE_DL_SOCKETS
ZEND_GET_MODULE(sockets)
#endif
+/* this should be mutex'ed */
+volatile int inet_ntoa_lock = 0;
+
static void destroy_fd_sets(zend_rsrc_list_entry *rsrc)
{
- fd_set *set = (fd_set *) rsrc->ptr;
+ fd_set *set = (fd_set*)rsrc->ptr;
efree(set);
}
static void destroy_iovec(zend_rsrc_list_entry *rsrc)
{
- int i;
- php_iovec_t *iov = (php_iovec_t *) rsrc->ptr;
+ unsigned int i;
+ php_iovec_t *iov = (php_iovec_t*)rsrc->ptr;
if (iov->count && iov->iov_array) {
for (i = 0; i < iov->count; i++) {
@@ -201,842 +183,722 @@ static void destroy_iovec(zend_rsrc_list_entry *rsrc)
}
}
+static void destroy_socket(zend_rsrc_list_entry *rsrc) {
+ php_socket *php_sock = (php_socket*)rsrc->ptr;
+
+ close(php_sock->socket);
+ efree(php_sock);
+}
+
+static php_socket *open_listen_sock(int port)
+{
+ struct sockaddr_in la;
+ struct hostent *hp;
+ php_socket *php_sock = (php_socket*)emalloc(sizeof(php_socket));
+
+#ifndef PHP_WIN32
+ if ((hp = gethostbyname("0.0.0.0")) == NULL) {
+#else
+ if ((hp = gethostbyname("localhost")) == NULL) {
+#endif
+ efree(php_sock);
+ return NULL;
+ }
+
+ memcpy((char *)&la.sin_addr, hp->h_addr, hp->h_length);
+ la.sin_family = hp->h_addrtype;
+ la.sin_port = htons((unsigned short)port);
+
+ php_sock->socket = socket(AF_INET, SOCK_STREAM, 0);
+ php_sock->type = AF_INET;
+ if (IS_INVALID_SOCKET(php_sock)) {
+ efree(php_sock);
+ return NULL;
+ }
+ if ((bind(php_sock->socket, (struct sockaddr *)&la, sizeof(la)) != 0)) {
+ efree(php_sock);
+ return NULL;
+ }
+ listen(php_sock->socket, 128);
+ return php_sock;
+}
+
+static php_socket *accept_connect(php_socket *php_sock, struct sockaddr *la)
+{
+ int m;
+ php_socket *retval = (php_socket*)emalloc(sizeof(php_socket));
+
+ m = sizeof(*la);
+
+ retval->socket = accept(php_sock->socket, la, &m);
+ if (IS_INVALID_SOCKET(retval)) {
+ efree(retval);
+ return NULL;
+ }
+ return retval;
+}
+
+/* php_read -- wrapper around read() so that it only reads to a \r or \n. */
+int php_read(php_socket *php_sock, void *buf, int maxlen)
+{
+ int m = 0, n = 0;
+ int no_read = 0;
+ int nonblock = 0;
+ char *t = (char*)buf;
+
+ m = fcntl(php_sock->socket, F_GETFL);
+
+ if (m < 0) {
+ return m;
+ }
+
+ nonblock = (m & O_NONBLOCK);
+ m = 0;
+
+ set_errno(0);
+
+ while (*t != '\n' && *t != '\r' && n < maxlen) {
+ if (m > 0) {
+ t++;
+ n++;
+ } else if (m == 0) {
+ no_read++;
+ if (nonblock && no_read >= 2) {
+ return n;
+ /* The first pass, m always is 0, so no_read becomes 1
+ * in the first pass. no_read becomes 2 in the second pass,
+ * and if this is nonblocking, we should return.. */
+ }
+
+ if (no_read > 200) {
+ set_errno(ECONNRESET);
+ return -1;
+ }
+ }
+
+ if (n < maxlen) {
+ m = read(php_sock->socket, (void *) t, 1);
+ }
+
+ if (errno != 0 && errno != ESPIPE && errno != EAGAIN) {
+ return -1;
+ }
+
+ set_errno(0);
+ }
+
+ if (n < maxlen) {
+ n++;
+ /* The only reasons it makes it to here is
+ * if '\n' or '\r' are encountered. So, increase
+ * the return by 1 to make up for the lack of the
+ * '\n' or '\r' in the count (since read() takes
+ * place at the end of the loop..) */
+ }
+
+ return n;
+}
+
+
PHP_MINIT_FUNCTION(sockets)
{
- le_destroy = zend_register_list_destructors_ex(destroy_fd_sets, NULL, "sockets file descriptor set", module_number);
- le_iov = zend_register_list_destructors_ex(destroy_iovec, NULL, "sockets i/o vector", module_number);
-
- 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;
+
+ le_socket = zend_register_list_destructors_ex(destroy_socket, NULL, "Socket", module_number);
+ le_destroy = zend_register_list_destructors_ex(destroy_fd_sets,NULL, "Socket file descriptor set", module_number);
+ le_iov = zend_register_list_destructors_ex(destroy_iovec, NULL, "Socket I/O vector", module_number);
+
+ 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);
REGISTER_LONG_CONSTANT("PHP_NORMAL_READ", PHP_NORMAL_READ, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_BINARY_READ", PHP_BINARY_READ, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_SYSTEM_READ", PHP_SYSTEM_READ, CONST_CS | CONST_PERSISTENT);
- {
- struct protoent *pe;
- pe = getprotobyname("tcp");
- 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_CS | CONST_PERSISTENT);
- }
+ if ((pe = getprotobyname("tcp"))) {
+ REGISTER_LONG_CONSTANT("SOL_TCP", pe->p_proto, CONST_CS | CONST_PERSISTENT);
+ }
+
+ if ((pe = getprotobyname("udp"))) {
+ REGISTER_LONG_CONSTANT("SOL_UDP", pe->p_proto, CONST_CS | CONST_PERSISTENT);
}
return SUCCESS;
}
+
PHP_MINFO_FUNCTION(sockets)
{
php_info_print_table_start();
- php_info_print_table_row(2, "sockets support", "enabled");
+ php_info_print_table_row(2, "Sockets Support", "enabled");
php_info_print_table_end();
}
-/* {{{ proto resource fd_alloc(void)
- Allocates a file descriptor set */
-PHP_FUNCTION(fd_alloc)
+
+
+/* {{{ proto resource socket_fd_alloc(void)
+ Allocates a new file descriptor set */
+PHP_FUNCTION(socket_fd_alloc)
{
fd_set *set;
- set = (fd_set *) emalloc(sizeof(fd_set));
- if (!set) {
- php_error(E_WARNING, "Can't allocate memory for fd_set");
+ if ((set = (fd_set*)emalloc(sizeof(fd_set))) == NULL) {
+ php_error(E_WARNING, "cannot allocate file descriptor");
RETURN_FALSE;
}
-
+
+ FD_ZERO(set);
ZEND_REGISTER_RESOURCE(return_value, set, le_destroy);
}
/* }}} */
-/* {{{ proto bool fd_dealloc(int set)
- De-allocates a file descriptor set */
-PHP_FUNCTION(fd_dealloc)
+/* {{{ proto bool socket_fd_dealloc(resource set)
+ Deallocates a file descriptor set */
+PHP_FUNCTION(socket_fd_free)
{
- zval **set;
+ zval **arg1;
fd_set *the_set;
- if (ZEND_NUM_ARGS() != 1 ||
- zend_get_parameters_ex(1, &set) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
-
- zend_list_delete(Z_LVAL_PP(set));
+ ZEND_FETCH_RESOURCE(the_set, fd_set *, arg1, -1, "File descriptor set", le_destroy);
+ zend_list_delete(Z_RESVAL_PP(arg1));
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool fd_set(int fd, resource set)
+/* {{{ proto bool socket_fd_set(resource socket, resource set)
Adds a file descriptor to a set */
-PHP_FUNCTION(fd_set)
+PHP_FUNCTION(socket_fd_set)
{
- zval **set, **fd;
+ zval **arg1, **arg2;
fd_set *the_set;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
- ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
-
- if (Z_LVAL_PP(fd) < 0) {
- php_error(E_WARNING, "Can't set negative fd falues in a set");
- RETURN_FALSE;
- }
-
- FD_SET(Z_LVAL_PP(fd), the_set);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(the_set, fd_set*, arg2, -1, "File descriptor set", le_destroy);
+ FD_SET(php_sock->socket, the_set);
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool fd_clear(int fd, resource set)
+/* {{{ proto bool socket_fd_clear(resource socket, resource set)
Clears a file descriptor from a set */
-PHP_FUNCTION(fd_clear)
+PHP_FUNCTION(socket_fd_clear)
{
- zval **set, **fd;
+ zval **arg1, **arg2;
fd_set *the_set;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
- ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
-
- if (Z_LVAL_PP(fd) < 0) {
- php_error(E_WARNING, "Can't clear negative fd values in a set");
- RETURN_FALSE;
- }
-
- FD_CLR(Z_LVAL_PP(fd), the_set);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(the_set, fd_set *, arg2, -1, "File descriptor set", le_destroy);
+ FD_CLR(php_sock->socket, the_set);
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool fd_isset(int fd, resource set)
+/* {{{ proto bool socket_fd_isset(resource socket, resource set)
Checks to see if a file descriptor is set within the file descrirptor set */
-PHP_FUNCTION(fd_isset)
+PHP_FUNCTION(socket_fd_isset)
{
- zval **set, **fd;
+ zval **arg1, **arg2;
fd_set *the_set;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &fd, &set) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
- ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(the_set, fd_set *, arg2, -1, "File descriptor set", le_destroy);
- if (Z_LVAL_PP(fd) < 0) {
- php_error(E_WARNING, "Can't check for negative fd values in a set");
- RETURN_FALSE;
- }
-
- if (FD_ISSET(Z_LVAL_PP(fd), the_set)) {
+ if (FD_ISSET(php_sock->socket, the_set)) {
RETURN_TRUE;
}
-
RETURN_FALSE;
}
/* }}} */
-/* {{{ proto void fd_zero(resource set)
+/* {{{ proto bool socket_fd_zero(resource set)
Clears a file descriptor set */
-PHP_FUNCTION(fd_zero)
+PHP_FUNCTION(socket_fd_zero)
{
- zval **set;
+ zval **arg1;
fd_set *the_set;
- if (ZEND_NUM_ARGS() != 1 ||
- zend_get_parameters_ex(1, &set) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(the_set, fd_set *, set, -1, "File descriptor set", le_destroy);
+ ZEND_FETCH_RESOURCE(the_set, fd_set *, arg1, -1, "File descriptor set", le_destroy);
FD_ZERO(the_set);
-
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int select(int max_fd, resource readfds, resource writefds, resource exceptfds, int tv_sec, int tv_usec)
+/* {{{ proto int socket_select(int max_sockets, resource read_fd, resource write_fd, resource except_fd, int tv_sec, int tv_usec)
Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec */
-/* See select(2) man page for details.
-
- From man page:
- select waits for a number of file descriptors to change status.
-
- Three independent sets of descriptors are watched. Those in
- readfds will be watched to see if characters become avaliable for
- reading, those in writefds will be watched to see if it is ok to
- immediately write on them, and those in exceptfds will be watched
- for exceptions. On exit, the sets are modified in place to
- indicate which descriptors actually changed status.
-
- -1 is passed for any sets for which NULL would be passed to the
- system call.
- */
-
-PHP_FUNCTION(select)
+PHP_FUNCTION(socket_select)
{
- zval **max_fd, **readfds, **writefds,
- **exceptfds, **tv_sec, **tv_usec;
-
+ zval **arg1, **arg2, **arg3, **arg4, **arg5, **arg6;
struct timeval tv;
fd_set *rfds, *wfds, *xfds;
- int ret = 0;
- if (ZEND_NUM_ARGS() != 6 ||
- zend_get_parameters_ex(6, &max_fd, &readfds, &writefds, &exceptfds, &tv_sec, &tv_usec) == FAILURE) {
+ if (zend_get_parameters_ex(6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(3, max_fd, tv_sec, tv_usec);
-
- tv.tv_sec = Z_LVAL_PP(tv_sec);
- tv.tv_usec = Z_LVAL_PP(tv_usec);
-
- if (Z_LVAL_PP(readfds) != 0) {
- ZEND_FETCH_RESOURCE(rfds, fd_set *, readfds, -1, "File descriptor set", le_destroy);
- } else {
- rfds = NULL;
- }
- if (Z_LVAL_PP(writefds) != 0) {
- ZEND_FETCH_RESOURCE(wfds, fd_set *, writefds, -1, "File descriptor set", le_destroy);
- } else {
- wfds = NULL;
- }
-
- if (Z_LVAL_PP(exceptfds) != 0) {
- ZEND_FETCH_RESOURCE(xfds, fd_set *, exceptfds, -1, "File descriptor set", le_destroy);
- } else {
- xfds = NULL;
- }
-
- ret = select(Z_LVAL_PP(max_fd), rfds, wfds, xfds, &tv);
+ convert_to_long_ex(arg1);
+ convert_to_long_ex(arg5);
+ convert_to_long_ex(arg6);
+ ZEND_FETCH_RESOURCE(rfds, fd_set*, arg2, -1, "File descriptor set", le_destroy);
+ ZEND_FETCH_RESOURCE(wfds, fd_set*, arg3, -1, "File descriptor set", le_destroy);
+ ZEND_FETCH_RESOURCE(xfds, fd_set*, arg4, -1, "File descriptor set", le_destroy);
+ tv.tv_sec = Z_LVAL_PP(arg5);
+ tv.tv_usec = Z_LVAL_PP(arg6);
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_LONG(select(Z_LVAL_PP(arg1), rfds, wfds, xfds, &tv));
}
/* }}} */
-static int open_listen_sock(int port)
-{
- int fd;
- struct sockaddr_in la;
- struct hostent *hp;
-
- if ((hp = gethostbyname("0.0.0.0")) == NULL) {
- return -1;
- }
-
- memcpy((char *)&la.sin_addr, hp->h_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)) {
- return -1;
- }
- listen(fd, 128);
- return fd;
-}
-
-/* {{{ proto int open_listen_sock(int port)
+/* {{{ proto mixed socket_create_listen(int port)
Opens a socket on port to accept connections */
-PHP_FUNCTION(open_listen_sock)
+PHP_FUNCTION(socket_create_listen)
{
zval **port;
- int ret;
+ php_socket *php_sock;
- 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_sock(Z_LVAL_PP(port));
+ php_sock = open_listen_sock(Z_LVAL_PP(port));
- RETURN_LONG(((ret < 0) ? -errno : ret));
-}
-/* }}} */
-
-static int accept_connect(int fd, struct sockaddr *la)
-{
- int ret, m;
-
- m = sizeof(*la);
- if ((ret = accept(fd, la, &m)) < 0) {
- return -1;
+ if(php_sock == NULL) {
+ php_error(E_WARNING, "unable to create listening socket, %i", errno);
+ RETURN_FALSE;
}
- return ret;
+
+ ZEND_REGISTER_RESOURCE(return_value, php_sock, le_socket);
}
+/* }}} */
-/* {{{ proto int accept_connect(int fd)
+/* {{{ proto socket socket_accept(resource socket)
Accepts a connection on the listening socket fd */
-PHP_FUNCTION(accept_connect)
+PHP_FUNCTION(socket_accept)
{
- zval **fd;
- int ret;
+ zval **arg1;
+ php_socket *php_sock, *new_sock;
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, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
- ret = accept_connect(Z_LVAL_PP(fd), (struct sockaddr *)&sa);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ new_sock = accept_connect(php_sock, (struct sockaddr*)&sa);
+
+ if(new_sock == NULL) {
+ php_error(E_WARNING, "unable to accept connection, %i", errno);
+ RETURN_FALSE
+ }
+
+ ZEND_REGISTER_RESOURCE(return_value, new_sock, le_socket);
}
/* }}} */
-/* {{{ proto bool set_nonblock(int fd)
+/* {{{ proto bool socket_set_nonblock(resource socket)
Sets nonblocking mode for file descriptor fd */
-PHP_FUNCTION(set_nonblock)
+PHP_FUNCTION(socket_set_nonblock)
{
- zval **fd;
- int ret;
+ zval **arg1;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 1 ||
- zend_get_parameters_ex(1, &fd) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
-
- ret = fcntl(Z_LVAL_PP(fd), F_SETFL, O_NONBLOCK);
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+
+ if (fcntl(php_sock->socket, F_SETFL, O_NONBLOCK) == 0) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
}
/* }}} */
-/* {{{ proto bool listen(int fd, int backlog)
+/* {{{ proto bool socket_listen(resource socket, int backlog)
Sets the maximum number of connections allowed to be waited for on the socket specified by fd */
-PHP_FUNCTION(listen)
+PHP_FUNCTION(socket_listen)
{
- zval **fd, **backlog;
- int ret;
+ zval **arg1, **arg2;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fd, &backlog) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(2, fd, backlog);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(arg2);
- ret = listen(Z_LVAL_PP(fd), Z_LVAL_PP(backlog));
+ if (listen(php_sock->socket, Z_LVAL_PP(arg2)) == 0) {
+ RETURN_FALSE;
+ }
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool close(int fd)
+/* {{{ proto void socket_close(resource socket)
Closes a file descriptor */
-PHP_FUNCTION(close)
+PHP_FUNCTION(socket_close)
{
- zval **fd;
- int ret;
+ zval **arg1;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 1 ||
- zend_get_parameters_ex(1, &fd) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
- ret = close(Z_LVAL_PP(fd));
-
- if (ret == -1) {
- php_error(E_WARNING, "Invalid file descriptor");
- RETURN_FALSE;
- }
- RETURN_TRUE;
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ zend_list_delete(Z_RESVAL_PP(arg1));
}
/* }}} */
-/* {{{ proto int write(int fd, string buf, int length)
- Writes length bytes of buf to the file descriptor fd */
-PHP_FUNCTION(write)
+/* {{{ proto int socket_write(resource socket, string buf[, int length])
+ Writes the buffer to the file descriptor fd, length is optional */
+PHP_FUNCTION(socket_write)
{
- zval **fd, **buf, **length;
- int ret;
+ zval **arg1, **arg2, **arg3;
+ php_socket *php_sock;
+ int retval, which, argc = ZEND_NUM_ARGS();
- if (ZEND_NUM_ARGS() != 3 ||
- zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
+ if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
-
- multi_convert_to_long_ex(2, fd, length);
- convert_to_string_ex(buf);
- if (Z_STRLEN_PP(buf) < Z_LVAL_PP(length)) {
- ret = write(Z_LVAL_PP(fd), (void *)Z_STRVAL_PP(buf), Z_STRLEN_PP(buf));
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_string_ex(arg2);
+ if (argc == 3) {
+ convert_to_long_ex(arg3);
+ which = (Z_STRLEN_PP(arg2) < Z_LVAL_PP(arg3)) ? 1 : 0;
} else {
- ret = write(Z_LVAL_PP(fd), (void *)Z_STRVAL_PP(buf), Z_LVAL_PP(length));
+ which = 1;
}
-
- RETURN_LONG(((ret < 0) ? -errno : ret));
-}
-/* }}} */
-
-/* {{{ proto int read(int fd, string &buf, int length [, int type])
- Reads length bytes from fd into buf */
-
-/* php_read -- wrapper around read() so that it only reads to a \r or \n. */
-int php_read(int fd, void *buf, int maxlen)
-{
- char *t;
- int m = 0, n = 0;
- int no_read = 0;
- int nonblock = 0;
-
- m = fcntl(fd, F_GETFL);
- if (m < 0)
- return m;
+#ifndef PHP_WIN32
+ retval = write(php_sock->socket, (void *)Z_STRVAL_PP(arg2), (which ? Z_STRLEN_PP(arg2) : Z_LVAL_PP(arg3)));
+#else
+ retval = send(php_sock->socket, Z_STRVAL_PP(arg2), (which ? Z_STRLEN_PP(arg2) : Z_LVAL_PP(arg3)), 0);
+#endif
- nonblock = (m & O_NONBLOCK);
- m = 0;
+ if (!retval) {
+ php_error(E_WARNING, "unable to write, %i", errno);
+ RETURN_LONG(0);
+ }
- errno = 0;
- t = (char *) buf;
- while (*t != '\n' && *t != '\r' && n < maxlen) {
- if (m > 0) {
- t++;
- n++;
- } else if (m == 0) {
- no_read++;
- if (nonblock && no_read >= 2) {
- return n; /* The first pass, m always is 0, so no_read becomes 1
- * in the first pass. no_read becomes 2 in the second pass,
- * and if this is nonblocking, we should return.. */
- }
- if (no_read > 200) {
- errno = ECONNRESET;
- return -1;
- }
- }
- if (n < maxlen) {
- m = read(fd, (void *) t, 1);
- }
- if (errno != 0 && errno != ESPIPE && errno != EAGAIN) {
- return -1;
- }
- errno = 0;
- }
- if (n < maxlen)
- n++; /* The only reasons it makes it to here is
- * if '\n' or '\r' are encountered. So, increase
- * the return by 1 to make up for the lack of the
- * '\n' or '\r' in the count (since read() takes
- * place at the end of the loop..) */
- return n;
+ RETURN_LONG(retval);
}
+/* }}} */
-PHP_FUNCTION(read)
+/* {{{ proto mixed socket_read(resource socket, int length [, int type])
+ Reads length bytes from socket */
+PHP_FUNCTION(socket_read)
{
- zval **fd, **buf, **length, **binary;
+ zval **arg1, **arg2, **arg3;
char *tmpbuf;
- int ret;
- int (*read_function)(int, void *, int);
+ php_socket *php_sock;
+ int (*read_function)(int, void *, int) = (int (*)(int, void *, int)) php_read;
+ int retval, argc = ZEND_NUM_ARGS();
- if (ZEND_NUM_ARGS() < 3 || ZEND_NUM_ARGS() > 4 ||
- zend_get_parameters_ex(ZEND_NUM_ARGS(), &fd, &buf, &length, &binary) == FAILURE) {
+ if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(ZEND_NUM_ARGS() - 1, fd, length, binary);
- convert_to_string_ex(buf);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(arg2);
- if (ZEND_NUM_ARGS() == 4) {
- switch (Z_LVAL_PP(binary)) {
- case PHP_SYSTEM_READ:
- case PHP_BINARY_READ:
- read_function = (int (*)(int, void *, int)) read;
- break;
- case PHP_NORMAL_READ:
- default:
- read_function = (int (*)(int, void *, int)) php_read;
- break;
+ if (argc == 3) {
+ convert_to_long_ex(arg3);
+ switch (Z_LVAL_PP(arg3)) {
+ case PHP_SYSTEM_READ:
+ case PHP_BINARY_READ:
+ read_function = (int (*)(int, void *, int)) read;
+ break;
}
- } else {
- read_function = (int (*)(int, void *, int)) php_read;
}
- tmpbuf = emalloc((Z_LVAL_PP(length)+1)*sizeof(char));
- if (tmpbuf == NULL) {
- php_error(E_WARNING, "Couldn't allocate memory from %s()", get_active_function_name());
+ if ((tmpbuf = (char*)emalloc((Z_LVAL_PP(arg2)+1)*sizeof(char))) == NULL) {
+ php_error(E_WARNING, "couldn't allocate memory");
RETURN_FALSE;
}
-
- ret = (*read_function)(Z_LVAL_PP(fd), tmpbuf, Z_LVAL_PP(length));
-
- if (ret >= 0) {
- if(Z_STRLEN_PP(buf) > 0) {
- efree(Z_STRVAL_PP(buf));
- }
- tmpbuf[ret] = '\0';
- Z_STRVAL_PP(buf) = erealloc(tmpbuf, ret+1);
- Z_STRLEN_PP(buf) = ret;
+#ifndef PHP_WIN32
+ retval = (*read_function)(php_sock->socket, tmpbuf, Z_LVAL_PP(arg2));
+#else
+ retval = recv(php_sock->socket, tmpbuf, Z_LVAL_PP(arg2), 0);
+#endif
- RETURN_LONG(ret);
- } else {
+ if (retval <= 0) {
efree(tmpbuf);
- RETURN_LONG(-errno);
+ RETURN_FALSE;
}
+
+ tmpbuf[retval] = '\0';
+ RETURN_STRING(tmpbuf, 1);
}
/* }}} */
-/* {{{ proto int getsockname(int fd, string &addr[, int &port])
+/* {{{ proto bool socket_getsockname(resource socket, 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 */
-volatile int inet_ntoa_lock = 0;
-
-PHP_FUNCTION(getsockname)
+PHP_FUNCTION(socket_getsockname)
{
- zval **fd, **addr, **port;
+ zval **arg1, **addr, **port;
char *tmp;
php_sockaddr_storage sa_storage;
+ php_socket *php_sock;
struct sockaddr *sa;
struct sockaddr_in *sin;
struct sockaddr_un *s_un;
int salen = sizeof(php_sockaddr_storage);
- int ret;
+ int argc = ZEND_NUM_ARGS();
- if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
- zend_get_parameters_ex(ZEND_NUM_ARGS(), &fd, &addr, &port) == FAILURE) {
+ if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &arg1, &addr, &port) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(ZEND_NUM_ARGS() - 1, fd, port);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(port);
convert_to_string_ex(addr);
sa = (struct sockaddr *) &sa_storage;
- ret = getsockname(Z_LVAL_PP(fd), sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ if (getsockname(php_sock->socket, sa, &salen) != 0) {
+ php_error(E_WARNING, "unable to retrieve socket name, %i", errno);
+ RETURN_FALSE;
} else {
char *addr_string;
switch (sa->sa_family) {
- case AF_INET: {
- sin = (struct sockaddr_in *) sa;
- while (inet_ntoa_lock == 1);
- inet_ntoa_lock = 1;
- addr_string = inet_ntoa(sin->sin_addr);
- tmp = emalloc(strlen(addr_string) + 1);
- memset(tmp, 0, strlen(addr_string) + 1);
- strncpy(tmp, addr_string, strlen(addr_string));
- inet_ntoa_lock = 0;
-
- if (Z_STRLEN_PP(addr) > 0) {
- efree(Z_STRVAL_PP(addr));
- }
-
- Z_STRVAL_PP(addr) = tmp;
- Z_STRLEN_PP(addr) = strlen(tmp);
- Z_LVAL_PP(port) = htons(sin->sin_port);
-
- RETURN_LONG(ret);
- }
- case AF_UNIX: {
- if (Z_STRLEN_PP(addr) > 0) {
- efree(Z_STRVAL_PP(addr));
- }
- s_un = (struct sockaddr_un *) sa;
- Z_STRVAL_PP(addr) = estrndup(s_un->sun_path,strlen(s_un->sun_path));
- Z_STRLEN_PP(addr) = strlen(s_un->sun_path);
- RETURN_LONG(ret);
- }
- default:
- RETURN_LONG(-EINVAL);
+ case AF_INET:
+ sin = (struct sockaddr_in *) sa;
+ while (inet_ntoa_lock == 1);
+ inet_ntoa_lock = 1;
+ addr_string = inet_ntoa(sin->sin_addr);
+ tmp = (char*)emalloc(strlen(addr_string) + 1);
+ memset(tmp, 0, strlen(addr_string) + 1);
+ strncpy(tmp, addr_string, strlen(addr_string));
+ inet_ntoa_lock = 0;
+
+ if (Z_STRLEN_PP(addr) > 0) {
+ efree(Z_STRVAL_PP(addr));
+ }
+
+ Z_STRVAL_PP(addr) = tmp;
+ Z_STRLEN_PP(addr) = strlen(tmp);
+ Z_LVAL_PP(port) = htons(sin->sin_port);
+ RETURN_TRUE;
+
+ case AF_UNIX:
+ if (Z_STRLEN_PP(addr) > 0) {
+ efree(Z_STRVAL_PP(addr));
+ }
+ s_un = (struct sockaddr_un *) sa;
+ Z_STRVAL_PP(addr) = estrndup(s_un->sun_path,strlen(s_un->sun_path));
+ Z_STRLEN_PP(addr) = strlen(s_un->sun_path);
+ RETURN_TRUE;
+
+ default:
+ RETURN_FALSE;
}
}
}
/* }}} */
-/* {{{ proto int gethostbyname(string name, string &addr)
- Given a hostname, sets addr to be a human-readable version of the host's address */
-
-#if 0
-/* Another lock to prevent multiple threads from grabbing gethostbyname() */
-volatile int gethostbyname_lock = 0;
-
-PHP_FUNCTION(gethostbyname)
-{
- zval **name, **addr;
- int ret;
- char *tmp, *addr_string;
- struct hostent *host_struct;
- struct in_addr a;
-
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &name, &addr) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- convert_to_string_ex(name);
- convert_to_string_ex(addr);
-
- while (gethostbyname_lock == 1);
- gethostbyname_lock = 1;
-
- 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 */
- }
- if (host_struct->h_addrtype != AF_INET) {
- gethostbyname_lock = 0;
- RETURN_LONG(-EINVAL);
- }
- while (inet_ntoa_lock == 1);
- inet_ntoa_lock = 1;
-
- a.s_addr = (int) (*(host_struct->h_addr_list[0]));
- addr_string = inet_ntoa(a);
- tmp = emalloc(strlen(addr_string) + 1);
- strncpy(tmp, addr_string, strlen(addr_string));
-
- inet_ntoa_lock = 0;
- gethostbyname_lock = 0;
-
- Z_STRVAL_PP(addr) = tmp;
- Z_STRLEN_PP(addr) = strlen(tmp);
-
- RETURN_LONG(0);
-}
-
-/* }}} */
-
-#endif
-
-/* {{{ proto int getpeername(int fd, string &addr[, int &port])
+/* {{{ proto bool socket_getpeername(resource socket, 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 remote side of a socket */
-
-PHP_FUNCTION(getpeername)
+PHP_FUNCTION(socket_getpeername)
{
- zval **fd, **addr, **port;
+ zval **arg1, **arg2, **arg3;
char *tmp;
php_sockaddr_storage sa_storage;
+ php_socket *php_sock;
struct sockaddr *sa;
struct sockaddr_in *sin;
struct sockaddr_un *s_un;
int salen = sizeof(php_sockaddr_storage);
- int ret;
+ int argc = ZEND_NUM_ARGS();
- if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
- zend_get_parameters_ex(ZEND_NUM_ARGS(), &fd, &addr, &port) == FAILURE) {
+ if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(ZEND_NUM_ARGS() - 1, fd, port);
- convert_to_string_ex(addr);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_string_ex(arg2);
+ convert_to_long_ex(arg3);
sa = (struct sockaddr *) &sa_storage;
- ret = getpeername(Z_LVAL_PP(fd), sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ if (getpeername(php_sock->socket, sa, &salen) != 0) {
+ php_error(E_WARNING, "unable to retrieve peername, %i", errno);
+ RETURN_FALSE;
} else {
char *addr_string;
switch (sa->sa_family) {
- case AF_INET: {
+ case AF_INET:
sin = (struct sockaddr_in *) sa;
while (inet_ntoa_lock == 1);
inet_ntoa_lock = 1;
addr_string = inet_ntoa(sin->sin_addr);
- tmp = emalloc(strlen(addr_string) + 1);
+ tmp = (char*)emalloc(strlen(addr_string) + 1);
memset(tmp, 0, strlen(addr_string) + 1);
strncpy(tmp, addr_string, strlen(addr_string));
inet_ntoa_lock = 0;
- if (Z_STRLEN_PP(addr) > 0) {
- efree(Z_STRVAL_PP(addr));
+ if (Z_STRLEN_PP(arg2) > 0) {
+ efree(Z_STRVAL_PP(arg2));
}
- Z_STRVAL_PP(addr) = tmp;
- Z_STRLEN_PP(addr) = strlen(tmp);
- if (ZEND_NUM_ARGS() > 2)
- Z_LVAL_PP(port) = htons(sin->sin_port);
+ Z_STRVAL_PP(arg2) = tmp;
+ Z_STRLEN_PP(arg2) = strlen(tmp);
- RETURN_LONG(ret);
- }
- case AF_UNIX: {
- if (Z_STRLEN_PP(addr) > 0) {
- efree(Z_STRVAL_PP(addr));
+ if (argc > 2) {
+ Z_LVAL_PP(arg3) = htons(sin->sin_port);
}
- s_un = (struct sockaddr_un *) sa;
- Z_STRVAL_PP(addr) = estrndup(s_un->sun_path,strlen(s_un->sun_path));
- Z_STRLEN_PP(addr) = strlen(s_un->sun_path);
- RETURN_LONG(ret);
- }
- default:
- RETURN_LONG(-EINVAL);
- }
- }
-}
-/* }}} */
-
-/* {{{ proto int gethostbyaddr(string addr, string &name)
- Given a human-readable address, sets name to be the host's name */
-#if 0
-/* Another lock to prevent multiple threads from grabbing gethostbyname() */
-volatile int gethostbyaddr_lock = 0;
+ RETURN_TRUE;
-PHP_FUNCTION(gethostbyaddr)
-{
- zval **name, **addr;
- int ret;
- char *tmp, *addr_string;
- struct hostent *host_struct;
- struct in_addr addr_buf;
-
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &addr, &name) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- convert_to_string_ex(addr);
- convert_to_string_ex(name);
-
- ret = inet_aton(Z_STRVAL_PP(addr), &addr_buf);
-
- if (ret < 0) {
- RETURN_LONG(-EINVAL);
- }
-
- while (gethostbyaddr_lock == 1);
- gethostbyaddr_lock = 1;
-
- host_struct = gethostbyaddr((char *)&addr_buf, sizeof(addr_buf), AF_INET);
+ case AF_UNIX:
+ if (Z_STRLEN_PP(arg2) > 0) {
+ efree(Z_STRVAL_PP(arg2));
+ }
+ s_un = (struct sockaddr_un *) sa;
+ Z_STRVAL_PP(arg2) = estrndup(s_un->sun_path,strlen(s_un->sun_path));
+ Z_STRLEN_PP(arg2) = strlen(s_un->sun_path);
+ RETURN_TRUE;
- if (!host_struct) {
- gethostbyaddr_lock = 0;
- RETURN_LONG(-(h_errno) - 10000);
- }
- if (host_struct->h_addrtype != AF_INET) {
- gethostbyaddr_lock = 0;
- RETURN_LONG(-EINVAL);
+ default:
+ RETURN_FALSE;
+ }
}
-
- addr_string = host_struct->h_name;
- tmp = emalloc(strlen(addr_string) + 1);
- strncpy(tmp, addr_string, strlen(addr_string));
-
- gethostbyaddr_lock = 0;
-
- Z_STRVAL_PP(addr) = tmp;
- Z_STRLEN_PP(addr) = strlen(tmp);
-
- RETURN_LONG(0);
}
/* }}} */
-#endif
-
-/* {{{ proto int socket(int domain, int type, int protocol)
+/* {{{ proto mixed socket_create(int domain, int type, int protocol)
Creates an endpoint for communication in the domain specified by domain, of type specified by type */
-PHP_FUNCTION(socket)
+PHP_FUNCTION(socket_create)
{
- zval **domain, **type, **protocol;
- int ret;
+ zval **arg1, **arg2, **arg3;
+ php_socket *php_sock = (php_socket*)emalloc(sizeof(php_socket));
- if (ZEND_NUM_ARGS() != 3 ||
- zend_get_parameters_ex(3, &domain, &type, &protocol) == FAILURE) {
+ if (zend_get_parameters_ex(3, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_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;
+ convert_to_long_ex(arg1);
+ convert_to_long_ex(arg2);
+ convert_to_long_ex(arg3);
+
+ if (Z_LVAL_PP(arg1) != AF_UNIX && Z_LVAL_PP(arg1) != AF_INET) {
+ php_error(E_WARNING, "invalid socket domain [%i] specified, assuming AF_INET", Z_LVAL_PP(arg1));
+ Z_LVAL_PP(arg1) = 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;
+ if (Z_LVAL_PP(arg2) > 10) {
+ php_error(E_WARNING, "invalid socket type [%i] specified, assuming SOCK_STREAM", Z_LVAL_PP(arg2));
+ Z_LVAL_PP(arg2) = SOCK_STREAM;
}
- ret = socket(Z_LVAL_PP(domain), Z_LVAL_PP(type), Z_LVAL_PP(protocol));
+ php_sock->socket = socket(Z_LVAL_PP(arg1), Z_LVAL_PP(arg2), Z_LVAL_PP(arg3));
+ php_sock->type = Z_LVAL_PP(arg1);
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ if(IS_INVALID_SOCKET(php_sock)) {
+ RETURN_FALSE;
+ }
+
+ ZEND_REGISTER_RESOURCE(return_value, php_sock, le_socket);
}
/* }}} */
-/* {{{ proto int connect(int sockfd, string addr [, int port])
- Opens a connection to addr:port on the socket specified by sockfd */
-PHP_FUNCTION(connect)
+/* {{{ proto bool socket_connect(resource socket, string addr [, int port])
+ Opens a connection to addr:port on the socket specified by socket */
+PHP_FUNCTION(socket_connect)
{
- zval **sockfd, **addr, **port;
+ zval **arg1, **arg2, **arg3;
+ php_socket *php_sock;
php_sockaddr_storage sa_storage;
struct sockaddr *sa = (struct sockaddr *) &sa_storage;
struct sockaddr_in *sin;
struct sockaddr_un *s_un;
- int ret;
+ int retval;
socklen_t salen;
struct in_addr addr_buf;
struct hostent *host_struct;
int argc = ZEND_NUM_ARGS();
- if (argc < 2 || argc > 3 ||
- zend_get_parameters_ex(argc, &sockfd, &addr, &port) == FAILURE) {
+ if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(sockfd)
- convert_to_string_ex(addr);
- if (argc > 2) {
- convert_to_long_ex(port);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_string_ex(arg2);
+
+ if (argc == 3) {
+ convert_to_long_ex(arg3);
}
memset(sa, 0, sizeof(sa_storage));
-
salen = sizeof(sa_storage);
- ret = getsockname(Z_LVAL_PP(sockfd), sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ if (getsockname(php_sock->socket, sa, &salen) != 0) {
+ php_error(E_WARNING, "failed connecting to [%s], %i", Z_STRVAL_PP(arg2), errno);
+ RETURN_FALSE;
}
switch(sa->sa_family) {
- case AF_INET: {
+ case AF_INET:
sin = (struct sockaddr_in *)sa;
salen = sizeof(struct sockaddr_in);
@@ -1044,14 +906,14 @@ PHP_FUNCTION(connect)
WRONG_PARAM_COUNT;
}
- sin->sin_port = htons((unsigned short int)Z_LVAL_PP(port));
- if (inet_aton(Z_STRVAL_PP(addr), &addr_buf) == 0) {
+ sin->sin_port = htons((unsigned short int)Z_LVAL_PP(arg3));
+ if (inet_aton(Z_STRVAL_PP(arg2), &addr_buf) == 0) {
sin->sin_addr.s_addr = addr_buf.s_addr;
} else {
char *q = (char *) &(sin->sin_addr.s_addr);
- host_struct = gethostbyname(Z_STRVAL_PP(addr));
+ host_struct = gethostbyname(Z_STRVAL_PP(arg2));
if (host_struct->h_addrtype != AF_INET) {
- RETURN_LONG(-EINVAL);
+ RETURN_FALSE;
}
q[0] = host_struct->h_addr_list[0][0];
q[1] = host_struct->h_addr_list[0][1];
@@ -1059,156 +921,161 @@ PHP_FUNCTION(connect)
q[3] = host_struct->h_addr_list[0][3];
}
- ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) sin, salen);
+ retval = connect(php_sock->socket, (struct sockaddr *) sin, salen);
break;
- }
- case AF_UNIX: {
+
+ case AF_UNIX:
s_un = (struct sockaddr_un *)sa;
- snprintf(s_un->sun_path, 108, "%s", Z_STRVAL_PP(addr));
- ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) s_un, SUN_LEN(s_un));
+ snprintf(s_un->sun_path, 108, "%s", Z_STRVAL_PP(arg2));
+ retval = connect(php_sock->socket, (struct sockaddr *) s_un, SUN_LEN(s_un));
break;
- }
- default:
- ret = -1;
- errno = EINVAL;
+
+ default:
+ RETURN_FALSE;
}
- RETURN_LONG(((ret < 0) ? -errno : ret));
+
+ if (retval != 0) {
+ php_error(E_WARNING, "unable to connect, %i", errno);
+ RETURN_FALSE;
+ }
+
+ RETURN_FALSE;
}
/* }}} */
-/* {{{ proto string strerror(int errno)
+/* {{{ proto string socket_strerror(int errno)
Returns a string describing an error */
-PHP_FUNCTION(strerror)
+PHP_FUNCTION(socket_strerror)
{
- zval **error;
+ zval **arg1;
const char *buf;
-
- if (ZEND_NUM_ARGS() != 1 ||
- zend_get_parameters_ex(1, &error) == FAILURE) {
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- if (Z_LVAL_PP(error) < -10000) {
- Z_LVAL_PP(error) += 10000;
- buf = hstrerror(-(Z_LVAL_PP(error)));
- } else {
- buf = strerror(-(Z_LVAL_PP(error)));
- }
- if (!buf) {
- RETURN_FALSE;
+#ifndef PHP_WIN32
+ if (Z_LVAL_PP(arg1) < -10000) {
+ Z_LVAL_PP(arg1) += 10000;
+ buf = hstrerror(-(Z_LVAL_PP(arg1)));
+ } else {
+ buf = strerror(-(Z_LVAL_PP(arg1)));
}
-
- RETURN_STRING((char *)buf, 1);
+#else
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ Z_LVAL_PP(arg1),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&buf,
+ 0,
+ NULL
+ );
+#endif
+ RETURN_STRING(buf?(char*)buf:"", 1);
}
/* }}} */
-/* {{{ 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)
+/* {{{ proto bool socket_bind(resource socket, string addr [, int port])
+ Binds an open socket to a listening port, port is only specified in AF_INET family. */
+PHP_FUNCTION(socket_bind)
{
- zval **arg0, **arg1, **arg2;
- long ret;
+ zval **arg1, **arg2, **arg3;
+ long retval;
php_sockaddr_storage sa_storage;
- struct sockaddr *sock_type = (struct sockaddr *) &sa_storage;
+ struct sockaddr *sock_type = (struct sockaddr*) &sa_storage;
socklen_t length = sizeof(sa_storage);
-
- switch (ZEND_NUM_ARGS())
- {
- case 2:
- if (zend_get_parameters_ex(2, &arg0, &arg1) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- break;
+ php_socket *php_sock;
+ int argc = ZEND_NUM_ARGS();
+
+
+ if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ switch (argc) {
case 3:
- if (zend_get_parameters_ex(3, &arg0, &arg1, &arg2) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
+ convert_to_long_ex(arg3);
+ case 2:
+ convert_to_string_ex(arg2);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
break;
- default:
- WRONG_PARAM_COUNT;
}
+
- convert_to_long_ex(arg0);
-
- ret = getsockname(Z_LVAL_PP(arg0), sock_type, &length);
- if (ret < 0) {
- RETURN_LONG(-errno);
- }
- if (sock_type->sa_family == AF_UNIX) {
+ if (php_sock->type == AF_UNIX) {
struct sockaddr_un *sa = (struct sockaddr_un *) sock_type;
- memset(sa, 0, sizeof(sa_storage)); /* This is safe -> sock_type = &sa_storage -> sa = sock_type */
+ memset(sa, 0, sizeof(sa_storage));
sa->sun_family = AF_UNIX;
- snprintf(sa->sun_path, 108, "%s", Z_STRVAL_PP(arg1));
- ret = bind(Z_LVAL_PP(arg0), (struct sockaddr *) sa, SUN_LEN(sa));
- } else if (sock_type->sa_family == AF_INET) {
- struct sockaddr_in *sa = (struct sockaddr_in *) sock_type;
- struct in_addr addr_buf;
+ snprintf(sa->sun_path, 108, "%s", Z_STRVAL_PP(arg2));
+ retval = bind(php_sock->socket, (struct sockaddr *) sa, SUN_LEN(sa));
- memset(sa, 0, sizeof(sa_storage));
+ } else if (php_sock->type == AF_INET) {
+
+ struct sockaddr_in sa;
+ struct hostent *hp;
- if (ZEND_NUM_ARGS() != 3) {
+ if (argc != 3) {
WRONG_PARAM_COUNT;
}
- 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 = 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;
+ if ((hp = gethostbyname(Z_STRVAL_PP(arg2))) == NULL) {
+ php_error(E_WARNING, "unable to lookup [%s], %i", Z_STRVAL_PP(arg2), h_errno);
+ RETURN_FALSE;
}
+
+ memcpy((char *)&sa.sin_addr, hp->h_addr, hp->h_length);
+ sa.sin_family = hp->h_addrtype;
+ sa.sin_port = htons((unsigned short)Z_LVAL_PP(arg3));
+ retval = bind(php_sock->socket, (struct sockaddr *)&sa, sizeof(sa));
- ret = bind(Z_LVAL_PP(arg0), (struct sockaddr *) sa, sizeof(sa_storage));
} else {
- RETURN_LONG(-EPROTONOSUPPORT);
+ php_error(E_WARNING,"the specified port is not supported");
+ RETURN_FALSE;
}
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ if (retval != 0) {
+ php_error(E_WARNING, "unable to bind address, %i", errno);
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
}
/* }}} */
-/* {{{ proto resource build_iovec(int num_vectors [, int ...])
+/* {{{ proto resource socket_iovec_alloc(int num_vectors [, int ...])
Builds a 'struct iovec' for use with sendmsg, recvmsg, writev, and readv */
/* First parameter is number of vectors, each additional parameter is the
length of the vector to create.
*/
-
-PHP_FUNCTION(build_iovec)
+PHP_FUNCTION(socket_iovec_alloc)
{
zval ***args = (zval ***)NULL;
php_iovec_t *vector;
struct iovec *vector_array;
- int i, j, num_vectors, argcount = ZEND_NUM_ARGS();
+ int i, j, num_vectors, argc = ZEND_NUM_ARGS();
- args = emalloc(argcount * sizeof(zval *));
+ args = (zval***)emalloc(argc*sizeof(zval**));
- if (argcount < 1 ||
- zend_get_parameters_array_ex(argcount, args) == FAILURE) {
- if (args)
- efree(args);
+ if (argc < 1 || zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
WRONG_PARAM_COUNT;
}
convert_to_long_ex(args[0]);
num_vectors = Z_LVAL_PP(args[0]);
- vector_array = emalloc(sizeof(struct iovec) * (num_vectors + 1));
+ vector_array = (struct iovec*)emalloc(sizeof(struct iovec)*(num_vectors+1));
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_array[i].iov_base = (char*)emalloc(Z_LVAL_PP(args[j]));
+ vector_array[i].iov_len = Z_LVAL_PP(args[j]);
}
- vector = emalloc(sizeof(php_iovec_t));
+ vector = (php_iovec_t*)emalloc(sizeof(php_iovec_t));
vector->iov_array = vector_array;
vector->count = num_vectors;
@@ -1216,15 +1083,14 @@ PHP_FUNCTION(build_iovec)
}
/* }}} */
-/* {{{ proto string fetch_iovec(resource iovec_id, int iovec_position)
+/* {{{ proto string socket_iovec_fetch(resource iovec, int iovec_position)
Returns the data held in the iovec specified by iovec_id[iovec_position] */
-PHP_FUNCTION(fetch_iovec)
+PHP_FUNCTION(socket_iovec_fetch)
{
zval **iovec_id, **iovec_position;
php_iovec_t *vector;
- 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;
}
@@ -1234,20 +1100,20 @@ PHP_FUNCTION(fetch_iovec)
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[Z_LVAL_PP(iovec_position)].iov_base,
vector->iov_array[Z_LVAL_PP(iovec_position)].iov_len, 1);
}
/* }}} */
-/* {{{ proto bool set_iovec(resource iovec_id, int iovec_position, string new_val)
+/* {{{ proto bool socket_iovec_set(resource iovec, int iovec_position, string new_val)
Sets the data held in iovec_id[iovec_position] to new_val */
-PHP_FUNCTION(set_iovec)
+PHP_FUNCTION(socket_iovec_set)
{
zval **iovec_id, **iovec_position, **new_val;
php_iovec_t *vector;
- 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;
}
@@ -1269,25 +1135,24 @@ PHP_FUNCTION(set_iovec)
}
/* }}} */
-/* {{{ proto bool add_iovec(resource iovec_id, int iov_len)
+/* {{{ proto bool socket_iovec_add(resource iovec, int iov_len)
Adds a new vector to the scatter/gather array */
-PHP_FUNCTION(add_iovec)
+PHP_FUNCTION(socket_iovec_add)
{
zval **iovec_id, **iov_len;
php_iovec_t *vector;
struct iovec *vector_array;
- 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;
}
ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
- vector_array = emalloc(sizeof(struct iovec) * (vector->count + 2));
+ vector_array = (struct iovec*)emalloc(sizeof(struct iovec) * (vector->count + 2));
memcpy(vector_array, vector->iov_array, sizeof(struct iovec) * vector->count);
- vector_array[vector->count].iov_base = emalloc(Z_LVAL_PP(iov_len));
+ vector_array[vector->count].iov_base = (char*)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;
@@ -1298,17 +1163,16 @@ PHP_FUNCTION(add_iovec)
/* }}} */
-/* {{{ proto bool delete_iovec(resource iovec_id, int iov_pos)
+/* {{{ proto bool socket_iovec_delete(resource iovec, int iov_pos)
Deletes a vector from an array of vectors */
-PHP_FUNCTION(delete_iovec)
+PHP_FUNCTION(socket_iovec_delete)
{
zval **iovec_id, **iov_pos;
php_iovec_t *vector;
struct iovec *vector_array;
int i;
- 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;
}
@@ -1318,7 +1182,7 @@ PHP_FUNCTION(delete_iovec)
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));
+ vector_array = (struct iovec*)emalloc(vector->count * sizeof(struct iovec));
for (i = 0; i < vector->count; i++) {
if (i < Z_LVAL_PP(iov_pos)) {
@@ -1336,677 +1200,663 @@ PHP_FUNCTION(delete_iovec)
/* }}} */
-/* {{{ proto bool free_iovec(resource iovec_id)
+/* {{{ proto bool socket_iovec_free(resource iovec)
Frees the iovec specified by iovec_id */
-PHP_FUNCTION(free_iovec)
+PHP_FUNCTION(socket_iovec_free)
{
- zval **iovec_id;
+ zval **arg1;
php_iovec_t *vector;
- if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &iovec_id) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+ ZEND_FETCH_RESOURCE(vector, php_iovec_t *, arg1, -1, "IO vector table", le_iov);
- zend_list_delete(Z_LVAL_PP(iovec_id));
+ zend_list_delete(Z_RESVAL_PP(arg1));
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int readv(int fd, resource iovec_id)
+/* {{{ proto bool socket_readv(resource socket, resource iovec_id)
Reads from an fd, using the scatter-gather array defined by iovec_id */
-PHP_FUNCTION(readv)
+PHP_FUNCTION(socket_readv)
{
- zval **fd, **iovec_id;
+ zval **arg1, **arg2;
php_iovec_t *vector;
- int ret;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &fd, &iovec_id) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(vector, php_iovec_t *, arg2, -1, "IO vector table", le_iov);
- ret = readv(Z_LVAL_PP(fd), vector->iov_array, vector->count);
+ if (readv(php_sock->socket, vector->iov_array, vector->count) != 0) {
+ php_error(E_WARNING, "unable to read, %i", errno);
+ RETURN_FALSE;
+ }
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int writev(int fd, resource iovec_id)
+/* {{{ proto bool socket_writev(resource socket, resource iovec_id)
Writes to a file descriptor, fd, using the scatter-gather array defined by iovec_id */
-PHP_FUNCTION(writev)
+PHP_FUNCTION(socket_writev)
{
- zval **fd, **iovec_id;
+ zval **arg1, **arg2;
php_iovec_t *vector;
- int ret;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 2 ||
- zend_get_parameters_ex(2, &fd, &iovec_id) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(vector, php_iovec_t *, iovec_id, -1, "IO vector table", le_iov);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(vector, php_iovec_t *, arg2, -1, "IO vector table", le_iov);
- ret = writev(Z_LVAL_PP(fd), vector->iov_array, vector->count);
+ if (writev(php_sock->socket, vector->iov_array, vector->count) != 0) {
+ php_error(E_WARNING, "unable to write, %i", errno);
+ RETURN_FALSE;
+ }
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int recv(int fd, string buf, int len, int flags)
+/* {{{ proto mixed socket_recv(resource socket, int len, int flags)
Receives data from a connected socket */
-/* May be used with SOCK_DGRAM sockets. */
-PHP_FUNCTION(recv)
+PHP_FUNCTION(socket_recv)
{
- zval **fd, **buf, **len, **flags;
- int ret;
+ zval **arg1, **arg2, **arg3;
char *recv_buf;
+ php_socket *php_sock;
+ int retval;
- if (ZEND_NUM_ARGS() != 4 ||
- zend_get_parameters_ex(4, &fd, &buf, &len, &flags) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(3, fd, len, flags);
- convert_to_string_ex(buf);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(arg2);
+ convert_to_long_ex(arg3);
- recv_buf = emalloc(Z_LVAL_PP(len) + 2);
- memset(recv_buf, 0, Z_LVAL_PP(len) + 2);
+ recv_buf = (char*)emalloc(Z_LVAL_PP(arg2) + 2);
+ memset(recv_buf, 0, Z_LVAL_PP(arg2) + 2);
- 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 (Z_STRLEN_PP(buf) > 0) {
- efree(Z_STRVAL_PP(buf));
- }
- Z_STRVAL_PP(buf) = estrndup(recv_buf, strlen(recv_buf));
- Z_STRLEN_PP(buf) = strlen(recv_buf);
+ retval = recv(php_sock->socket, recv_buf, Z_LVAL_PP(arg2), Z_LVAL_PP(arg3));
+ if (retval == 0) {
efree(recv_buf);
-
- RETURN_LONG(ret);
+ RETURN_FALSE;
}
+
+ recv_buf[retval+1] = '\0';
+ RETURN_STRING(recv_buf, 0);
}
/* }}} */
-/* {{{ proto int send(int fd, string buf, int len, int flags)
+/* {{{ proto int socket_send(resource socket, string buf, int len, int flags)
Sends data to a connected socket */
-/* May be used with SOCK_DGRAM sockets. */
-PHP_FUNCTION(send)
+PHP_FUNCTION(socket_send)
{
- zval **fd, **buf, **len, **flags;
- int ret;
+ zval **arg1, **arg2, **arg3, **arg4;
+ php_socket *php_sock;
+ int retval;
- 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, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(3, fd, len, flags);
- convert_to_string_ex(buf);
- 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));
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(arg3);
+ convert_to_long_ex(arg4);
+ convert_to_string_ex(arg2);
+
+ retval = send(php_sock->socket, Z_STRVAL_PP(arg2), (Z_STRLEN_PP(arg2) < Z_LVAL_PP(arg3) ? Z_STRLEN_PP(arg2) : Z_LVAL_PP(arg3)), Z_LVAL_PP(arg4));
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_LONG(retval);
}
/* }}} */
-/* {{{ proto int recvfrom(int fd, string &buf, int len, int flags, string &name [, int &port])
+/* {{{ proto int socket_recvfrom(resource socket, string &buf, int len, int flags, string &name [, int &port])
Receives data from a socket, connected or not */
-PHP_FUNCTION(recvfrom)
+PHP_FUNCTION(socket_recvfrom)
{
- zval **fd, **buf, **len, **flags, **name, **port;
- int ret;
+ zval **arg1, **arg2, **arg3, **arg4, **arg5, **arg6;
php_sockaddr_storage sa_storage;
+ php_socket *php_sock;
struct sockaddr *sa = (struct sockaddr *) &sa_storage;
socklen_t salen;
+ int retval, argc = ZEND_NUM_ARGS();
- switch (ZEND_NUM_ARGS())
- {
- case 5:
- if (zend_get_parameters_ex(5, &fd, &buf, &len, &flags, &name) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- break;
+
+ if(argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ switch (argc) {
case 6:
- if (zend_get_parameters_ex(6, &fd, &buf, &len, &flags, &name, &port) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
+ convert_to_long_ex(arg6);
+ case 5:
+ convert_to_string_ex(arg5);
+ convert_to_long_ex(arg4);
+ convert_to_long_ex(arg3);
+ convert_to_string_ex(arg2);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
break;
- default:
- WRONG_PARAM_COUNT;
}
salen = sizeof(sa_storage);
-
- ret = getsockname(Z_LVAL_PP(fd), sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ if (getsockname(php_sock->socket, sa, &salen) != 0) {
+ php_error(E_WARNING, "unable to recvfrom, %i", errno);
+ RETURN_LONG(0);
}
- switch (sa->sa_family)
- {
+ switch (sa->sa_family) {
case AF_UNIX:
{
struct sockaddr_un s_un;
- char *recv_buf = emalloc(Z_LVAL_PP(len) + 2);
socklen_t sun_length = sizeof(s_un);
-
- if (ZEND_NUM_ARGS() != 5) {
- WRONG_PARAM_COUNT;
- }
- memset(recv_buf, 0, Z_LVAL_PP(len) + 2);
+ char *recv_buf = (char*)emalloc(Z_LVAL_PP(arg3) + 2);
- ret = recvfrom(Z_LVAL_PP(fd), recv_buf, Z_LVAL_PP(len), Z_LVAL_PP(flags),
- (struct sockaddr *)&s_un, (socklen_t *) & sun_length);
+ memset(recv_buf, 0, Z_LVAL_PP(arg3) + 2);
+ retval = recvfrom(php_sock->socket, recv_buf, Z_LVAL_PP(arg3), Z_LVAL_PP(arg4),
+ (struct sockaddr *)&s_un, (socklen_t *) & sun_length);
- if (ret < 0) {
+ if (retval < 0) {
efree(recv_buf);
- RETURN_LONG(-errno);
+ php_error(E_WARNING, "unable to recvfrom, %i", errno);
+ RETURN_FALSE;
}
-
- if (Z_STRVAL_PP(buf) != NULL) {
- efree(Z_STRVAL_PP(buf));
+
+ if (Z_STRVAL_PP(arg2) != NULL) {
+ efree(Z_STRVAL_PP(arg2));
}
- Z_STRVAL_PP(buf) = estrndup(recv_buf, strlen(recv_buf));
- Z_STRLEN_PP(buf) = strlen(recv_buf);
-
- if (Z_STRLEN_PP(name) > 0) {
- efree(Z_STRVAL_PP(name));
+ Z_STRVAL_PP(arg2) = estrndup(recv_buf, strlen(recv_buf));
+ Z_STRLEN_PP(arg2) = strlen(recv_buf);
+
+ if (Z_STRLEN_PP(arg5) > 0) {
+ efree(Z_STRVAL_PP(arg5));
}
- Z_STRVAL_PP(name) = estrdup(s_un.sun_path);
- Z_STRLEN_PP(name) = strlen(s_un.sun_path);
-
+ Z_STRVAL_PP(arg5) = estrdup(s_un.sun_path);
+ Z_STRLEN_PP(arg5) = strlen(s_un.sun_path);
efree(recv_buf);
-
- RETURN_LONG(ret);
}
- break;
+
+
case AF_INET:
{
struct sockaddr_in sin;
- char *recv_buf = emalloc(Z_LVAL_PP(len) + 2);
+ char *recv_buf = (char*)emalloc(Z_LVAL_PP(arg3) + 2);
socklen_t sin_length = sizeof(sin);
char *address;
- if (ZEND_NUM_ARGS() != 6) {
+ if (argc != 6) {
WRONG_PARAM_COUNT;
}
- memset(recv_buf, 0, Z_LVAL_PP(len) + 2);
-
- 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) {
+
+ memset(recv_buf, 0, Z_LVAL_PP(arg3) + 2);
+ retval = recvfrom(php_sock->socket, recv_buf, Z_LVAL_PP(arg3), Z_LVAL_PP(arg4),
+ (struct sockaddr *)&sin, (socklen_t *) & sin_length);
+
+ if (retval < 0) {
efree(recv_buf);
- RETURN_LONG(-errno);
+ php_error(E_WARNING, "unable to recvfrom, %i", errno);
+ RETURN_FALSE;
}
- if (Z_STRLEN_PP(buf) > 0) {
- efree(Z_STRVAL_PP(buf));
+ if (Z_STRLEN_PP(arg2) > 0) {
+ efree(Z_STRVAL_PP(arg2));
}
+
+ Z_STRVAL_PP(arg2) = estrdup(recv_buf);
+ Z_STRLEN_PP(arg2) = strlen(recv_buf);
- if (Z_STRLEN_PP(name) > 0) {
- efree(Z_STRVAL_PP(name));
+ if (Z_STRLEN_PP(arg5) > 0) {
+ efree(Z_STRVAL_PP(arg5));
}
- Z_STRVAL_PP(buf) = estrdup(recv_buf);
- Z_STRLEN_PP(buf) = strlen(recv_buf);
-
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));
+ Z_STRVAL_PP(arg5) = estrdup("0.0.0.0");
+ Z_STRLEN_PP(arg5) = strlen(Z_STRVAL_PP(arg5));
} else {
- Z_STRVAL_PP(name) = estrdup(address);
- Z_STRLEN_PP(name) = strlen(address);
+ Z_STRVAL_PP(arg5) = estrdup(address);
+ Z_STRLEN_PP(arg5) = strlen(address);
}
- Z_LVAL_PP(port) = ntohs(sin.sin_port);;
-
+ Z_LVAL_PP(arg6) = ntohs(sin.sin_port);
efree(recv_buf);
- RETURN_LONG(ret);
}
- break;
+
default:
- RETURN_LONG(-EPROTONOSUPPORT);
+ RETURN_FALSE;
}
+
+ RETURN_LONG(retval);
}
/* }}} */
-/* {{{ proto int sendto(int fd, string buf, int len, int flags, string addr [, int port])
+/* {{{ proto int socket_sendto(resource socket, string buf, int len, int flags, string addr [, int port])
Sends a message to a socket, whether it is connected or not */
-PHP_FUNCTION(sendto)
+PHP_FUNCTION(socket_sendto)
{
- zval **fd, **buf, **len, **flags, **addr, **port;
+ zval **arg1, **arg2, **arg3, **arg4, **arg5, **arg6;
php_sockaddr_storage sa_storage;
+ php_socket *php_sock;
struct sockaddr *sa = (struct sockaddr *) &sa_storage;
socklen_t salen = sizeof(sa_storage);
- int ret;
+ int retval, argc = ZEND_NUM_ARGS();
- 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) {
+ if(argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(3, fd, len, flags);
- convert_to_string_ex(buf);
- if (ZEND_NUM_ARGS() == 6) {
- convert_to_long_ex(port);
+ switch (argc) {
+ case 6:
+ convert_to_long_ex(arg6);
+ case 5:
+ convert_to_string_ex(arg5);
+ convert_to_long_ex(arg4);
+ convert_to_long_ex(arg3);
+ convert_to_string_ex(arg2);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ break;
}
- ret = getsockname(Z_LVAL_PP(fd), sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+
+ if (getsockname(php_sock->socket, sa, &salen) != 0) {
+ php_error(E_WARNING, "unable to sendto, %i", errno);
+ RETURN_LONG(0);
}
- switch (sa->sa_family)
- {
+ switch (sa->sa_family) {
case AF_UNIX:
{
struct sockaddr_un s_un;
-
- if (ZEND_NUM_ARGS() != 5) {
- WRONG_PARAM_COUNT;
- }
+ int which;
+
memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX;
- snprintf(s_un.sun_path, 108, "%s", Z_STRVAL_PP(addr));
- 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), (struct sockaddr *) &s_un, SUN_LEN(&s_un));
-
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ snprintf(s_un.sun_path, 108, "%s", Z_STRVAL_PP(arg5));
+
+ which = (Z_STRLEN_PP(arg2) > Z_LVAL_PP(arg3)) ? 1 : 0;
+ retval = sendto(php_sock->socket, Z_STRVAL_PP(arg2), (which ? Z_LVAL_PP(arg3) : Z_STRLEN_PP(arg2)),
+ Z_LVAL_PP(arg4), (struct sockaddr *) &s_un, SUN_LEN(&s_un));
}
- break;
+
case AF_INET:
{
struct sockaddr_in sin;
struct in_addr addr_buf;
+ int which;
- if (ZEND_NUM_ARGS() != 6) {
+ if (argc != 6) {
WRONG_PARAM_COUNT;
}
+
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- if (inet_aton(Z_STRVAL_PP(addr), &addr_buf) == 0) {
+ if (inet_aton(Z_STRVAL_PP(arg5), &addr_buf) == 0) {
sin.sin_addr.s_addr = addr_buf.s_addr;
} else {
struct hostent *he;
- he = gethostbyname(Z_STRVAL_PP(addr));
+ he = gethostbyname(Z_STRVAL_PP(arg4));
+
if (he == NULL) {
- RETURN_LONG(-(h_errno) - 10000);
+ php_error(E_WARNING, "unable to sendto, %i", h_errno);
+ RETURN_FALSE;
}
+
sin.sin_addr.s_addr = *(int *) (he->h_addr_list[0]);
}
- 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), (struct sockaddr *) &sin, sizeof(sin));
-
- RETURN_LONG(((ret < 0) ? -errno : ret));
+
+ sin.sin_port = htons((unsigned short)Z_LVAL_PP(arg6));
+ which = (Z_STRLEN_PP(arg2) > Z_LVAL_PP(arg3)) ? 1 : 0;
+ retval = sendto(php_sock->socket, Z_STRVAL_PP(arg2), (which ? Z_LVAL_PP(arg3) : Z_STRLEN_PP(arg2)),
+ Z_LVAL_PP(arg4), (struct sockaddr *) &sin, sizeof(sin));
}
- break;
+
default:
- RETURN_LONG(-EPROTONOSUPPORT);
- break;
+ RETURN_LONG(0);
}
+
+ RETURN_LONG(retval);
}
/* }}} */
-/* {{{ proto int recvmsg(int fd, resource iovec, array &control, int &controllen, int &flags, string &addr [, int &port])
+/* {{{ proto bool socket_recvmsg(resource socket, 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)
+PHP_FUNCTION(socket_recvmsg)
{
- zval **fd, **iovec, **control, **controllen, **flags, **addr, **port;
+ zval **arg1, **arg2, **arg3, **arg4, **arg5, **arg6, **arg7;
zval *control_array = NULL;
php_iovec_t *iov;
struct msghdr hdr;
php_sockaddr_storage sa_storage;
+ php_socket *php_sock;
struct sockaddr *sa = (struct sockaddr *) &sa_storage;
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
struct sockaddr_un *s_un = (struct sockaddr_un *) sa;
struct cmsghdr *ctl_buf;
socklen_t salen = sizeof(sa_storage);
- int ret;
-
- 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;
- }
+ int argc = ZEND_NUM_ARGS();
- if (ret == FAILURE) {
+ if(argc < 6 || argc > 7 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_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);
+ switch (argc) {
+ case 7:
+ convert_to_long_ex(arg7);
+ case 6:
+ convert_to_string_ex(arg6);
+ convert_to_long_ex(arg5);
+ convert_to_long_ex(arg4);
+ convert_to_array_ex(arg3);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(iov, php_iovec_t *, arg2, -1, "IO vector table", le_iov);
+ break;
}
- ZEND_FETCH_RESOURCE(iov, php_iovec_t *, iovec, -1, "IO vector table", le_iov);
-
- ret = getsockname(Z_LVAL_PP(fd), sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ if (getsockname(php_sock->socket, sa, &salen) != 0) {
+ php_error(E_WARNING, "unable to recvms, %i", errno);
+ RETURN_FALSE;
}
- if (Z_LVAL_PP(controllen) > sizeof(struct cmsghdr)) {
- ctl_buf = emalloc(Z_LVAL_PP(controllen));
- } else {
- ctl_buf = NULL;
- }
+ ctl_buf = (Z_LVAL_PP(arg4) > sizeof(struct cmsghdr)) ? (struct cmsghdr*)emalloc(Z_LVAL_PP(arg4)) : NULL;
+ MAKE_STD_ZVAL(control_array);
- switch (sa->sa_family)
- {
+ switch (sa->sa_family) {
case AF_INET:
- {
- if (ZEND_NUM_ARGS() != 7) {
- efree(ctl_buf);
- WRONG_PARAM_COUNT;
- }
- memset(sa, 0, sizeof(sa_storage));
- hdr.msg_name = sin;
- hdr.msg_namelen = sizeof(sa_storage);
- hdr.msg_iov = iov->iov_array;
- hdr.msg_iovlen = iov->count;
-
- if (ctl_buf) {
- hdr.msg_control = ctl_buf;
- hdr.msg_controllen = Z_LVAL_PP(controllen);
- } else {
- hdr.msg_control = NULL;
- hdr.msg_controllen = 0;
- }
-
- 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... */
- 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_STRLEN_PP(addr) > 0) {
- 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);
- }
- }
- break;
- case AF_UNIX:
- {
- if (ZEND_NUM_ARGS() != 6) {
+
+ if (ZEND_NUM_ARGS() != 7) {
efree(ctl_buf);
WRONG_PARAM_COUNT;
}
+
memset(sa, 0, sizeof(sa_storage));
- hdr.msg_name = s_un;
- hdr.msg_namelen = sizeof(struct sockaddr_un);
+ hdr.msg_name = sin;
+ hdr.msg_namelen = sizeof(sa_storage);
hdr.msg_iov = iov->iov_array;
hdr.msg_iovlen = iov->count;
- if (ctl_buf) {
- hdr.msg_control = ctl_buf;
- hdr.msg_controllen = Z_LVAL_PP(controllen);
- } else {
- hdr.msg_control = NULL;
- hdr.msg_controllen = 0;
- }
-
+ hdr.msg_control = ctl_buf ? ctl_buf : NULL;
+ hdr.msg_controllen = ctl_buf ? Z_LVAL_PP(arg4) : 0;
hdr.msg_flags = 0;
-
- ret = recvmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
- if (ret < 0) {
- RETURN_LONG(-errno);
+
+ if (recvmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg5)) != 0) {
+ php_error(E_WARNING, "unable to recvmsg, %i", errno);
+ RETURN_FALSE;
} else {
struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;
+
+ /* 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);
+ *arg3 = control_array;
+ zval_copy_ctor(*arg3);
+
+ Z_LVAL_PP(arg4) = hdr.msg_controllen;
+ Z_LVAL_PP(arg5) = hdr.msg_flags;
- if (mhdr != NULL) {
- /* copy values as appropriate... */
- if (array_init(control_array) == FAILURE) {
- php_error(E_WARNING, "Cannot initialize return value from recvmsg()");
- RETURN_FALSE;
+ if (Z_STRLEN_PP(arg6) > 0) {
+ efree(Z_STRVAL_PP(arg6));
+ }
+
+ {
+ char *tmp = inet_ntoa(sin->sin_addr);
+ if (tmp == NULL) {
+ Z_STRVAL_PP(arg6) = estrdup("0.0.0.0");
+ } else {
+ Z_STRVAL_PP(arg6) = estrdup(tmp);
}
- 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;
- 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));
+
+ Z_STRLEN_PP(arg6) = strlen(Z_STRVAL_PP(arg6));
+ Z_LVAL_PP(arg7) = ntohs(sin->sin_port);
+ RETURN_TRUE;
+ }
+
+ case AF_UNIX:
+ memset(sa, 0, sizeof(sa_storage));
+ hdr.msg_name = s_un;
+ hdr.msg_namelen = sizeof(struct sockaddr_un);
+ hdr.msg_iov = iov->iov_array;
+ hdr.msg_iovlen = iov->count;
+
+ if (ctl_buf) {
+ hdr.msg_control = ctl_buf;
+ hdr.msg_controllen = Z_LVAL_PP(arg4);
+ } else {
+ hdr.msg_control = NULL;
+ hdr.msg_controllen = 0;
+ }
+
+ hdr.msg_flags = 0;
+
+ if (recvmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg5)) != 0) {
+ php_error(E_WARNING, "unable to recvmsg, %i", errno);
+ RETURN_FALSE;
+ } else {
+ struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;
+
+ if (mhdr != NULL) {
+ /* copy values as appropriate... */
+ if (array_init(control_array) == FAILURE) {
+ php_error(E_WARNING, "Cannot initialize return value from recvmsg()");
+ RETURN_FALSE;
}
- Z_STRVAL_PP(addr) = estrdup(s_un->sun_path);
- RETURN_LONG(ret);
+
+ 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);
+ *arg3 = control_array;
+ Z_LVAL_PP(arg4) = hdr.msg_controllen;
+ }
+
+ Z_LVAL_PP(arg5) = hdr.msg_flags;
+
+ if (Z_STRVAL_PP(arg6) != NULL) {
+ efree(Z_STRVAL_PP(arg6));
}
+
+ Z_STRVAL_PP(arg6) = estrdup(s_un->sun_path);
+ RETURN_TRUE;
}
- break;
default:
- RETURN_LONG(-EPROTONOSUPPORT);
+ RETURN_FALSE;
}
}
/* }}} */
-/* {{{ proto int sendmsg(int fd, resource iovec, int flags, string addr [, int port])
+/* {{{ proto bool socket_sendmsg(resource socket, 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)
+PHP_FUNCTION(socket_sendmsg)
{
- zval **fd, **iovec, **flags, **addr, **port;
+ zval **arg1, **arg2, **arg3, **arg4, **arg5;
php_iovec_t *iov;
- int ret, argc = ZEND_NUM_ARGS();
+ php_socket *php_sock;
+ int argc = ZEND_NUM_ARGS();
struct sockaddr sa;
int salen;
- if (argc < 4 || argc > 5 ||
- zend_get_parameters_ex(argc, &fd, &iovec, &flags, &addr, &port) == FAILURE) {
+ if (argc < 4 || argc > 5 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3, &arg4, &arg5) == FAILURE) {
WRONG_PARAM_COUNT;
}
- salen = sizeof(sa);
- ret = getsockname(Z_LVAL_PP(fd), &sa, &salen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ switch (argc) {
+ case 5:
+ convert_to_long_ex(arg5);
+ case 4:
+ convert_to_string_ex(arg4);
+ convert_to_long_ex(arg3);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ ZEND_FETCH_RESOURCE(iov, php_iovec_t *, arg2, -1, "IO vector table", le_iov);
+ break;
}
- ZEND_FETCH_RESOURCE(iov, php_iovec_t *, iovec, -1, "IO vector table", le_iov);
+ salen = sizeof(sa);
+ if (getsockname(php_sock->socket, &sa, &salen) != 0) {
+ php_error(E_WARNING, "unable to sendmsg, %i", errno);
+ RETURN_FALSE;
+ }
- switch(sa.sa_family)
- {
+ switch(sa.sa_family) {
case AF_INET:
{
struct msghdr hdr;
struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
- h_errno = 0;
- errno = 0;
+
+ set_h_errno(0);
+ set_errno(0);
+
memset(&hdr, 0, sizeof(hdr));
hdr.msg_name = &sa;
hdr.msg_namelen = sizeof(sa);
hdr.msg_iov = iov->iov_array;
hdr.msg_iovlen = iov->count;
- if (inet_aton(Z_STRVAL_PP(addr), &sin->sin_addr) != 0) {
- struct hostent *he = gethostbyname(Z_STRVAL_PP(addr));
+ if (inet_aton(Z_STRVAL_PP(arg4), &sin->sin_addr) != 0) {
+ struct hostent *he = gethostbyname(Z_STRVAL_PP(arg4));
if (!he) {
- RETURN_LONG(h_errno > 0 ? -(h_errno) - 10000 : -errno)
+ php_error(E_WARNING, "unable to sendmsg, %i", h_errno);
+ RETURN_FALSE;
}
sin->sin_addr.s_addr = *(int *)(he->h_addr_list[0]);
}
- sin->sin_port = htons(Z_LVAL_PP(port));
- ret = sendmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
+ sin->sin_port = htons((unsigned short)Z_LVAL_PP(arg5));
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ if(sendmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg3)) != 0) {
+ php_error(E_WARNING, "unable to sendmsg, %i", errno);
+ }
+
+ RETURN_TRUE;
}
- break;
+
case AF_UNIX:
{
struct msghdr hdr;
struct sockaddr_un *s_un = (struct sockaddr_un *) &sa;
- errno = 0;
+
+ set_errno(0);
+
hdr.msg_name = s_un;
hdr.msg_iov = iov->iov_array;
hdr.msg_iovlen = iov->count;
- snprintf(s_un->sun_path, 108, "%s", Z_STRVAL_PP(addr));
+ snprintf(s_un->sun_path, 108, "%s", Z_STRVAL_PP(arg4));
hdr.msg_namelen = SUN_LEN(s_un);
- ret = sendmsg(Z_LVAL_PP(fd), &hdr, Z_LVAL_PP(flags));
+ if(sendmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg3)) != 0) {
+ php_error(E_WARNING, "unable to sendmsg, %i", errno);
+ RETURN_FALSE;
+ }
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_TRUE;
}
- break;
+
default:
- RETURN_LONG(-EPROTONOSUPPORT);
+ RETURN_FALSE;
}
}
/* }}} */
-/* {{{ proto int getsockopt(int fd, int level, int optname, array|int &optval)
+/* {{{ proto mixed socket_getopt(resource socket, int level, int optname)
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.
-*/
-PHP_FUNCTION(getsockopt)
+PHP_FUNCTION(socket_getopt)
{
- zval **fd, **level, **optname, **optval;
+ zval **arg1, **arg2, **arg3;
struct linger linger_val;
int other_val;
socklen_t optlen;
- int ret;
-
- fd = level = optname = optval = NULL;
+ php_socket *php_sock;
- if (ZEND_NUM_ARGS() != 4 ||
- zend_get_parameters_ex(4, &fd, &level, &optname, &optval) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(3, fd, level, optname);
- /* optname is set on the way out .. */
-
- if (Z_LVAL_PP(level) == SO_LINGER) {
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(arg2);
+ convert_to_long_ex(arg3);
+
+ if (Z_LVAL_PP(arg2) == SO_LINGER) {
zval *optval_array = NULL;
optlen = sizeof(struct linger);
- ret = getsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &linger_val, &optlen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+ if (getsockopt(php_sock->socket, Z_LVAL_PP(arg2), Z_LVAL_PP(arg3), (char*)&linger_val, &optlen) != 0) {
+ php_error(E_WARNING, "unable to retrieve socket option, %i", errno);
+ RETURN_FALSE;
}
- if (array_init(optval_array) == FAILURE) {
- php_error(E_WARNING, "Cannot initialize array from getsockopt()");
+ if (array_init(return_value) == FAILURE) {
RETURN_FALSE;
}
- add_assoc_long(optval_array, "l_onoff", linger_val.l_onoff);
- add_assoc_long(optval_array, "l_linger", linger_val.l_linger);
+ add_assoc_long(return_value, "l_onoff", linger_val.l_onoff);
+ add_assoc_long(return_value, "l_linger", linger_val.l_linger);
- *optval = optval_array;
- RETURN_LONG(ret);
} else {
optlen = sizeof(other_val);
- ret = getsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &other_val, &optlen);
- if (ret < 0) {
- RETURN_LONG(-errno);
+
+ if (getsockopt(php_sock->socket, Z_LVAL_PP(arg2), Z_LVAL_PP(arg3), (char*)&other_val, &optlen) != 0) {
+ php_error(E_WARNING, "unable to retrieve socket option, %i", errno);
+ RETURN_FALSE;
}
- Z_LVAL_PP(optval) = other_val;
- RETURN_LONG(ret);
+ RETURN_LONG(other_val);
}
}
/* }}} */
-/* {{{ proto int setsockopt(int fd, int level, int optname, int|array optval)
+/* {{{ proto bool socket_setopt(resource socket, 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. */
-PHP_FUNCTION(setsockopt)
+PHP_FUNCTION(socket_setopt)
{
- zval **fd, **level, **optname, **optval;
- int ret;
+ zval **arg1, **arg2, **arg3, **arg4;
struct linger lv;
- int ov;
- int optlen;
- errno = 0;
+ int ov, optlen, retval;
+ php_socket *php_sock;
- 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, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
WRONG_PARAM_COUNT;
}
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
+ convert_to_long_ex(arg2);
+ convert_to_long_ex(arg3);
- multi_convert_to_long_ex(3, fd, level, optname);
+ set_errno(0);
- if (Z_LVAL_PP(optname) == SO_LINGER) {
+ if (Z_LVAL_PP(arg3) == SO_LINGER) {
HashTable *ht;
zval **l_onoff;
zval **l_linger;
- convert_to_array_ex(optval);
- ht = HASH_OF(*optval);
+ convert_to_array_ex(arg4);
+ ht = HASH_OF(*arg4);
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) {
+ if (zend_hash_find(ht, "l_linger", strlen("l_linger") + 1, (void **)&l_linger) == FAILURE) {
php_error(E_WARNING, "No key \"l_linger\" passed in optval");
RETURN_FALSE;
}
@@ -2014,98 +1864,128 @@ PHP_FUNCTION(setsockopt)
convert_to_long_ex(l_onoff);
convert_to_long_ex(l_linger);
- lv.l_onoff = Z_LVAL_PP(l_onoff);
- lv.l_linger = Z_LVAL_PP(l_linger);
+ lv.l_onoff = (unsigned short)Z_LVAL_PP(l_onoff);
+ lv.l_linger = (unsigned short)Z_LVAL_PP(l_linger);
optlen = sizeof(lv);
- ret = setsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &lv, optlen);
+
+ retval = setsockopt(php_sock->socket, Z_LVAL_PP(arg2), Z_LVAL_PP(arg3), (char*)&lv, optlen);
+
} else {
- convert_to_long_ex(optval);
+ convert_to_long_ex(arg4);
optlen = sizeof(ov);
- ov = Z_LVAL_PP(optval);
+ ov = Z_LVAL_PP(arg3);
+
+ retval = setsockopt(php_sock->socket, Z_LVAL_PP(arg2), Z_LVAL_PP(arg3), (char*)&ov, optlen);
+ }
- ret = setsockopt(Z_LVAL_PP(fd), Z_LVAL_PP(level), Z_LVAL_PP(optname), &ov, optlen);
+ if(retval != 0) {
+ php_error(E_WARNING, "unable to set socket option, %i", errno);
+ RETURN_FALSE;
}
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int socketpair(int domain, int type, int protocol, array &fds)
+/* {{{ proto bool socket_create_pair(int domain, int type, int protocol, array &fd)
Creates a pair of indistinguishable sockets and stores them in fds. */
-PHP_FUNCTION(socketpair)
+PHP_FUNCTION(socket_create_pair)
{
- zval **domain, **type, **protocol, **fds;
- int ret, fds_ar[2];
+ zval **arg1, **arg2, **arg3, **arg4;
+ zval *retval[2];
+ php_socket *php_sock[2];
+
+#ifndef PHP_WIN32
+ int fds_array[2];
+#else
+ SOCKET fds_array[2];
+#endif
- if (ZEND_NUM_ARGS() != 4 ||
- zend_get_parameters_ex(4, &domain, &type, &protocol, &fds) == FAILURE) {
+ if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
WRONG_PARAM_COUNT;
}
- multi_convert_to_long_ex(3, domain, type, protocol);
+
+ convert_to_long_ex(arg1);
+ convert_to_long_ex(arg2);
+ convert_to_long_ex(arg3);
+ convert_to_array_ex(arg4);
+
+ php_sock[0]= (php_socket*)emalloc(sizeof(php_socket));
+ php_sock[1]= (php_socket*)emalloc(sizeof(php_socket));
- 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(arg1) != AF_INET && Z_LVAL_PP(arg2) != AF_UNIX) {
+ php_error(E_WARNING, "invalid socket domain specified, assuming AF_INET");
+ Z_LVAL_PP(arg1) = 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;
+ if (Z_LVAL_PP(arg2) > 10) {
+ php_error(E_WARNING, "Invalid socket type specified, assuming SOCK_STREAM");
+ Z_LVAL_PP(arg2) = SOCK_STREAM;
}
- /* Initialize the array */
- if (array_init(*fds) == FAILURE) {
+ if (array_init(*arg4) == FAILURE) {
php_error(E_WARNING, "Can't initialize fds array");
RETURN_FALSE;
}
-
- /* Get the sockets */
- ret = socketpair(Z_LVAL_PP(domain), Z_LVAL_PP(type), Z_LVAL_PP(protocol), fds_ar);
-
- if (ret < 0) {
- RETURN_LONG(-errno);
+
+ if (socketpair(Z_LVAL_PP(arg1), Z_LVAL_PP(arg2), Z_LVAL_PP(arg3), fds_array) != 0) {
+ php_error(E_WARNING, "unable to create socket pair, %i", errno);
+ RETURN_FALSE;
}
- /* Put them into the array */
- add_index_long(*fds, 0, fds_ar[0]);
- add_index_long(*fds, 1, fds_ar[1]);
+ MAKE_STD_ZVAL(retval[0]);
+ MAKE_STD_ZVAL(retval[1]);
+
+ php_sock[0]->socket = fds_array[0];
+ php_sock[1]->socket = fds_array[1];
+ php_sock[0]->type = Z_LVAL_PP(arg1);
+ php_sock[1]->type = Z_LVAL_PP(arg1);
+
+ ZEND_REGISTER_RESOURCE(retval[0], php_sock[0], le_socket);
+ ZEND_REGISTER_RESOURCE(retval[1], php_sock[1], le_socket);
- /* ... and return */
- RETURN_LONG(ret);
+ add_index_zval(*arg4, 0, retval[0]);
+ add_index_zval(*arg4, 1, retval[1]);
+
+ RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int shutdown(int fd, int how)
+/* {{{ proto bool socket_shutdown(resource socket[, int how])
Shuts down a socket for receiving, sending, or both. */
-PHP_FUNCTION(shutdown)
+PHP_FUNCTION(socket_shutdown)
{
- zval **fd, **how;
- int how_shutdown = 0, argc = ZEND_NUM_ARGS(), ret;
+ zval **arg1, **arg2;
+ int how_shutdown = 0, argc = ZEND_NUM_ARGS();
+ php_socket *php_sock;
- if (argc < 1 || argc > 2 ||
- zend_get_parameters_ex(argc, &fd, &how) == FAILURE) {
+ if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(fd);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, "Socket", le_socket);
if (argc > 1) {
- convert_to_long_ex(how);
- how_shutdown = Z_LVAL_PP(how);
+ convert_to_long_ex(arg2);
+ how_shutdown = Z_LVAL_PP(arg2);
}
- ret = shutdown(Z_LVAL_PP(fd), how_shutdown);
+ if(shutdown(php_sock->socket, how_shutdown) != 0) {
+ php_error(E_WARNING, "unable to shutdown socket, %i", errno);
+ RETURN_FALSE;
+ }
- RETURN_LONG(((ret < 0) ? -errno : ret));
+ RETURN_TRUE;
}
/* }}} */
-#endif /* HAVE_SOCKETS */
+#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
- */
+ */ \ No newline at end of file
diff --git a/ext/sockets/sockets.dsp b/ext/sockets/sockets.dsp
new file mode 100644
index 0000000000..a909c8daea
--- /dev/null
+++ b/ext/sockets/sockets.dsp
@@ -0,0 +1,116 @@
+# Microsoft Developer Studio Project File - Name="sockets" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=sockets - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SOCKETS.MAK".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SOCKETS.MAK" CFG="sockets - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "sockets - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "sockets - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "sockets - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOCKETS_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /D "WIN32" /D "PHP_EXPORTS" /D "COMPILE_DL_SOCKETS" /D ZTS=1 /D HAVE_SOCKETS=1 /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 php4ts.lib Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_sockets.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+
+!ELSEIF "$(CFG)" == "sockets - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOCKETS_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PHP_EXPORTS" /D "COMPILE_DL_SOCKETS" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SOCKETS=1 /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 php4ts_debug.lib Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_sockets.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "sockets - Win32 Release_TS"
+# Name "sockets - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\php_sockets_win.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sockets.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_sockets.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_sockets_win.h
+# End Source File
+# End Group
+# End Target
+# End Project