From e228b16885d1a5b42fd50611e3e914bd406dbf3c Mon Sep 17 00:00:00 2001 From: Jason Greene Date: Wed, 6 Mar 2002 05:21:56 +0000 Subject: [PATCH] Socket Rework Patch 2 Redesigned socket_recv() as outlined on php-dev Modified socket_last_error() to no longer clear the error Added socket_clear_error() Fixed socket_set_nonblock() Added socket_set_block() Fixed a proto Saved 1 byte of RAM : ) --- ext/sockets/php_sockets.h | 2 + ext/sockets/sockets.c | 105 ++++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index df8a6785cb..5d2f71ba5a 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -59,6 +59,7 @@ PHP_FUNCTION(socket_create_listen); PHP_FUNCTION(socket_create_pair); PHP_FUNCTION(socket_accept); PHP_FUNCTION(socket_set_nonblock); +PHP_FUNCTION(socket_set_block); PHP_FUNCTION(socket_listen); PHP_FUNCTION(socket_close); PHP_FUNCTION(socket_write); @@ -81,6 +82,7 @@ PHP_FUNCTION(socket_getopt); PHP_FUNCTION(socket_setopt); PHP_FUNCTION(socket_shutdown); PHP_FUNCTION(socket_last_error); +PHP_FUNCTION(socket_clear_error); typedef struct php_iovec { struct iovec *iov_array; diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index c506e0de61..b0094bdcd6 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -129,6 +129,7 @@ function_entry sockets_functions[] = { PHP_FE(socket_create_pair, NULL) 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) @@ -138,7 +139,7 @@ function_entry sockets_functions[] = { PHP_FE(socket_connect, NULL) PHP_FE(socket_strerror, NULL) PHP_FE(socket_bind, NULL) - PHP_FE(socket_recv, NULL) + PHP_FE(socket_recv, second_arg_force_ref) PHP_FE(socket_send, NULL) PHP_FE(socket_recvfrom, second_fifth_and_sixth_args_force_ref) PHP_FE(socket_sendto, NULL) @@ -150,6 +151,7 @@ function_entry sockets_functions[] = { PHP_FE(socket_setopt, NULL) PHP_FE(socket_shutdown, NULL) PHP_FE(socket_last_error, NULL) + PHP_FE(socket_clear_error, NULL) {NULL, NULL, NULL} }; /* }}} */ @@ -676,18 +678,56 @@ PHP_FUNCTION(socket_accept) /* }}} */ /* {{{ proto bool socket_set_nonblock(resource socket) - Sets nonblocking mode for file descriptor fd */ + Sets nonblocking mode on a socket resource */ PHP_FUNCTION(socket_set_nonblock) { zval *arg1; php_socket *php_sock; - + int flags; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) return; ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); + + flags=fcntl(php_sock->bsd_socket, F_GETFL); + + /* Safely append non blocking to other flags unless the get fails. + * Note: This does not abort on failure becuse getfl will always fail + * under the current win32 code. */ + if (flags > -1) flags |= O_NONBLOCK; + else flags=O_NONBLOCK; + + if (fcntl(php_sock->bsd_socket, F_SETFL, flags) > -1) { + RETURN_TRUE; + } - if (fcntl(php_sock->bsd_socket, F_SETFL, O_NONBLOCK) == 0) { + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto bool socket_set_block(resource socket) + Sets blocking mode on a socket resource */ +PHP_FUNCTION(socket_set_block) +{ + zval *arg1; + php_socket *php_sock; + int flags; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) + return; + + ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); + + flags=fcntl(php_sock->bsd_socket, F_GETFL); + + /* Safely remove blocking from flags unless the get fails. + * Note: This does not abort on failure becuse getfl will always fail + * under the current win32 code. */ + if (flags > -1) flags &= ~O_NONBLOCK; + else flags=0; + + if (fcntl(php_sock->bsd_socket, F_SETFL, flags) > -1) { RETURN_TRUE; } @@ -1298,30 +1338,42 @@ PHP_FUNCTION(socket_writev) } /* }}} */ -/* {{{ proto string socket_recv(resource socket, int len, int flags) +/* {{{ proto int socket_recv(resource socket, string &buf, int len, int flags) Receives data from a connected socket */ PHP_FUNCTION(socket_recv) { - zval *arg1; + zval *php_sock_res, *buf; char *recv_buf; php_socket *php_sock; int retval, len, flags; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &arg1, &len, &flags) == FAILURE) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzll", &php_sock_res, &buf, &len, &flags) == FAILURE) return; - ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); + ZEND_FETCH_RESOURCE(php_sock, php_socket *, &php_sock_res, -1, le_socket_name, le_socket); - recv_buf = emalloc(len + 2); - memset(recv_buf, 0, len + 2); + recv_buf = emalloc(len + 1); + memset(recv_buf, 0, len + 1); - if ((retval = recv(php_sock->bsd_socket, recv_buf, len, flags)) == 0) { + if ((retval = recv(php_sock->bsd_socket, recv_buf, len, flags)) < 1) { + if (retval == -1) PHP_SOCKET_ERROR(php_sock, "unable to read from socket", errno); + efree(recv_buf); - RETURN_FALSE; + + zval_dtor(buf); + Z_TYPE_P(buf)=IS_NULL; + } else { + recv_buf[retval+1] = '\0'; + + /* Rebuild buffer zval */ + zval_dtor(buf); + + Z_STRVAL_P(buf)=recv_buf; + Z_STRLEN_P(buf)=retval; + Z_TYPE_P(buf)=IS_STRING; } - recv_buf[retval+1] = '\0'; - RETURN_STRING(recv_buf, 0); + RETURN_LONG(retval); } /* }}} */ @@ -1930,7 +1982,7 @@ PHP_FUNCTION(socket_shutdown) /* }}} */ /* {{{ proto int socket_last_error(resource socket) - Returns/Clears the last error on the socket */ + Returns the last error on the socket */ PHP_FUNCTION(socket_last_error) { zval *arg1; @@ -1943,11 +1995,30 @@ PHP_FUNCTION(socket_last_error) ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket); error = php_sock->error; - php_sock->error = 0; RETURN_LONG(error); -} +} +/* }}} */ + +/* {{{ proto void socket_clear_error(resource socket) + Clears the error on the socket */ +PHP_FUNCTION(socket_clear_error) +{ + zval *arg1; + php_socket *php_sock; + int error; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) + return; + + ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, le_socket); + + php_sock->error=0; + + return; +} /* }}} */ + #endif /* -- 2.50.1