com php-src: Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport: ext/pcre/ php_pcre.c ext/pgsql/pgsql.c
ext/pgsql/php_pgsql. h ext/standard/url.c sapi/phpdbg/phpdbg.c

From: Date: Tue, 18 Mar 2014 13:03:25 +0000
Subject: com php-src: Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport: ext/pcre/ php_pcre.c ext/pgsql/pgsql.c
ext/pgsql/php_pgsql. h ext/standard/url.c sapi/phpdbg/phpdbg.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-76518@lists.php.net to get a copy of this message
Commit: ed70f02b290034b1685bc33e1e5e3cbf10bfec27 Author: Anatol Belski <ab@php.net> Tue, 18 Mar 2014 14:03:25 +0100 Parents: 1ad45a3741fa7d4909f36d4f90f510a38ec69889 6c259625c45f4a4137b53a9e3a06677f7c3236ed Branches: str_size_and_int64_56_backport Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=ed70f02b290034b1685bc33e1e5e3cbf10bfec27 Log: Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport * origin/PHP-5.6: Fixed wrong indentation Fix phpdbg build on FreeBSD Fixed off-by-one in php_url_parse_ex Fixed typo in UPGRADING and modified php.ini-* description for encoding related changes Add support for PCRE marks Update UPGRADING. Add more descriptions about default_charset and encoding related changes. Many thanks to Christopher. UPGRADING (openssl updates) Support async pgsql connections and non-blocking queries Conflicts: ext/pcre/php_pcre.c ext/pgsql/pgsql.c Changed paths: MM ext/pcre/php_pcre.c MM ext/pgsql/pgsql.c MM ext/pgsql/php_pgsql.h MM ext/standard/url.c MM sapi/phpdbg/phpdbg.c

diff --cc ext/pcre/php_pcre.c index 9f13609,52d43ce..187d70e --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@@ -607,17 -577,9 +607,19 @@@ PHPAPI void php_pcre_match_impl(pcre_ca int i, rc; int subpats_order; /* Order of subpattern matches */ int offset_capture; /* Capture match offsets: yes/no */ + unsigned char *mark = NULL; /* Target for MARK name */ + zval *marks = NULL; /* Array of marks for PREG_PATTERN_ORDER */ + if (subject_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Subject is too long"); + RETURN_FALSE; + } + + if (start_offset > INT_MAX-1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Start offset is too big"); + RETURN_FALSE; + } + /* Overwrite the passed-in value for subpatterns with an empty array. */ if (subpats != NULL) { zval_dtor(subpats); @@@ -895,7 -881,7 +921,7 @@@ static int preg_get_backref(char **str /* {{{ preg_do_repl_func */ - static php_size_t preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, char **result TSRMLS_DC) -static int preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, unsigned char *mark, char **result TSRMLS_DC) ++static php_size_t preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, unsigned char *mark, char **result TSRMLS_DC) { zval *retval_ptr; /* Function return value */ zval **args[1]; /* Argument to pass to function */ @@@ -1072,12 -1061,8 +1101,13 @@@ PHPAPI char *php_pcre_replace_impl(pcre *eval_result, /* Result of eval or custom function */ walk_last; /* Last walked character */ int rc; + unsigned char *mark = NULL; /* Target for MARK name */ + if (subject_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Subject is too long"); + return NULL; + } + if (extra == NULL) { extra_data.flags = PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra = &extra_data; diff --cc ext/pgsql/pgsql.c index a7c5605,f5e142a..63ca471 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@@ -1098,21 -1114,34 +1118,34 @@@ PHP_MINIT_FUNCTION(pgsql REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", PG_VERSION_STR, CONST_CS | CONST_PERSISTENT); #endif /* For connection option */ - REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_CS | CONST_PERSISTENT); /* For pg_fetch_array() */ - REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT); /* For pg_connection_status() */ - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_STARTED", CONNECTION_STARTED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_MADE", CONNECTION_MADE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AUTH_OK", CONNECTION_AUTH_OK, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SETENV", CONNECTION_SETENV, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECTION_STARTED", CONNECTION_STARTED, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECTION_MADE", CONNECTION_MADE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECTION_AUTH_OK", CONNECTION_AUTH_OK, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_CONNECTION_SETENV", CONNECTION_SETENV, CONST_CS | CONST_PERSISTENT); + /* For pg_connect_poll() */ - REGISTER_LONG_CONSTANT("PGSQL_POLLING_FAILED", PGRES_POLLING_FAILED, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_POLLING_READING", PGRES_POLLING_READING, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_POLLING_WRITING", PGRES_POLLING_WRITING, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_POLLING_OK", PGRES_POLLING_OK, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_POLLING_ACTIVE", PGRES_POLLING_ACTIVE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_POLLING_FAILED", PGRES_POLLING_FAILED, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_POLLING_READING", PGRES_POLLING_READING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_POLLING_WRITING", PGRES_POLLING_WRITING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_POLLING_OK", PGRES_POLLING_OK, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("PGSQL_POLLING_ACTIVE", PGRES_POLLING_ACTIVE, CONST_CS | CONST_PERSISTENT); #if HAVE_PGTRANSACTIONSTATUS /* For pg_transaction_status() */ - REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_IDLE", PQTRANS_IDLE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_ACTIVE", PQTRANS_ACTIVE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INTRANS", PQTRANS_INTRANS, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INERROR", PQTRANS_INERROR, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_UNKNOWN", PQTRANS_UNKNOWN, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_TRANSACTION_IDLE", PQTRANS_IDLE, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_TRANSACTION_ACTIVE", PQTRANS_ACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_TRANSACTION_INTRANS", PQTRANS_INTRANS, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_TRANSACTION_INERROR", PQTRANS_INERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("PGSQL_TRANSACTION_UNKNOWN", PQTRANS_UNKNOWN, CONST_CS | CONST_PERSISTENT); #endif #if HAVE_PQSETERRORVERBOSITY /* For pg_set_error_verbosity() */ @@@ -1403,20 -1431,38 +1436,38 @@@ static void php_pgsql_do_connect(INTERN } } if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", PGG(num_links)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%pd)", PGG(num_links)); goto err; } - if (connstring) { - pgsql = PQconnectdb(connstring); + + /* Non-blocking connect */ + if (connect_type & PGSQL_CONNECT_ASYNC) { + if (connstring) { + pgsql = PQconnectStart(connstring); + if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { + PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql); + if (pgsql) { + PQfinish(pgsql); + } + goto err; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection string required for async connections"); + goto err; + } } else { - pgsql = PQsetdb(host,port,options,tty,dbname); - } - if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { - PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql); - if (pgsql) { - PQfinish(pgsql); + if (connstring) { + pgsql = PQconnectdb(connstring); + } else { + pgsql = PQsetdb(host,port,options,tty,dbname); + } + if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { + PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql); + if (pgsql) { + PQfinish(pgsql); + } + goto err; } - goto err; } /* add it to the list */ @@@ -1468,6 -1514,31 +1519,31 @@@ PHP_FUNCTION(pg_connect } /* }}} */ + /* {{{ proto resource pg_connect_poll(resource connection) + Poll the status of an in-progress async PostgreSQL connection attempt*/ + PHP_FUNCTION(pg_connect_poll) + { + zval *pgsql_link; + int id = -1; + PGconn *pgsql; + int ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + return; + } + + if (pgsql_link == NULL && id == -1) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + + ret = PQconnectPoll(pgsql); + - RETURN_LONG(ret); ++ RETURN_INT(ret); + } + /* }}} */ + /* {{{ proto resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database) Open a persistent PostgreSQL connection */ PHP_FUNCTION(pg_pconnect) @@@ -4760,15 -4816,13 +4846,13 @@@ PHP_FUNCTION(pg_send_query { zval *pgsql_link; char *query; - int len; - int id = -1; + php_size_t len; + php_int_t id = -1; PGconn *pgsql; - PGresult *res; - int leftover = 0; + int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rS", - &pgsql_link, &query, &len) == FAILURE) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &len) == FAILURE) { ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rS", &pgsql_link, &query, &len) == FAILURE) { return; } @@@ -4792,19 -4844,38 +4874,38 @@@ if (!PQsendQuery(pgsql, query)) { RETURN_FALSE; } - } - /* Wait to finish sending buffer */ - while ((ret = PQflush(pgsql))) { - if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); - break; + ret = PQflush(pgsql); + } else { + if (!PQsendQuery(pgsql, query)) { + if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { + PQreset(pgsql); + } + if (!PQsendQuery(pgsql, query)) { + RETURN_FALSE; + } + } + + /* Wait to finish sending buffer */ + while ((ret = PQflush(pgsql))) { + if (ret == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + break; + } + usleep(10000); + } + + if (PQ_SETNONBLOCKING(pgsql, 0)) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); } - usleep(10000); } - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + + if (ret == 0) { + RETURN_TRUE; + } else if (ret == -1) { + RETURN_FALSE; + } else { - RETURN_LONG(0); ++ RETURN_INT(0); } - RETURN_TRUE; } /* }}} */ @@@ -4817,14 -4888,12 +4918,13 @@@ PHP_FUNCTION(pg_send_query_params int num_params = 0; char **params = NULL; char *query; - int query_len, id = -1; + php_size_t query_len; + php_int_t id = -1; PGconn *pgsql; - PGresult *res; - int leftover = 0; + int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa/", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rSa/", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { return; } @@@ -4888,19 -4962,31 +4993,31 @@@ RETURN_FALSE; } } - _php_pgsql_free_params(params, num_params); - /* Wait to finish sending buffer */ - while ((ret = PQflush(pgsql))) { - if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); - break; + + if (is_non_blocking) { + ret = PQflush(pgsql); + } else { + /* Wait to finish sending buffer */ + while ((ret = PQflush(pgsql))) { + if (ret == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + break; + } + usleep(10000); + } + + if (PQ_SETNONBLOCKING(pgsql, 0) != 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); } - usleep(10000); } - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + + if (ret == 0) { + RETURN_TRUE; + } else if (ret == -1) { + RETURN_FALSE; + } else { - RETURN_LONG(0); ++ RETURN_INT(0); } - RETURN_TRUE; } /* }}} */ #endif @@@ -4912,14 -4998,12 +5029,13 @@@ PHP_FUNCTION(pg_send_prepare { zval *pgsql_link; char *query, *stmtname; - int stmtname_len, query_len, id = -1; + php_size_t stmtname_len, query_len; + php_int_t id = -1; PGconn *pgsql; - PGresult *res; - int leftover = 0; + int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rSS", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { return; } @@@ -4933,33 -5019,48 +5051,48 @@@ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); RETURN_FALSE; } - while ((res = PQgetResult(pgsql))) { - PQclear(res); - leftover = 1; - } - if (leftover) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There are results on this connection. Call pg_get_result() until it returns FALSE"); + + if (_php_pgsql_link_has_results(pgsql)) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, + "There are results on this connection. Call pg_get_result() until it returns FALSE"); } + if (!PQsendPrepare(pgsql, stmtname, query, 0, NULL)) { - if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { - PQreset(pgsql); - } - if (!PQsendPrepare(pgsql, stmtname, query, 0, NULL)) { + if (is_non_blocking) { RETURN_FALSE; + } else { + if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { + PQreset(pgsql); + } + if (!PQsendPrepare(pgsql, stmtname, query, 0, NULL)) { + RETURN_FALSE; + } } } - /* Wait to finish sending buffer */ - while ((ret = PQflush(pgsql))) { - if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty postgres send buffer"); - break; + + if (is_non_blocking) { + ret = PQflush(pgsql); + } else { + /* Wait to finish sending buffer */ + while ((ret = PQflush(pgsql))) { + if (ret == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + break; + } + usleep(10000); + } + if (PQ_SETNONBLOCKING(pgsql, 0) != 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); } - usleep(10000); } - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + + if (ret == 0) { + RETURN_TRUE; + } else if (ret == -1) { + RETURN_FALSE; + } else { - RETURN_LONG(0); ++ RETURN_INT(0); } - RETURN_TRUE; } /* }}} */ #endif @@@ -4974,14 -5075,12 +5107,13 @@@ PHP_FUNCTION(pg_send_execute int num_params = 0; char **params = NULL; char *stmtname; - int stmtname_len, id = -1; + php_size_t stmtname_len; + php_int_t id = -1; PGconn *pgsql; - PGresult *res; - int leftover = 0; + int is_non_blocking; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rSa", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { return; } @@@ -5045,19 -5149,30 +5182,30 @@@ RETURN_FALSE; } } - _php_pgsql_free_params(params, num_params); - /* Wait to finish sending buffer */ - while ((ret = PQflush(pgsql))) { - if (ret == -1) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty postgres send buffer"); - break; + + if (is_non_blocking) { + ret = PQflush(pgsql); + } else { + /* Wait to finish sending buffer */ + while ((ret = PQflush(pgsql))) { + if (ret == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not empty PostgreSQL send buffer"); + break; + } + usleep(10000); + } + if (PQ_SETNONBLOCKING(pgsql, 0) != 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); } - usleep(10000); } - if (PQ_SETNONBLOCKING(pgsql, 0)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode"); + + if (ret == 0) { + RETURN_TRUE; + } else if (ret == -1) { + RETURN_FALSE; + } else { - RETURN_LONG(0); ++ RETURN_INT(0); } - RETURN_TRUE; } /* }}} */ #endif @@@ -5202,6 -5317,141 +5350,141 @@@ PHP_FUNCTION(pg_get_pid } /* }}} */ + static size_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) + { + return 0; + } + + static size_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) + { + return 0; + } + + static int php_pgsql_fd_close(php_stream *stream, int close_handle TSRMLS_DC) + { + return EOF; + } + + static int php_pgsql_fd_flush(php_stream *stream TSRMLS_DC) + { + return FAILURE; + } + + static int php_pgsql_fd_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) + { + PGconn *pgsql = (PGconn *) stream->abstract; + switch (option) { + case PHP_STREAM_OPTION_BLOCKING: + return PQ_SETNONBLOCKING(pgsql, value); + default: + return FAILURE; + } + } + + static int php_pgsql_fd_cast(php_stream *stream, int cast_as, void **ret TSRMLS_DC) + { + PGconn *pgsql = (PGconn *) stream->abstract; + int fd_number; + + switch (cast_as) { + case PHP_STREAM_AS_FD_FOR_SELECT: + case PHP_STREAM_AS_FD: + case PHP_STREAM_AS_SOCKETD: + if (ret) { + fd_number = PQsocket(pgsql); + if (fd_number == -1) { + return FAILURE; + } + + *(php_socket_t *)ret = fd_number; + return SUCCESS; + } + default: + return FAILURE; + } + } + + /* {{{ proto resource pg_socket(resource) + Get a read-only handle to the socket underlying the pgsql connection */ + PHP_FUNCTION(pg_socket) + { + zval *pgsql_link; + php_stream *stream; + PGconn *pgsql; + int id = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + + stream = php_stream_alloc(&php_stream_pgsql_fd_ops, pgsql, NULL, "r"); + + if (stream) { + php_stream_to_zval(stream, return_value); + return; + } + + RETURN_FALSE; + } + /* }}} */ + + /* {{{ proto bool pg_consume_input(resource) + Reads input on the connection */ + PHP_FUNCTION(pg_consume_input) + { + zval *pgsql_link; + int id = -1; + PGconn *pgsql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + + RETURN_BOOL(PQconsumeInput(pgsql)); + } + /* }}} */ + + /* {{{ proto mixed pg_flush(resource) + Flush outbound query data on the connection */ + PHP_FUNCTION(pg_flush) + { + zval *pgsql_link; + int id = -1; + PGconn *pgsql; + int ret; + int is_non_blocking; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + + is_non_blocking = PQisnonblocking(pgsql); + + if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 1) == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); + RETURN_FALSE; + } + + ret = PQflush(pgsql); + + if (is_non_blocking == 0 && PQ_SETNONBLOCKING(pgsql, 0) == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed resetting connection to blocking mode"); + } + + switch (ret) { + case 0: RETURN_TRUE; break; - case 1: RETURN_LONG(0); break; ++ case 1: RETURN_INT(0); break; + default: RETURN_FALSE; + } + } + /* }}} */ + /* {{{ php_pgsql_meta_data * TODO: Add meta_data cache for better performance */ diff --cc ext/pgsql/php_pgsql.h index 26b72d1,62f20da..9bcbec5 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@@ -284,12 -296,24 +296,24 @@@ typedef struct _php_pgsql_notice size_t len; } php_pgsql_notice; + static php_stream_ops php_stream_pgsql_fd_ops = { + php_pgsql_fd_write, + php_pgsql_fd_read, + php_pgsql_fd_close, + php_pgsql_fd_flush, + "PostgreSQL link", + NULL, /* seek */ + php_pgsql_fd_cast, /* cast */ + NULL, /* stat */ + php_pgsql_fd_set_option + }; + ZEND_BEGIN_MODULE_GLOBALS(pgsql) - long default_link; /* default link when connection is omitted */ - long num_links,num_persistent; - long max_links,max_persistent; - long allow_persistent; - long auto_reset_persistent; + php_int_t default_link; /* default link when connection is omitted */ + php_int_t num_links,num_persistent; + php_int_t max_links,max_persistent; + php_int_t allow_persistent; + php_int_t auto_reset_persistent; int le_lofp,le_string; int ignore_notices,log_notices; HashTable notices; /* notice message for each connection */
« previous php.cvs (#76518) next »