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

📄 sockets.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct sockaddr_in		*sin = (struct sockaddr_in *) sa;	struct sockaddr_un		*s_un = (struct sockaddr_un *) sa;	socklen_t				salen = sizeof(sa_storage);	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrzzzz|z", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7) == FAILURE)		return;	if(Z_LVAL_P(arg4)<0) RETURN_FALSE;	ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);	ZEND_FETCH_RESOURCE(iov, php_iovec_t *, &arg2, -1, le_iov_name, le_iov);	if (getsockname(php_sock->bsd_socket, sa, &salen) != 0) {		PHP_SOCKET_ERROR(php_sock, "unable to receive message", errno);		RETURN_FALSE;	}		ctl_buf = (Z_LVAL_P(arg4) > sizeof(struct cmsghdr)) ? (struct cmsghdr*)emalloc(Z_LVAL_P(arg4)) : NULL;	switch (sa->sa_family) {		case AF_INET:						if (arg7 == NULL) {				efree(ctl_buf);				WRONG_PARAM_COUNT;			}						memset(sa, 0, sizeof(sa_storage));			hdr.msg_name	= (void *) sin;			hdr.msg_namelen	= sizeof(sa_storage);			hdr.msg_iov		= iov->iov_array;			hdr.msg_iovlen	= iov->count;			hdr.msg_control = ctl_buf ? (void *) ctl_buf : NULL;			hdr.msg_controllen = ctl_buf ? Z_LVAL_P(arg4) : 0;#ifndef MISSING_MSGHDR_MSGFLAGS			hdr.msg_flags	= 0;#endif			if (recvmsg(php_sock->bsd_socket, &hdr, Z_LVAL_P(arg5)) < 0) {				PHP_SOCKET_ERROR(php_sock, "unable to receive message", errno);				RETURN_FALSE;			} else {				struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;								zval_dtor(arg3);				zval_dtor(arg4);				zval_dtor(arg5);				zval_dtor(arg6);				zval_dtor(arg7);								ZVAL_LONG(arg4, hdr.msg_controllen);#ifndef MISSING_MSGHDR_MSGFLAGS				ZVAL_LONG(arg5, hdr.msg_flags);#endif				ZVAL_LONG(arg7, ntohs(sin->sin_port));								if (array_init(arg3) == FAILURE) {					php_error(E_WARNING, "%s() cannot intialize array", get_active_function_name(TSRMLS_C));					RETURN_FALSE;				}								if (mhdr != NULL) {					add_assoc_long(arg3,	"cmsg_level",	mhdr->cmsg_level);					add_assoc_long(arg3,	"cmsg_type",	mhdr->cmsg_type);					add_assoc_string(arg3,	"cmsg_data",	CMSG_DATA(mhdr), 1);				}								{					char *tmp = inet_ntoa(sin->sin_addr);					if (tmp == NULL) {						ZVAL_STRING(arg6, "0.0.0.0", 1);					} else {						ZVAL_STRING(arg6, tmp, 1);					}				}								RETURN_TRUE;			}	case AF_UNIX:		memset(sa, 0, sizeof(sa_storage));		hdr.msg_name	= (void *) 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 = (void *) ctl_buf;			hdr.msg_controllen = Z_LVAL_P(arg4);		} else {			hdr.msg_control = NULL;			hdr.msg_controllen = 0;		}#ifndef MISSING_MSGHDR_MSGFLAGS				hdr.msg_flags = 0;#endif 				if (recvmsg(php_sock->bsd_socket, &hdr, Z_LVAL_P(arg5)) != 0) {			PHP_SOCKET_ERROR(php_sock, "unable to receive message", errno);			RETURN_FALSE;		} else {			struct cmsghdr *mhdr = (struct cmsghdr *) hdr.msg_control;						if (mhdr != NULL) {								zval_dtor(arg3);				zval_dtor(arg4);				zval_dtor(arg5);				zval_dtor(arg6);								ZVAL_LONG(arg4, hdr.msg_controllen);#ifndef MISSING_MSGHDR_MSGFLAGS				ZVAL_LONG(arg5, hdr.msg_flags);#endif								if (array_init(arg3) == FAILURE) {					php_error(E_WARNING, "%s() cannot initialize return value", get_active_function_name(TSRMLS_C));					RETURN_FALSE;				}								add_assoc_long(arg3, "cmsg_level", mhdr->cmsg_level);				add_assoc_long(arg3, "cmsg_type", mhdr->cmsg_type);				add_assoc_string(arg3, "cmsg_data", CMSG_DATA(mhdr), 1);			}									ZVAL_STRING(arg6, s_un->sun_path, 1);			RETURN_TRUE;		}			default:		php_error(E_WARNING, "%s() Unsupported address family %d",				  get_active_function_name(TSRMLS_C), sa->sa_family);		RETURN_FALSE;	}}#endif/* }}} *//* {{{ 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(socket_sendmsg){	zval			*arg1, *arg2;	php_iovec_t		*iov;	php_socket		*php_sock;	struct sockaddr	sa;	char			*addr;	socklen_t		salen;	int				addr_len;	long				flags, port;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrls|l", &arg1, &arg2, &flags, &addr, &addr_len, &port) == FAILURE)		return;	ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);	ZEND_FETCH_RESOURCE(iov, php_iovec_t *, &arg2, -1, le_iov_name, le_iov);	salen = sizeof(sa);	if (getsockname(php_sock->bsd_socket, &sa, &salen) != 0) {		PHP_SOCKET_ERROR(php_sock, "unable to send messge", errno);		RETURN_FALSE;	}	switch(sa.sa_family) {		case AF_INET:			{				struct msghdr hdr;				struct sockaddr_in *sin = (struct sockaddr_in *) &sa;								SET_H_ERRNO(0);				set_errno(0);								memset(&hdr, 0, sizeof(hdr));				hdr.msg_name = (void *) &sa;				hdr.msg_namelen = sizeof(sa);				hdr.msg_iov = iov->iov_array;				hdr.msg_iovlen = iov->count;								memset(sin, 0, sizeof(sa));								sin->sin_family = AF_INET;				sin->sin_port = htons((unsigned short)port);								if (! php_set_inet_addr(sin, addr, php_sock TSRMLS_CC)) {					RETURN_FALSE;				}								if (sendmsg(php_sock->bsd_socket, &hdr, flags) == -1) {					PHP_SOCKET_ERROR(php_sock, "unable to send message", errno);				}								RETURN_TRUE;			}					case AF_UNIX:			{				struct msghdr hdr;				struct sockaddr_un *s_un = (struct sockaddr_un *) &sa;								set_errno(0);								hdr.msg_name = (void *) s_un;				hdr.msg_iov = iov->iov_array;				hdr.msg_iovlen = iov->count;								snprintf(s_un->sun_path, 108, "%s", addr);								hdr.msg_namelen = SUN_LEN(s_un);								if (sendmsg(php_sock->bsd_socket, &hdr, flags) == -1) {					PHP_SOCKET_ERROR(php_sock, "unable to send message", errno);					RETURN_FALSE;				}								RETURN_TRUE;			}		default:			php_error(E_WARNING, "%s() Unsupported address family %d",					  get_active_function_name(TSRMLS_C), sa.sa_family);			RETURN_FALSE;	}}/* }}} *//* {{{ proto mixed socket_get_option(resource socket, int level, int optname)   Gets socket options for the socket */PHP_FUNCTION(socket_get_option){	zval			*arg1;	struct linger	linger_val;	struct timeval		tv;	int				timeout = 0;	socklen_t		optlen;	php_socket		*php_sock;	int				other_val;	long				level, optname;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &arg1, &level, &optname) == FAILURE)		return;	ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);		switch(optname) {		case SO_LINGER: 			optlen = sizeof(linger_val);			if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&linger_val, &optlen) != 0) {				PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);				RETURN_FALSE;			}			if (array_init(return_value) == FAILURE) {				RETURN_FALSE;			}			add_assoc_long(return_value, "l_onoff", linger_val.l_onoff);			add_assoc_long(return_value, "l_linger", linger_val.l_linger);	     			break; 		case SO_RCVTIMEO:		case SO_SNDTIMEO:#ifndef PHP_WIN32			optlen = sizeof(tv);			if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&tv, &optlen) != 0) {				PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);				RETURN_FALSE;			}#else			optlen = sizeof(int);						if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&timeout, &optlen) != 0) {				PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);				RETURN_FALSE;			}						tv.tv_sec = timeout ? timeout / 1000 : 0;			tv.tv_usec = timeout ? (timeout * 1000) % 1000000 : 0;#endif			if (array_init(return_value) == FAILURE) {				RETURN_FALSE;			}						add_assoc_long(return_value, "sec", tv.tv_sec);			add_assoc_long(return_value, "usec", tv.tv_usec);						break;		default:			optlen = sizeof(other_val);						if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {				PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);				RETURN_FALSE;			}			RETURN_LONG(other_val);			break;	}}/* }}} *//* {{{ proto bool socket_set_option(resource socket, int level, int optname, int|array optval)   Sets socket options for the socket */PHP_FUNCTION(socket_set_option){	zval			*arg1, *arg4;	struct linger	lv;	struct timeval tv;	php_socket		*php_sock;	int				ov, optlen, retval, timeout;	long				level, optname;	void 			*opt_ptr;		HashTable 		*opt_ht;	zval 			**l_onoff, **l_linger;	zval 			**sec, **usec;		/* key name constants */     	char			*l_onoff_key = "l_onoff";	char			*l_linger_key = "l_linger";	char			*sec_key = "sec";	char			*usec_key = "usec";	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllz", &arg1, &level, &optname, &arg4) == FAILURE)		return;	ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);	set_errno(0);	switch (optname) {		case SO_LINGER:			convert_to_array_ex(&arg4);			opt_ht = HASH_OF(arg4);			if (zend_hash_find(opt_ht, l_onoff_key, strlen(l_onoff_key) + 1, (void **)&l_onoff) == FAILURE) {				php_error(E_WARNING, "%s() no key \"%s\" passed in optval", get_active_function_name(TSRMLS_C), l_onoff_key);				RETURN_FALSE;			}			if (zend_hash_find(opt_ht, l_linger_key, strlen(l_linger_key) + 1, (void **)&l_linger) == FAILURE) {				php_error(E_WARNING, "%s() no key \"%s\" passed in optval", get_active_function_name(TSRMLS_C), l_linger_key);				RETURN_FALSE;			}			convert_to_long_ex(l_onoff);			convert_to_long_ex(l_linger);			lv.l_onoff = (unsigned short)Z_LVAL_PP(l_onoff);			lv.l_linger = (unsigned short)Z_LVAL_PP(l_linger);			optlen = sizeof(lv);			opt_ptr = &lv;			break;		case SO_RCVTIMEO:		case SO_SNDTIMEO:			convert_to_array_ex(&arg4);			opt_ht = HASH_OF(arg4);			if (zend_hash_find(opt_ht, sec_key, strlen(sec_key) + 1, (void **)&sec) == FAILURE) {				php_error(E_WARNING, "%s() no key \"%s\" passed in optval", get_active_function_name(TSRMLS_C), sec_key);				RETURN_FALSE;			}			if (zend_hash_find(opt_ht, usec_key, strlen(usec_key) + 1, (void **)&usec) == FAILURE) {				php_error(E_WARNING, "%s() no key \"%s\" passed in optval", get_active_function_name(TSRMLS_C), usec_key);				RETURN_FALSE;			}						convert_to_long_ex(sec);			convert_to_long_ex(usec);#ifndef PHP_WIN32			tv.tv_sec = Z_LVAL_PP(sec);			tv.tv_usec = Z_LVAL_PP(usec);			optlen = sizeof(tv);			opt_ptr = &tv;#else			timeout = Z_LVAL_PP(sec) * 1000 + Z_LVAL_PP(usec) / 1000;			optlen = sizeof(int);			opt_ptr = &timeout;#endif			break;		default:			convert_to_long_ex(&arg4);			ov = Z_LVAL_P(arg4);						optlen = sizeof(ov);			opt_ptr = &ov;			break;	}	retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen);		if (retval != 0) {		PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);		RETURN_FALSE;	}	RETURN_TRUE;}/* }}} *//* {{{ proto bool socket_create_pair(int domain, int type, int protocol, array &fd)   Creates a pair of indistinguishable sockets and stores them in fds. */PHP_FUNCTION(socket_create_pair){	zval		*retval[2], *fds_array_zval;	php_socket	*php_sock[2];	SOCKET		fds_array[2];	long			domain, type, protocol;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lllz", &domain, &type, &protocol, &fds_array_zval) == FAILURE)		return;	php_sock[0] = (php_socket*)emalloc(sizeof(php_socket));	php_sock[1] = (php_socket*)emalloc(sizeof(php_socket));	if (domain != AF_INET && domain != AF_UNIX) {		php_error(E_WARNING, "%s() invalid socket domain [%ld] specified for argument 1, assuming AF_INET", get_active_function_name(TSRMLS_C), domain);		domain = AF_INET;	}		if (type > 10) {		php_error(E_WARNING, "%s() invalid socket type [%ld] specified for argument 2, assuming SOCK_STREAM", get_active_function_name(TSRMLS_C), type);		type = SOCK_STREAM;	}		if (socketpair(domain, type, protocol, fds_array) != 0) {		SOCKETS_G(last_error) = errno;		php_error(E_WARNING, "%s() unable to create socket pair [%d]: %s", get_active_function_name(TSRMLS_C), errno, php_strerror(errno TSRMLS_CC));		efree(php_sock[0]);		efree(php_sock[1]);		RETURN_FALSE;	}	zval_dtor(fds_array_zval);	if (array_init(fds_array_zval) == FAILURE) {		php_error(E_WARNING, "%s() can't initialize array for 4th argument", get_active_function_name(TSRMLS_C));		efree(php_sock[0]);		efree(php_sock[1]);		RETURN_FALSE;	}	MAKE_STD_ZVAL(retval[0]);	MAKE_STD_ZVAL(retval[1]);	php_sock[0]->bsd_socket = fds_array[0];	php_sock[1]->bsd_socket = fds_array[1];	php_sock[0]->type		= domain;	php_sock[1]->type		= domain;	php_sock[0]->error		= 0;	php_sock[1]->error		= 0;	ZEND_REGISTER_RESOURCE(retval[0], php_sock[0], le_socket);	ZEND_REGISTER_RESOURCE(retval[1], php_sock[1], le_socket);	add_index_zval(fds_array_zval, 0, retval[0]);	add_index_zval(fds_array_zval, 1, retval[1]);	RETURN_TRUE;}/* }}} *//* {{{ proto bool socket_shutdown(resource socket[, int how])   Shuts down a socket for receiving, sending, or both. */PHP_FUNCTION(socket_shutdown){	zval		*arg1;	long			how_shutdown = 2;	php_socket	*php_sock;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &how_shutdown) == FAILURE)		return;	ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket);		if (shutdown(php_sock->bsd_socket, how_shutdown) != 0) {		PHP_SOCKET_ERROR(php_sock, "unable to shutdown socket", errno);		RETURN_FALSE;	}		RETURN_TRUE;}/* }}} *//* {{{ proto int socket_last_error([resource socket])   Returns the last socket error (either the last used or the provided socket resource) */PHP_FUNCTION(socket_last_error){	zval		*arg1 = NULL;	php_socket	*php_sock;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg1) == FAILURE)		return;	if (arg1) {		ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket);		RETVAL_LONG(php_sock->error);	} else {		RETVAL_LONG(SOCKETS_G(last_error));	}}/* }}} *//* {{{ proto void socket_clear_error([resource socket])   Clears the error on the socket or the last error code. */PHP_FUNCTION(socket_clear_error){	zval		*arg1 = NULL;	php_socket	*php_sock;	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg1) == FAILURE)		return;	if (arg1) {		ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket);		php_sock->error = 0;	} else {		SOCKETS_G(last_error) = 0;	}	return;}  /* }}} */   #endif/* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */

⌨️ 快捷键说明

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