⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockets.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*   +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.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>                         |   |          Jason Greene     <jason@php.net>                            |   | WinSock: Daniel Beulshausen <daniel@php4win.de>                      |   +----------------------------------------------------------------------+ *//* $Id: sockets.c,v 1.125.2.29.2.7 2007/01/01 09:46:47 sebastian Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#if HAVE_SOCKETS#ifndef _XOPEN_SOURCE_EXTENDED#define _XOPEN_SOURCE_EXTENDED#endif#define _XPG4_2#define __EXTENSIONS__#include "php_network.h"#include "ext/standard/info.h"#include "php_ini.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->bsd_socket < 0)# define set_errno(a) (errno = a)# ifdef HAVE_SET_H_ERRNO#  define SET_H_ERRNO(newval) set_h_errno(newval)# else#  define SET_H_ERRNO(newval) h_errno = (newval)# endif#else /* windows */# include "php_sockets.h"# include "php_sockets_win.h"# define IS_INVALID_SOCKET(a)	(a->bsd_socket == INVALID_SOCKET)#endifZEND_DECLARE_MODULE_GLOBALS(sockets)#ifndef MSG_WAITALL#ifdef LINUX#define MSG_WAITALL 0x00000100#else#define MSG_WAITALL 0x00000000#endif#endif#ifndef SUN_LEN#define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))#endif#ifndef PF_INET#define PF_INET AF_INET#endifstatic char *php_strerror(int error TSRMLS_DC);#define PHP_NORMAL_READ 0x0001#define PHP_BINARY_READ 0x0002#define PHP_SOCKET_ERROR(socket,msg,errn)	socket->error = errn;	\											SOCKETS_G(last_error) = errn; \											php_error(E_WARNING, "%s() %s [%d]: %s", \													  get_active_function_name(TSRMLS_C), msg, errn, php_strerror(errn TSRMLS_CC))static int le_iov;#define le_iov_name "Socket I/O vector"static int le_socket;#define le_socket_name "Socket"static unsigned char first_through_third_args_force_ref[] ={3, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE};static unsigned char second_and_third_args_force_ref[] ={3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE};static unsigned char second_arg_of_four_force_ref[] ={4, BYREF_NONE, BYREF_FORCE, BYREF_NONE, BYREF_NONE};static unsigned char fourth_arg_force_ref[] ={4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE};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 third_through_seventh_args_force_ref[] ={7, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE};/* {{{ sockets_functions[] */function_entry sockets_functions[] = {	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,			first_through_third_args_force_ref)	PHP_FE(socket_create,			NULL)	PHP_FE(socket_create_listen,	NULL)	PHP_FE(socket_create_pair,		fourth_arg_force_ref)	PHP_FE(socket_accept,			NULL)	PHP_FE(socket_set_nonblock,		NULL)	PHP_FE(socket_set_block,		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,				second_arg_of_four_force_ref)	PHP_FE(socket_send,				NULL)	PHP_FE(socket_recvfrom,			second_fifth_and_sixth_args_force_ref)	PHP_FE(socket_sendto,			NULL)#ifdef HAVE_CMSGHDR	PHP_FE(socket_recvmsg,			third_through_seventh_args_force_ref)#endif	PHP_FE(socket_sendmsg,			NULL)	PHP_FE(socket_readv,			NULL)	PHP_FE(socket_writev,			NULL)	PHP_FE(socket_get_option,		NULL)	PHP_FE(socket_set_option,		NULL)	PHP_FE(socket_shutdown,			NULL)	PHP_FE(socket_last_error,		NULL)	PHP_FE(socket_clear_error,		NULL)		/* for downwards compatability */	PHP_FALIAS(socket_getopt, socket_get_option, NULL)	PHP_FALIAS(socket_setopt, socket_set_option, NULL)		{NULL, NULL, NULL}};/* }}} */zend_module_entry sockets_module_entry = {	STANDARD_MODULE_HEADER,	"sockets",	sockets_functions,	PHP_MINIT(sockets),	NULL,	PHP_RINIT(sockets),	PHP_RSHUTDOWN(sockets),	PHP_MINFO(sockets),	NO_VERSION_YET,	STANDARD_MODULE_PROPERTIES};#ifdef COMPILE_DL_SOCKETSZEND_GET_MODULE(sockets)#endif/* inet_ntop should be used instead of inet_ntoa */int inet_ntoa_lock = 0;static void php_destroy_iovec(zend_rsrc_list_entry *rsrc TSRMLS_DC){	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++) {			efree(iov->iov_array[i].iov_base);		}		efree(iov->iov_array);		efree(iov);	}}static void php_destroy_socket(zend_rsrc_list_entry *rsrc TSRMLS_DC){	php_socket *php_sock = (php_socket *) rsrc->ptr;	close(php_sock->bsd_socket);	efree(php_sock);}static int php_open_listen_sock(php_socket **php_sock, int port, int backlog TSRMLS_DC){	struct sockaddr_in  la;	struct hostent		*hp;	php_socket			*sock = (php_socket*)emalloc(sizeof(php_socket));	*php_sock = sock;#ifndef PHP_WIN32	if ((hp = gethostbyname("0.0.0.0")) == NULL) {#else	if ((hp = gethostbyname("localhost")) == NULL) {#endif		efree(sock);		return 0;	}		memcpy((char *) &la.sin_addr, hp->h_addr, hp->h_length);	la.sin_family = hp->h_addrtype;	la.sin_port = htons((unsigned short) port);	sock->bsd_socket = socket(PF_INET, SOCK_STREAM, 0);	if (IS_INVALID_SOCKET(sock)) {		PHP_SOCKET_ERROR(sock, "unable to create listening socket", errno);		efree(sock);		return 0;	}	sock->type = PF_INET;	if (bind(sock->bsd_socket, (struct sockaddr *)&la, sizeof(la)) < 0) {		PHP_SOCKET_ERROR(sock, "unable to bind to given adress", errno);		close(sock->bsd_socket);		efree(sock);		return 0;	}	if (listen(sock->bsd_socket, backlog) < 0) {		PHP_SOCKET_ERROR(sock, "unable to listen on socket", errno);		close(sock->bsd_socket);		efree(sock);		return 0;	}	return 1;}static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct sockaddr *la TSRMLS_DC){	socklen_t	salen;	php_socket	*out_sock = (php_socket*)emalloc(sizeof(php_socket));		*new_sock = out_sock;	salen = sizeof(*la);	out_sock->bsd_socket = accept(in_sock->bsd_socket, la, &salen);	if (IS_INVALID_SOCKET(out_sock)) {		PHP_SOCKET_ERROR(out_sock, "unable to accept incoming connection", errno);		efree(out_sock);		return 0;	}		return 1;}/* {{{ php_read -- wrapper around read() so that it only reads to a \r or \n. */static int php_read(int bsd_socket, void *buf, size_t maxlen, int flags){	int m = 0;	size_t n = 0;	int no_read = 0;	int nonblock = 0;	char *t = (char *) buf;	m = fcntl(bsd_socket, F_GETFL);	if (m < 0) {		return m;	}	nonblock = (m & O_NONBLOCK);	m = 0;	set_errno(0);	*t = '\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 = recv(bsd_socket, (void *) t, 1, flags);		}		 		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;}/* }}} */static char *php_strerror(int error TSRMLS_DC){	const char *buf;#ifndef PHP_WIN32	if (error < -10000) {		error = -error - 10000;#ifdef HAVE_HSTRERROR		buf = hstrerror(error);#else		{			if (SOCKETS_G(strerror_buf)) {				efree(SOCKETS_G(strerror_buf));			}			spprintf(&(SOCKETS_G(strerror_buf)), 0, "Host lookup error %d", error);			buf = SOCKETS_G(strerror_buf);		}#endif	} else {		buf = strerror(error);	}#else 	{		LPTSTR tmp = NULL;		buf = NULL;		if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |	FORMAT_MESSAGE_IGNORE_INSERTS,				  NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &tmp, 0, NULL)) {						if (SOCKETS_G(strerror_buf)) {				efree(SOCKETS_G(strerror_buf));			}			SOCKETS_G(strerror_buf) = estrdup(tmp);			LocalFree(tmp);					buf = SOCKETS_G(strerror_buf);		}	}#endif		return (buf ? (char *) buf : "");}/* Sets addr by hostname, or by ip in string form (AF_INET)  */static int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock TSRMLS_DC){	struct in_addr tmp;	struct hostent *host_entry;	if (inet_aton(string, &tmp)) {		sin->sin_addr.s_addr = tmp.s_addr;	} else {		if (! (host_entry = gethostbyname(string))) {			/* Note: < -10000 indicates a host lookup error */#ifdef PHP_WIN32			PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());#else			PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));#endif			return 0;		}		if (host_entry->h_addrtype != AF_INET) {			php_error(E_WARNING, "%s() Host lookup failed: Non AF_INET domain returned on AF_INET socket", get_active_function_name(TSRMLS_C));			return 0;		}		memcpy(&(sin->sin_addr.s_addr), host_entry->h_addr_list[0], host_entry->h_length);	}	return 1;}static void php_sockets_init_globals(zend_sockets_globals *sockets_globals TSRMLS_DC){	sockets_globals->last_error = 0;	sockets_globals->strerror_buf = NULL;}/* {{{ PHP_MINIT_FUNCTION */PHP_MINIT_FUNCTION(sockets){	struct protoent *pe;	ZEND_INIT_MODULE_GLOBALS(sockets, php_sockets_init_globals, NULL);	le_socket = zend_register_list_destructors_ex(php_destroy_socket, NULL, le_socket_name, module_number);	le_iov    = zend_register_list_destructors_ex(php_destroy_iovec,  NULL, le_iov_name,    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("SOMAXCONN",		SOMAXCONN,		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);#ifndef WIN32# include "unix_socket_constants.h"#else# include "win32_socket_constants.h"#endif	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 */PHP_MINFO_FUNCTION(sockets){	php_info_print_table_start();	php_info_print_table_row(2, "Sockets Support", "enabled");	php_info_print_table_end();}/* }}} *//* {{{ PHP_RINIT_FUNCTION */PHP_RINIT_FUNCTION(sockets){	return SUCCESS;}/* }}} *//* {{{ PHP_RSHUTDOWN_FUNCTION */PHP_RSHUTDOWN_FUNCTION(sockets){	if (SOCKETS_G(strerror_buf)) {		efree(SOCKETS_G(strerror_buf));		SOCKETS_G(strerror_buf) = NULL;	}	return SUCCESS;}/* }}} */		int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, SOCKET *max_fd TSRMLS_DC) {	zval		**element;	php_socket	*php_sock;	int			num = 0;		if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0;	for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(sock_array));		 zend_hash_get_current_data(Z_ARRVAL_P(sock_array), (void **) &element) == SUCCESS;		 zend_hash_move_forward(Z_ARRVAL_P(sock_array))) {		php_sock = (php_socket*) zend_fetch_resource(element TSRMLS_CC, -1, le_socket_name, NULL, 1, le_socket);		if (!php_sock) continue; /* If element is not a resource, skip it */		FD_SET(php_sock->bsd_socket, fds);		if (php_sock->bsd_socket > *max_fd) {			*max_fd = php_sock->bsd_socket;		}		num++;	}	return num ? 1 : 0;}int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) {	zval		**element;	zval		**dest_element;	php_socket	*php_sock;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -