From f23da140a9ae823c38be495e67078378c0879cec Mon Sep 17 00:00:00 2001 From: chiyou Date: Thu, 12 Feb 2015 13:35:36 +0800 Subject: [PATCH] php7 support --- packagers/json.c | 16 +- packagers/msgpack.c | 16 +- packagers/php.c | 12 +- php_yar.h | 2 +- transports/curl.c | 237 ++++++++++++--------- transports/socket.c | 76 +++---- yar.c | 10 +- yar_client.c | 503 ++++++++++++++++++++++---------------------- yar_client.h | 4 + yar_exception.c | 48 ++--- yar_exception.h | 4 +- yar_packager.c | 32 +-- yar_packager.h | 14 +- yar_protocol.c | 6 +- yar_protocol.h | 4 +- yar_request.c | 84 ++++---- yar_request.h | 10 +- yar_response.c | 106 +++++----- yar_response.h | 23 +- yar_server.c | 381 +++++++++++++-------------------- yar_transport.c | 22 +- yar_transport.h | 32 +-- yar_transports.h | 8 +- 23 files changed, 791 insertions(+), 859 deletions(-) diff --git a/packagers/json.c b/packagers/json.c index 1cee81f..1c6ecf5 100644 --- a/packagers/json.c +++ b/packagers/json.c @@ -28,26 +28,22 @@ #include "ext/json/php_json.h" #include "yar_packager.h" -int php_yar_packager_json_pack(yar_packager_t *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC) /* {{{ */ { +int php_yar_packager_json_pack(yar_packager_t *self, zval *pzval, smart_str *buf, char **msg) /* {{{ */ { #if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3)) - php_json_encode(buf, pzval TSRMLS_CC); + php_json_encode(buf, pzval); #else - php_json_encode(buf, pzval, 0 TSRMLS_CC); /* options */ + php_json_encode(buf, pzval, 0); /* options */ #endif return 1; } /* }}} */ -zval * php_yar_packager_json_unpack(yar_packager_t *self, char *content, size_t len, char **msg TSRMLS_DC) /* {{{ */ { +zval * php_yar_packager_json_unpack(yar_packager_t *self, char *content, size_t len, char **msg, zval *rret) /* {{{ */ { zval *return_value; - MAKE_STD_ZVAL(return_value); -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3)) - php_json_decode(return_value, content, len, 1 TSRMLS_CC); -#else - php_json_decode(return_value, content, len, 1, 512 TSRMLS_CC); -#endif + php_json_decode(rret, content, len, 1, 512); + return_value = rret; return return_value; } /* }}} */ diff --git a/packagers/msgpack.c b/packagers/msgpack.c index 13a90ee..3ff8f25 100644 --- a/packagers/msgpack.c +++ b/packagers/msgpack.c @@ -29,19 +29,19 @@ #include "php_yar.h" #include "yar_packager.h" -extern void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC); -extern void php_msgpack_unserialize(zval *return_value, char *str, size_t str_len TSRMLS_DC); +extern void php_msgpack_serialize(smart_str *buf, zval *val); +extern void php_msgpack_unserialize(zval *return_value, char *str, size_t str_len); -int php_yar_packager_msgpack_pack(yar_packager_t *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC) /* {{{ */ { - php_msgpack_serialize(buf, pzval TSRMLS_CC); +int php_yar_packager_msgpack_pack(yar_packager_t *self, zval *pzval, smart_str *buf, char **msg) /* {{{ */ { + php_msgpack_serialize(buf, pzval); return 1; } /* }}} */ -zval * php_yar_packager_msgpack_unpack(yar_packager_t *self, char *content, size_t len, char **msg TSRMLS_DC) /* {{{ */ { +zval * php_yar_packager_msgpack_unpack(yar_packager_t *self, char *content, size_t len, char **msg, zval *rret) /* {{{ */ { zval *return_value; - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - php_msgpack_unserialize(return_value, content, len TSRMLS_CC); + ZVAL_NULL(rret); + php_msgpack_unserialize(rret, content, len); + return_value = rret; return return_value; } /* }}} */ diff --git a/packagers/php.c b/packagers/php.c index 5eb5916..7d1f159 100644 --- a/packagers/php.c +++ b/packagers/php.c @@ -28,32 +28,32 @@ #include "yar_packager.h" #include "ext/standard/php_var.h" /* for serialize */ -int php_yar_packager_php_pack(yar_packager_t *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC) /* {{{ */ { +int php_yar_packager_php_pack(yar_packager_t *self, zval *pzval, smart_str *buf, char **msg) /* {{{ */ { php_serialize_data_t var_hash; PHP_VAR_SERIALIZE_INIT(var_hash); - php_var_serialize(buf, &pzval, &var_hash TSRMLS_CC); + php_var_serialize(buf, pzval, &var_hash); PHP_VAR_SERIALIZE_DESTROY(var_hash); return 1; } /* }}} */ -zval * php_yar_packager_php_unpack(yar_packager_t *self, char *content, size_t len, char **msg TSRMLS_DC) /* {{{ */ { +zval * php_yar_packager_php_unpack(yar_packager_t *self, char *content, size_t len, char **msg, zval *rret) /* {{{ */ { zval *return_value; const unsigned char *p; php_unserialize_data_t var_hash; p = (const unsigned char*)content; - MAKE_STD_ZVAL(return_value); PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (!php_var_unserialize(&return_value, &p, p + len, &var_hash TSRMLS_CC)) { - zval_ptr_dtor(&return_value); + if (!php_var_unserialize(rret, &p, p + len, &var_hash)) { + zval_ptr_dtor(rret); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); spprintf(msg, 0, "unpack error at offset %ld of %ld bytes", (long)((char*)p - content), len); return NULL; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + return_value = rret; return return_value; } /* }}} */ diff --git a/php_yar.h b/php_yar.h index d3f8c45..816d61e 100644 --- a/php_yar.h +++ b/php_yar.h @@ -37,7 +37,7 @@ extern zend_module_entry yar_module_entry; #include "TSRM.h" #endif -#define PHP_YAR_VERSION "1.2.2-dev" +#define PHP_YAR_VERSION "1.2.5-dev" PHP_MINIT_FUNCTION(yar); PHP_MSHUTDOWN_FUNCTION(yar); diff --git a/transports/curl.c b/transports/curl.c index 5cf208c..917fe65 100644 --- a/transports/curl.c +++ b/transports/curl.c @@ -32,7 +32,6 @@ #include "yar_packager.h" #include "yar_exception.h" #include "ext/standard/php_var.h" /* for serialize */ -#include "ext/standard/php_smart_str.h" /* for smart string */ #include "ext/standard/url.h" /* for php_url */ #include @@ -117,7 +116,7 @@ static int php_yar_sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void * } /* }}} */ #endif -void php_yar_curl_plink_dtor(void *ptr TSRMLS_DC) /* {{{ */ { +void php_yar_curl_plink_dtor(void *ptr) /* {{{ */ { yar_curl_plink_t *p, *q; for (p = (yar_curl_plink_t *)ptr; p;) { q = p->next; @@ -136,7 +135,7 @@ size_t php_yar_curl_buf_writer(char *ptr, size_t size, size_t nmemb, void *ctx) return len; } /* }}} */ -int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, long options, char **msg TSRMLS_DC) /* {{{ */ { +int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, long options, char **msg) /* {{{ */ { CURL *cp = NULL; php_url *url; char buf[1024]; @@ -144,19 +143,19 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, yar_curl_data_t *data = (yar_curl_data_t *)self->data; if (options & YAR_PROTOCOL_PERSISTENT) { - zend_rsrc_list_entry *le; + zend_resource *le; uint key_len = snprintf(buf, sizeof(buf), "yar_%s", address); data->persistent = 1; - if (zend_hash_find(&EG(persistent_list), buf, key_len + 1, (void **) &le) == FAILURE) { + if ((le = zend_hash_str_find_ptr(&EG(persistent_list), buf, key_len)) == NULL) { yar_persistent_le_t *con; yar_curl_plink_t *plink; - zend_rsrc_list_entry new_le; + zend_resource new_le; cp = curl_easy_init(); if (!cp) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "start curl failed"); + php_error_docref(NULL, E_ERROR, "start curl failed"); return 0; } @@ -178,10 +177,10 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, con->ptr = plink; con->dtor = php_yar_curl_plink_dtor; - Z_TYPE(new_le) = le_plink; + new_le.type = le_plink; new_le.ptr = con; - if (zend_hash_update(&EG(persistent_list), buf, key_len + 1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL) == SUCCESS) { + if (zend_hash_str_update_ptr(&EG(persistent_list), buf, key_len, (void *)&new_le) != NULL) { data->plink = plink; } else { data->persistent = 0; @@ -204,7 +203,7 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, if (!cp) { cp = curl_easy_init(); if (!cp) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "start curl failed"); + php_error_docref(NULL, E_ERROR, "start curl failed"); return 0; } @@ -224,7 +223,7 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, regular_link: cp = curl_easy_init(); if (!cp) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "start curl failed"); + php_error_docref(NULL, E_ERROR, "start curl failed"); return 0; } } @@ -259,7 +258,10 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, curl_easy_setopt(cp, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(cp, CURLOPT_POST, 1); curl_easy_setopt(cp, CURLOPT_NOPROGRESS, 1); -#if defined(ZTS) +#if LIBCURL_VERSION_NUM > 0x070A00 + /* For the bug that when libcurl use standard name resolver, + * Any timeout less than 1000ms will cause libcurl return timeout immediately + * Added in 7.10 */ curl_easy_setopt(cp, CURLOPT_NOSIGNAL, 1); #endif curl_easy_setopt(cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1); @@ -267,9 +269,12 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, curl_easy_setopt(cp, CURLOPT_DNS_CACHE_TIMEOUT, 300); curl_easy_setopt(cp, CURLOPT_TCP_NODELAY, 0); +#if LIBCURL_VERSION_NUM > 0x070E01 + /* added in 7.14.1 */ if (!data->persistent) { curl_easy_setopt(cp, CURLOPT_IGNORE_CONTENT_LENGTH, 1); } +#endif #if LIBCURL_VERSION_NUM > 0x071002 curl_easy_setopt(cp, CURLOPT_CONNECTTIMEOUT_MS, YAR_G(connect_timeout)); @@ -297,7 +302,7 @@ int php_yar_curl_open(yar_transport_interface_t *self, char *address, uint len, return 1; } /* }}} */ -void php_yar_curl_close(yar_transport_interface_t* self TSRMLS_DC) /* {{{ */ { +void php_yar_curl_close(yar_transport_interface_t* self) /* {{{ */ { yar_curl_data_t *data = (yar_curl_data_t *)self->data; if (!data) { @@ -333,36 +338,36 @@ void php_yar_curl_close(yar_transport_interface_t* self TSRMLS_DC) /* {{{ */ { } /* }}} */ -static void php_yar_curl_prepare(yar_transport_interface_t* self TSRMLS_DC) /* {{{ */ { +static void php_yar_curl_prepare(yar_transport_interface_t* self) /* {{{ */ { yar_curl_data_t *data = (yar_curl_data_t *)self->data; - curl_easy_setopt(data->cp, CURLOPT_POSTFIELDS, data->postfield.c); - curl_easy_setopt(data->cp, CURLOPT_POSTFIELDSIZE, data->postfield.len); + curl_easy_setopt(data->cp, CURLOPT_POSTFIELDS, data->postfield.s->val); + curl_easy_setopt(data->cp, CURLOPT_POSTFIELDSIZE, data->postfield.s->len); } /* }}} */ -yar_response_t * php_yar_curl_exec(yar_transport_interface_t* self, yar_request_t *request TSRMLS_DC) /* {{{ */ { +yar_response_t * php_yar_curl_exec(yar_transport_interface_t* self, yar_request_t *request, zval *zerr) /* {{{ */ { char *msg; uint len; CURLcode ret; yar_response_t *response; yar_curl_data_t *data = (yar_curl_data_t *)self->data; - php_yar_curl_prepare(self TSRMLS_CC); + php_yar_curl_prepare(self); if (request->options && IS_ARRAY == Z_TYPE_P(request->options)) { - zval **ppzval; - if (zend_hash_index_find(Z_ARRVAL_P(request->options), YAR_OPT_TIMEOUT, (void **)&ppzval) == SUCCESS) { - convert_to_long_ex(ppzval); - self->setopt(self, YAR_OPT_TIMEOUT, (long *)&Z_LVAL_PP(ppzval), NULL TSRMLS_CC); + zval *pzval; + if ((pzval = zend_hash_index_find(Z_ARRVAL_P(request->options), YAR_OPT_TIMEOUT)) != NULL) { + convert_to_long_ex(pzval); + self->setopt(self, YAR_OPT_TIMEOUT, (long *)&Z_LVAL_P(pzval), NULL); } } - response = php_yar_response_instance(TSRMLS_C); + response = php_yar_response_instance(); ret = curl_easy_perform(data->cp); if (ret != CURLE_OK) { len = spprintf(&msg, 0, "curl exec failed '%s'", curl_easy_strerror(ret)); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, msg, len TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, msg, len, zerr); efree(msg); return response; } else { @@ -371,25 +376,25 @@ yar_response_t * php_yar_curl_exec(yar_transport_interface_t* self, yar_request_ if(curl_easy_getinfo(data->cp, CURLINFO_RESPONSE_CODE, &http_code) == CURLE_OK && http_code != 200) { len = spprintf(&msg, 0, "server responsed non-200 code '%ld'", http_code); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, msg, len TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, msg, len, zerr); efree(msg); return response; } } - if (data->buf.a) { - zval *retval; + if (data->buf.s) { + zval *retval, rret; yar_header_t *header; char *payload; size_t payload_len; smart_str_0(&data->buf); - payload = data->buf.c; - payload_len = data->buf.len; + payload = data->buf.s->val; + payload_len = data->buf.s->len; - if (!(header = php_yar_protocol_parse(payload TSRMLS_CC))) { - php_yar_error(response, YAR_ERR_PROTOCOL TSRMLS_CC, "malformed response header '%.32s'", payload); + if (!(header = php_yar_protocol_parse(payload))) { + php_yar_error(response, YAR_ERR_PROTOCOL, zerr, "malformed response header '%.32s'", payload); return response; } @@ -397,53 +402,53 @@ yar_response_t * php_yar_curl_exec(yar_transport_interface_t* self, yar_request_ payload += sizeof(yar_header_t); payload_len -= sizeof(yar_header_t); - if (!(retval = php_yar_packager_unpack(payload, payload_len, &msg TSRMLS_CC))) { - php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg) TSRMLS_CC); + if (!(retval = php_yar_packager_unpack(payload, payload_len, &msg, &rret))) { + php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg), zerr); efree(msg); return response; } - php_yar_response_map_retval(response, retval TSRMLS_CC); + php_yar_response_map_retval(response, retval); DEBUG_C("%ld: server response content packaged by '%.*s', len '%ld', content '%.32s'", response->id, 7, payload, header->body_len, payload + 8); - zval_ptr_dtor(&retval); + zval_ptr_dtor(retval); } else { - php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response") TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response"), zerr); } return response; } /* }}} */ -int php_yar_curl_send(yar_transport_interface_t* self, yar_request_t *request, char **msg TSRMLS_DC) /* {{{ */ { - zval *payload; +int php_yar_curl_send(yar_transport_interface_t* self, yar_request_t *request, char **msg) /* {{{ */ { + zval *payload, rret; yar_header_t header = {0}; yar_curl_data_t *data = (yar_curl_data_t *)self->data; - if (!(payload = php_yar_request_pack(request, msg TSRMLS_CC))) { + if (!(payload = php_yar_request_pack(request, msg, &rret))) { return 0; } DEBUG_C("%ld: pack request by '%.*s', result len '%ld', content: '%.32s'", request->id, 7, Z_STRVAL_P(payload), Z_STRLEN_P(payload), Z_STRVAL_P(payload) + 8); - php_yar_protocol_render(&header, request->id, data->host->user, data->host->pass, Z_STRLEN_P(payload), 0 TSRMLS_CC); + php_yar_protocol_render(&header, request->id, data->host->user, data->host->pass, Z_STRLEN_P(payload), 0); smart_str_appendl(&data->postfield, (char *)&header, sizeof(yar_header_t)); smart_str_appendl(&data->postfield, Z_STRVAL_P(payload), Z_STRLEN_P(payload)); - zval_ptr_dtor(&payload); + zval_ptr_dtor(payload); return 1; } /* }}} */ -int php_yar_curl_set_calldata(yar_transport_interface_t* self, yar_call_data_t *entry TSRMLS_DC) /* {{{ */ { +int php_yar_curl_set_calldata(yar_transport_interface_t* self, yar_call_data_t *entry) /* {{{ */ { yar_curl_data_t *data = (yar_curl_data_t *)self->data; data->calldata = entry; return 1; } /* }}} */ -int php_yar_curl_setopt(yar_transport_interface_t* self, long type, void *value, void *addtional TSRMLS_DC) /* {{{ */ { +int php_yar_curl_setopt(yar_transport_interface_t* self, long type, void *value, void *addtional) /* {{{ */ { yar_curl_data_t *data = (yar_curl_data_t *)self->data; CURL *cp = data->cp; @@ -457,16 +462,16 @@ int php_yar_curl_setopt(yar_transport_interface_t* self, long type, void *value, return 1; } /* }}} */ -yar_transport_interface_t * php_yar_curl_init(TSRMLS_D) /* {{{ */ { +yar_transport_interface_t * php_yar_curl_init() /* {{{ */ { size_t newlen; - char content_type[512]; + //char content_type[512]; yar_curl_data_t *data; yar_transport_interface_t *self; self = ecalloc(1, sizeof(yar_transport_interface_t)); self->data = data = ecalloc(1, sizeof(yar_curl_data_t)); - snprintf(content_type, sizeof(content_type), "Content-Type: %s", YAR_G(content_type)); + //snprintf(content_type, sizeof(content_type), "Content-Type: %s", YAR_G(content_type)); data->headers = curl_slist_append(data->headers, "User-Agent: PHP Yar Rpc-" PHP_YAR_VERSION); data->headers = curl_slist_append(data->headers, "Expect:"); @@ -485,14 +490,14 @@ yar_transport_interface_t * php_yar_curl_init(TSRMLS_D) /* {{{ */ { return self; } /* }}} */ -void php_yar_curl_destroy(yar_transport_interface_t *self TSRMLS_DC) /* {{{ */ { +void php_yar_curl_destroy(yar_transport_interface_t *self) /* {{{ */ { } /* }}} */ -int php_yar_curl_multi_add_handle(yar_transport_multi_interface_t *self, yar_transport_interface_t *handle TSRMLS_DC) /* {{{ */ { +int php_yar_curl_multi_add_handle(yar_transport_multi_interface_t *self, yar_transport_interface_t *handle) /* {{{ */ { yar_curl_multi_data_t *multi = (yar_curl_multi_data_t *)self->data; yar_curl_data_t *data = (yar_curl_data_t *)handle->data; - php_yar_curl_prepare(handle TSRMLS_CC); + php_yar_curl_prepare(handle); curl_multi_add_handle(multi->cm, data->cp); @@ -506,8 +511,9 @@ int php_yar_curl_multi_add_handle(yar_transport_multi_interface_t *self, yar_tra return 1; } /* }}} */ -static int php_yar_curl_multi_parse_response(yar_curl_multi_data_t *multi, yar_concurrent_client_callback *f TSRMLS_DC) /* {{{ */ { +static int php_yar_curl_multi_parse_response(yar_curl_multi_data_t *multi, yar_concurrent_client_callback *f) /* {{{ */ { int msg_in_sequence; + zval zerr; CURLMsg *msg; do { @@ -535,7 +541,7 @@ static int php_yar_curl_multi_parse_response(yar_curl_multi_data_t *multi, yar_c yar_response_t *response; yar_curl_data_t *data = (yar_curl_data_t *)handle->data; - response = php_yar_response_instance(TSRMLS_C); + response = php_yar_response_instance(); if (msg->data.result == CURLE_OK) { curl_multi_remove_handle(multi->cm, data->cp); @@ -544,84 +550,87 @@ static int php_yar_curl_multi_parse_response(yar_curl_multi_data_t *multi, yar_c char buf[128]; uint len = snprintf(buf, sizeof(buf), "server responsed non-200 code '%ld'", http_code); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len, &zerr); - if (!f(data->calldata, YAR_ERR_TRANSPORT, response TSRMLS_CC)) { + if (!f(data->calldata, YAR_ERR_TRANSPORT, response)) { /* if f return zero, means user call exit/die explicitly */ - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + handle->close(handle); + php_yar_response_destroy(response); return -1; } if (EG(exception)) { /* uncaught exception */ - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + handle->close(handle); + php_yar_response_destroy(response); return 0; } - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + handle->close(handle); + php_yar_response_destroy(response); continue; } else { - if (data->buf.a) { - char *msg; - zval *retval; + if (data->buf.s) { + char *msg = NULL; + zval *retval, rret; yar_header_t *header; char *payload; size_t payload_len; smart_str_0(&data->buf); - payload = data->buf.c; - payload_len = data->buf.len; + payload = data->buf.s->val; + payload_len = data->buf.s->len; - if (!(header = php_yar_protocol_parse(payload TSRMLS_CC))) { - php_yar_error(response, YAR_ERR_PROTOCOL TSRMLS_CC, "malformed response header '%.32s'", payload); + if (!(header = php_yar_protocol_parse(payload))) { + php_yar_error(response, YAR_ERR_PROTOCOL, &zerr, "malformed response header '%.32s'", payload); } else { /* skip over the leading header */ payload += sizeof(yar_header_t); payload_len -= sizeof(yar_header_t); - if (!(retval = php_yar_packager_unpack(payload, payload_len, &msg TSRMLS_CC))) { - php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg) TSRMLS_CC); + if (!(retval = php_yar_packager_unpack(payload, payload_len, &msg, &rret))) { + php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg), &zerr); } else { - php_yar_response_map_retval(response, retval TSRMLS_CC); + php_yar_response_map_retval(response, retval); DEBUG_C("%ld: server response content packaged by '%.*s', len '%ld', content '%.32s'", response->id, 7, payload, header->body_len, payload + 8); - zval_ptr_dtor(&retval); + //zval_ptr_dtor(retval); + } + if (msg) { + efree(msg); } } } else { - php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response") TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response"), &zerr); } - if (!f(data->calldata, response->status, response TSRMLS_CC)) { - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + if (!f(data->calldata, response->status, response)) { + handle->close(handle); + php_yar_response_destroy(response); return -1; } if (EG(exception)) { - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + handle->close(handle); + php_yar_response_destroy(response); return 0; } } } else { char *err = (char *)curl_easy_strerror(msg->data.result); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, err, strlen(err) TSRMLS_CC); - if (!f(data->calldata, YAR_ERR_TRANSPORT, response TSRMLS_CC)) { - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, err, strlen(err), &zerr); + if (!f(data->calldata, YAR_ERR_TRANSPORT, response)) { + handle->close(handle); + php_yar_response_destroy(response); return -1; } if (EG(exception)) { - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + handle->close(handle); + php_yar_response_destroy(response); return 0; } } - handle->close(handle TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + handle->close(handle); + php_yar_response_destroy(response); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unexpected transport info missed"); + php_error_docref(NULL, E_WARNING, "unexpected transport info missed"); } } } while (msg_in_sequence); @@ -630,7 +639,7 @@ static int php_yar_curl_multi_parse_response(yar_curl_multi_data_t *multi, yar_c } /* }}} */ -int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurrent_client_callback *f TSRMLS_DC) /* {{{ */ { +int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurrent_client_callback *f) /* {{{ */ { int running_count, rest_count; yar_curl_multi_data_t *multi; #ifdef ENABLE_EPOLL @@ -656,7 +665,7 @@ int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurren while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi->cm, &running_count)); #endif - if (!f(NULL, YAR_ERR_OKEY, NULL TSRMLS_CC)) { + if (!f(NULL, YAR_ERR_OKEY, NULL)) { goto bailout; } @@ -690,10 +699,10 @@ int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurren } } } else if (-1 == nfds) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "epoll_wait error '%s'", strerror(errno)); + php_error_docref(NULL, E_WARNING, "epoll_wait error '%s'", strerror(errno)); goto onerror; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "epoll_wait timeout %ldms reached", YAR_G(timeout)); + php_error_docref(NULL, E_WARNING, "epoll_wait timeout %ldms reached", YAR_G(timeout)); goto onerror; } #else @@ -703,34 +712,58 @@ int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurren fd_set writefds; fd_set exceptfds; - tv.tv_sec = (ulong)(YAR_G(timeout) / 1000); - tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); - FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); curl_multi_fdset(multi->cm, &readfds, &writefds, &exceptfds, &max_fd); if (max_fd == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "can not get fd from curl instance"); +#if defined(PHP_WIN32) || defined(__DARWIN__) || defined(__APPLE__) + /* When max_fd returns with -1, you need to wait a while and then proceed and call + curl_multi_perform anyway, How long to wait? I would suggest 100 milliseconds at least */ + tv.tv_sec = 0; + tv.tv_usec = 5000; /* sleep 5ms */ + select(1, &readfds, &writefds, &exceptfds, &tv); + while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi->cm, &running_count)); + continue; +#else + /* should not reach here*/ + php_error_docref(NULL, E_WARNING, "can not get fd from curl instance"); goto onerror; - } +#endif + } + + + /* maybe we should use curl_multi_timeout like: + * curl_multi_timeout(curlm, (long *)&curl_timeout); + * if (curl_timeout == 0) { + * continue; + * } else if (curl_timeout == -1) { + * tv.tv_sec = (ulong)(YAR_G(timeout) / 1000); + * tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); + * } else { + * tv.tv_sec = curl_timeout / 1000; + * tv.tv_usec = (curl_timeout % 1000) * 1000; + * } + */ + tv.tv_sec = (ulong)(YAR_G(timeout) / 1000); + tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); return_code = select(max_fd + 1, &readfds, &writefds, &exceptfds, &tv); if (return_code > 0) { while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi->cm, &running_count)); } else if (-1 == return_code) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "select error '%s'", strerror(errno)); + php_error_docref(NULL, E_WARNING, "select error '%s'", strerror(errno)); goto onerror; } else { /* timeout */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "select timeout %ldms reached", YAR_G(timeout)); + php_error_docref(NULL, E_WARNING, "select timeout %ldms reached", YAR_G(timeout)); goto onerror; } #endif if (rest_count > running_count) { - int ret = php_yar_curl_multi_parse_response(multi, f TSRMLS_CC); + int ret = php_yar_curl_multi_parse_response(multi, f); if (ret == -1) { goto bailout; } else if (ret == 0) { @@ -740,7 +773,7 @@ int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurren } } while (running_count); } else { - int ret = php_yar_curl_multi_parse_response(multi, f TSRMLS_CC); + int ret = php_yar_curl_multi_parse_response(multi, f); if (ret == -1) { goto bailout; } else if (ret == 0) { @@ -752,12 +785,12 @@ int php_yar_curl_multi_exec(yar_transport_multi_interface_t *self, yar_concurren onerror: return 0; bailout: - self->close(self TSRMLS_CC); + self->close(self); zend_bailout(); return 0; } /* }}} */ -void php_yar_curl_multi_close(yar_transport_multi_interface_t *self TSRMLS_DC) /* {{{ */ { +void php_yar_curl_multi_close(yar_transport_multi_interface_t *self) /* {{{ */ { yar_curl_multi_data_t *multi = (yar_curl_multi_data_t *)self->data; if (multi->chs) { @@ -767,7 +800,7 @@ void php_yar_curl_multi_close(yar_transport_multi_interface_t *self TSRMLS_DC) / yar_curl_data_t *data = (yar_curl_data_t *)p->data; q = data->next; curl_multi_remove_handle(multi->cm, data->cp); - p->close(p TSRMLS_CC); + p->close(p); p = q; } } @@ -777,7 +810,7 @@ void php_yar_curl_multi_close(yar_transport_multi_interface_t *self TSRMLS_DC) / return ; } /* }}} */ -yar_transport_multi_interface_t * php_yar_curl_multi_init(TSRMLS_D) /* {{{ */ { +yar_transport_multi_interface_t * php_yar_curl_multi_init() /* {{{ */ { yar_transport_multi_interface_t *multi = emalloc(sizeof(yar_transport_multi_interface_t)); yar_curl_multi_data_t *data = ecalloc(1, sizeof(yar_curl_multi_data_t)); diff --git a/transports/socket.c b/transports/socket.c index 1e1a7cc..d6bb561 100644 --- a/transports/socket.c +++ b/transports/socket.c @@ -39,7 +39,6 @@ #include "yar_packager.h" #include "yar_exception.h" #include "ext/standard/php_var.h" /* for serialize */ -#include "ext/standard/php_smart_str.h" /* for smart string */ #ifdef ENABLE_EPOLL #include @@ -54,11 +53,12 @@ typedef struct _yar_socket_data_t { php_stream *stream; } yar_socket_data_t; -int php_yar_socket_open(yar_transport_interface_t *self, char *address, uint len, long options, char **err_msg TSRMLS_DC) /* {{{ */ { +int php_yar_socket_open(yar_transport_interface_t *self, char *address, uint len, long options, char **err_msg) /* {{{ */ { yar_socket_data_t *data = (yar_socket_data_t *)self->data; struct timeval tv; php_stream *stream = NULL; - char *errstr = NULL, *persistent_key = NULL; + zend_string *errstr = NULL; + char *persistent_key = NULL; int err; tv.tv_sec = (ulong)(YAR_G(connect_timeout) / 1000); @@ -94,7 +94,7 @@ int php_yar_socket_open(yar_transport_interface_t *self, char *address, uint len return 1; } /* }}} */ -void php_yar_socket_close(yar_transport_interface_t* self TSRMLS_DC) /* {{{ */ { +void php_yar_socket_close(yar_transport_interface_t* self) /* {{{ */ { yar_socket_data_t *data = (yar_socket_data_t *)self->data; if (!data) { @@ -112,7 +112,7 @@ void php_yar_socket_close(yar_transport_interface_t* self TSRMLS_DC) /* {{{ */ { } /* }}} */ -yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_request_t *request TSRMLS_DC) /* {{{ */ { +yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_request_t *request, zval *zerr) /* {{{ */ { fd_set rfds; struct timeval tv; yar_header_t *header; @@ -129,7 +129,7 @@ yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_reques PHP_SAFE_FD_SET(fd, &rfds); } else { len = snprintf(buf, sizeof(buf), "Unable cast socket fd form stream (%s)", strerror(errno)); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len, zerr); return response; } @@ -137,24 +137,24 @@ yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_reques tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); wait_io: - while ((retval = php_select(fd+1, &rfds, NULL, NULL, &tv)) == 0); + retval = php_select(fd+1, &rfds, NULL, NULL, &tv); if (retval == -1) { len = snprintf(buf, sizeof(buf), "Unable to select %d '%s'", fd, strerror(errno)); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len, zerr); return response; } else if (retval == 0) { len = snprintf(buf, sizeof(buf), "select timeout %ldms reached", YAR_G(timeout)); - php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_TRANSPORT, buf, len, zerr); return response; } if (PHP_SAFE_FD_ISSET(fd, &rfds)) { - zval *retval; + zval *retval, rret; if (!payload) { - if ((recvd = php_stream_xport_recvfrom(data->stream, buf, sizeof(buf), 0, NULL, NULL, NULL, NULL TSRMLS_CC)) > 0) { - if (!(header = php_yar_protocol_parse(buf TSRMLS_CC))) { - php_yar_error(response, YAR_ERR_PROTOCOL TSRMLS_CC, "malformed response header '%.32s'", payload); + if ((recvd = php_stream_xport_recvfrom(data->stream, buf, sizeof(buf), 0, NULL, NULL, NULL)) > 0) { + if (!(header = php_yar_protocol_parse(buf))) { + php_yar_error(response, YAR_ERR_PROTOCOL, zerr, "malformed response header '%.32s'", payload); return response; } @@ -172,7 +172,7 @@ yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_reques goto wait_io; } } else { - if ((recvd = php_stream_xport_recvfrom(data->stream, payload + total_recvd, len - total_recvd, 0, NULL, NULL, NULL, NULL TSRMLS_CC)) > 0) { + if ((recvd = php_stream_xport_recvfrom(data->stream, payload + total_recvd, len - total_recvd, 0, NULL, NULL, NULL)) > 0) { total_recvd += recvd; } @@ -182,21 +182,21 @@ yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_reques } if (len) { - if (!(retval = php_yar_packager_unpack(payload, len, &msg TSRMLS_CC))) { - php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg) TSRMLS_CC); + if (!(retval = php_yar_packager_unpack(payload, len, &msg, &rret))) { + php_yar_response_set_error(response, YAR_ERR_PACKAGER, msg, strlen(msg), zerr); efree(msg); return response; } - php_yar_response_map_retval(response, retval TSRMLS_CC); + php_yar_response_map_retval(response, retval); DEBUG_C("%ld: server response content packaged by '%.*s', len '%ld', content '%.32s'", response->id, 7, payload, header->body_len, payload + 8); efree(payload); - zval_ptr_dtor(&retval); + zval_ptr_dtor(retval); } else { - php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response") TSRMLS_CC); + php_yar_response_set_error(response, YAR_ERR_EMPTY_RESPONSE, ZEND_STRL("empty response"), zerr); } return response; } else { @@ -204,9 +204,9 @@ yar_response_t * php_yar_socket_exec(yar_transport_interface_t* self, yar_reques } } /* }}} */ -int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, char **msg TSRMLS_DC) /* {{{ */ { +int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, char **msg) /* {{{ */ { fd_set rfds; - zval *payload; + zval *payload, rret; struct timeval tv; int ret = -1, fd, retval; char buf[SEND_BUF_SIZE]; @@ -221,7 +221,7 @@ int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, return 0; } - if (!(payload = php_yar_request_pack(request, msg TSRMLS_CC))) { + if (!(payload = php_yar_request_pack(request, msg, &rret))) { return 0; } @@ -229,21 +229,21 @@ int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, request->id, 7, Z_STRVAL_P(payload), Z_STRLEN_P(payload), Z_STRVAL_P(payload) + 8); /* for tcp/unix RPC, we need another way to supports auth */ - php_yar_protocol_render(&header, request->id, "Yar PHP Client", NULL, Z_STRLEN_P(payload), data->persistent? YAR_PROTOCOL_PERSISTENT : 0 TSRMLS_CC); + php_yar_protocol_render(&header, request->id, "Yar PHP Client", NULL, Z_STRLEN_P(payload), data->persistent? YAR_PROTOCOL_PERSISTENT : 0); memcpy(buf, (char *)&header, sizeof(yar_header_t)); tv.tv_sec = (ulong)(YAR_G(timeout) / 1000); tv.tv_usec = (ulong)((YAR_G(timeout) % 1000)? (YAR_G(timeout) & 1000) * 1000 : 0); - while ((retval = php_select(fd+1, NULL, &rfds, NULL, &tv)) == 0); + retval = php_select(fd+1, NULL, &rfds, NULL, &tv); if (retval == -1) { - zval_ptr_dtor(&payload); + zval_ptr_dtor(payload); spprintf(msg, 0, "select error '%s'", strerror(errno)); return 0; } else if (retval == 0) { - zval_ptr_dtor(&payload); + zval_ptr_dtor(payload); spprintf(msg, 0, "select timeout '%ld' seconds reached", YAR_G(timeout)); return 0; } @@ -254,14 +254,14 @@ int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, if (Z_STRLEN_P(payload) > (sizeof(buf) - sizeof(yar_header_t))) { memcpy(buf + sizeof(yar_header_t), Z_STRVAL_P(payload), sizeof(buf) - sizeof(yar_header_t)); - if ((ret = php_stream_xport_sendto(data->stream, buf, sizeof(buf), 0, NULL, 0 TSRMLS_CC)) < 0) { - zval_ptr_dtor(&payload); + if ((ret = php_stream_xport_sendto(data->stream, buf, sizeof(buf), 0, NULL, 0)) < 0) { + zval_ptr_dtor(payload); return 0; } } else { memcpy(buf + sizeof(yar_header_t), Z_STRVAL_P(payload), Z_STRLEN_P(payload)); - if ((ret = php_stream_xport_sendto(data->stream, buf, sizeof(yar_header_t) + Z_STRLEN_P(payload), 0, NULL, 0 TSRMLS_CC)) < 0) { - zval_ptr_dtor(&payload); + if ((ret = php_stream_xport_sendto(data->stream, buf, sizeof(yar_header_t) + Z_STRLEN_P(payload), 0, NULL, 0)) < 0) { + zval_ptr_dtor(payload); return 0; } } @@ -271,20 +271,20 @@ int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, wait_io: if (bytes_left) { - while ((retval = php_select(fd+1, NULL, &rfds, NULL, &tv)) == 0); + retval = php_select(fd+1, NULL, &rfds, NULL, &tv); if (retval == -1) { - zval_ptr_dtor(&payload); + zval_ptr_dtor(payload); spprintf(msg, 0, "select error '%s'", strerror(errno)); return 0; } else if (retval == 0) { - zval_ptr_dtor(&payload); + zval_ptr_dtor(payload); spprintf(msg, 0, "select timeout %ldms reached", YAR_G(timeout)); return 0; } if (PHP_SAFE_FD_ISSET(fd, &rfds)) { - if ((ret = php_stream_xport_sendto(data->stream, Z_STRVAL_P(payload) + bytes_sent, bytes_left, 0, NULL, 0 TSRMLS_CC)) > 0) { + if ((ret = php_stream_xport_sendto(data->stream, Z_STRVAL_P(payload) + bytes_sent, bytes_left, 0, NULL, 0)) > 0) { bytes_left -= ret; bytes_sent += ret; } @@ -293,16 +293,16 @@ int php_yar_socket_send(yar_transport_interface_t* self, yar_request_t *request, } } - zval_ptr_dtor(&payload); + zval_ptr_dtor(payload); return ret < 0? 0 : 1; } /* }}} */ -int php_yar_socket_setopt(yar_transport_interface_t* self, long type, void *value, void *addtional TSRMLS_DC) /* {{{ */ { +int php_yar_socket_setopt(yar_transport_interface_t* self, long type, void *value, void *addtional) /* {{{ */ { return 1; } /* }}} */ -yar_transport_interface_t * php_yar_socket_init(TSRMLS_D) /* {{{ */ { +yar_transport_interface_t * php_yar_socket_init() /* {{{ */ { yar_socket_data_t *data; yar_transport_interface_t *self; @@ -319,7 +319,7 @@ yar_transport_interface_t * php_yar_socket_init(TSRMLS_D) /* {{{ */ { return self; } /* }}} */ -void php_yar_socket_destroy(yar_transport_interface_t *self TSRMLS_DC) /* {{{ */ { +void php_yar_socket_destroy(yar_transport_interface_t *self) /* {{{ */ { } /* }}} */ /* {{{ yar_transport_t yar_transport_socket diff --git a/yar.c b/yar.c index 56d8a97..f955964 100644 --- a/yar.c +++ b/yar.c @@ -60,18 +60,18 @@ PHP_INI_BEGIN() PHP_INI_END() /* }}} */ -/* {{{ void php_yar_debug(int server_side TSRMLS_DC, const char *format, ...) +/* {{{ void php_yar_debug(int server_side, const char *format, ...) */ -void php_yar_debug(int server_side TSRMLS_DC, const char *format, ...) { +void php_yar_debug(int server_side, const char *format, ...) { va_list args; if (!YAR_G(debug)) { return; } va_start(args, format); if (server_side) { - php_verror(NULL, NULL, E_NOTICE, "[Debug Yar_Server]: %s", args TSRMLS_CC); + php_verror(NULL, NULL, E_NOTICE, "[Debug Yar_Server]: %s", args); } else { - php_verror(NULL, NULL, E_NOTICE, "[Debug Yar_Client]: %s", args TSRMLS_CC); + php_verror(NULL, NULL, E_NOTICE, "[Debug Yar_Client]: %s", args); } va_end(args); } @@ -89,7 +89,7 @@ PHP_GINIT_FUNCTION(yar) PHP_MINIT_FUNCTION(yar) { REGISTER_INI_ENTRIES(); - REGISTER_STRINGL_CONSTANT("PHP_YAR_VERSION", PHP_YAR_VERSION, sizeof(PHP_YAR_VERSION)-1, CONST_CS|CONST_PERSISTENT); + REGISTER_STRINGL_CONSTANT("YAR_VERSION", PHP_YAR_VERSION, sizeof(PHP_YAR_VERSION)-1, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("YAR_OPT_PACKAGER", YAR_OPT_PACKAGER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("YAR_OPT_PERSISTENT", YAR_OPT_PERSISTENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("YAR_OPT_TIMEOUT", YAR_OPT_TIMEOUT, CONST_CS|CONST_PERSISTENT); diff --git a/yar_client.c b/yar_client.c index 9c33a2a..16adfcc 100644 --- a/yar_client.c +++ b/yar_client.c @@ -68,7 +68,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_client_loop, 0, 0, 0) ZEND_END_ARG_INFO() /* }}} */ -static void php_yar_client_trigger_error(int throw_exception TSRMLS_DC, int code, const char *format, ...) /* {{{ */ { +static void php_yar_client_trigger_error(int throw_exception, int code, const char *format, ...) /* {{{ */ { va_list arg; char *message; zend_class_entry *ce; @@ -96,78 +96,81 @@ static void php_yar_client_trigger_error(int throw_exception TSRMLS_DC, int code ce = yar_client_exception_ce; break; } - zend_throw_exception(ce, message, code TSRMLS_CC); + zend_throw_exception(ce, message, code); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d] %s", code, message); + php_error_docref(NULL, E_WARNING, "[%d] %s", code, message); } - efree(message); + if (message) { + efree(message); + } } /* }}} */ -static void php_yar_client_handle_error(int throw_exception, yar_response_t *response TSRMLS_DC) /* {{{ */ { +static void php_yar_client_handle_error(int throw_exception, yar_response_t *response) /* {{{ */ { if (response->status == YAR_ERR_EXCEPTION) { if (throw_exception) { - zval *ex, **property; - MAKE_STD_ZVAL(ex); - object_init_ex(ex, yar_server_exception_ce); + zval ex, *property; + object_init_ex(&ex, yar_server_exception_ce); - if (zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("message"), (void **)&property) == SUCCESS) { - zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("message"), *property TSRMLS_CC); + if ((property = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("message"))) != NULL) { + zend_update_property(yar_server_exception_ce, &ex, ZEND_STRL("message"), property); } - if (zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("code"), (void **)&property) == SUCCESS) { - zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("code"), *property TSRMLS_CC); + if ((property = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("code"))) != NULL) { + zend_update_property(yar_server_exception_ce, &ex, ZEND_STRL("code"), property); } - if (zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("file"), (void **)&property) == SUCCESS) { - zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("file"), *property TSRMLS_CC); + if ((property = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("file"))) != NULL) { + zend_update_property(yar_server_exception_ce, &ex, ZEND_STRL("file"), property); } - if (zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("line"), (void **)&property) == SUCCESS) { - zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("line"), *property TSRMLS_CC); + if ((property = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("line"))) != NULL) { + zend_update_property(yar_server_exception_ce, &ex, ZEND_STRL("line"), property); } - if (zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("_type"), (void **)&property) == SUCCESS) { - zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("_type"), *property TSRMLS_CC); + if ((property = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("_type"))) != NULL) { + zend_update_property(yar_server_exception_ce, &ex, ZEND_STRL("_type"), property); } - zend_throw_exception_object(ex TSRMLS_CC); + + zend_throw_exception_object(&ex); } else { - zval **msg, **code; - if (zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("message"), (void **)&msg) == SUCCESS - && zend_hash_find(Z_ARRVAL_P(response->err), ZEND_STRS("code"), (void **)&code) == SUCCESS) { + zval *msg, *code; + if ((msg = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("message"))) != NULL + && (code = zend_hash_str_find(Z_ARRVAL(response->err), ZEND_STRL("code"))) != NULL) { convert_to_string_ex(msg); convert_to_long_ex(code); - php_yar_client_trigger_error(0 TSRMLS_CC, Z_LVAL_PP(code), "server threw an exception with message `%s`", Z_STRVAL_PP(msg)); + php_yar_client_trigger_error(0, Z_LVAL_P(code), "server threw an exception with message `%s`", Z_STRVAL_P(msg)); } } } else { - php_yar_client_trigger_error(throw_exception TSRMLS_CC, response->status, "%s", Z_STRVAL_P(response->err)); + php_yar_client_trigger_error(throw_exception, response->status, "%s", Z_STRVAL(response->err)); } } /* }}} */ -static zval * php_yar_client_get_opt(zval *options, long type TSRMLS_DC) /* {{{ */ { - zval **value; +static zval * php_yar_client_get_opt(zval *options, long type) /* {{{ */ { + zval *value; if (IS_ARRAY != Z_TYPE_P(options)) { return NULL; } - if (zend_hash_index_find(Z_ARRVAL_P(options), type, (void **)&value) == SUCCESS) { - return *value; + if ((value = zend_hash_index_find(Z_ARRVAL_P(options), type)) != NULL) { + return value; } return NULL; } /* }}} */ -static int php_yar_client_set_opt(zval *client, long type, zval *value TSRMLS_DC) /* {{{ */ { +static int php_yar_client_set_opt(zval *client, long type, zval *value) /* {{{ */ { zend_bool verified = 0; + zval rv; switch (type) { case YAR_OPT_PACKAGER: { verified = 1; if (IS_STRING != Z_TYPE_P(value)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects a string packager name"); + php_error_docref(NULL, E_WARNING, "expects a string packager name"); return 0; } } @@ -175,8 +178,8 @@ static int php_yar_client_set_opt(zval *client, long type, zval *value TSRMLS_DC { if (!verified) { verified = 1; - if (IS_LONG != Z_TYPE_P(value) && IS_BOOL != Z_TYPE_P(value)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects a boolean persistent flag"); + if (IS_LONG != Z_TYPE_P(value) && IS_TRUE != Z_TYPE_P(value) && IS_FALSE != Z_TYPE_P(value)) { + php_error_docref(NULL, E_WARNING, "expects a boolean persistent flag"); return 0; } @@ -189,21 +192,21 @@ static int php_yar_client_set_opt(zval *client, long type, zval *value TSRMLS_DC if (!verified) { if (IS_LONG != Z_TYPE_P(value)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "expects a long integer timeout value"); + php_error_docref(NULL, E_WARNING, "expects a long integer timeout value"); return 0; } } - options = zend_read_property(yar_client_ce, client, ZEND_STRL("_options"), 0 TSRMLS_CC); + options = zend_read_property(yar_client_ce, client, ZEND_STRL("_options"), 0, &rv); if (IS_ARRAY != Z_TYPE_P(options)) { - MAKE_STD_ZVAL(options); - array_init(options); - zend_update_property(yar_client_ce, client, ZEND_STRL("_options"), options TSRMLS_CC); - zval_ptr_dtor(&options); + zval tmp_options; + array_init(&tmp_options); + zend_update_property(yar_client_ce, client, ZEND_STRL("_options"), &tmp_options); + zval_ptr_dtor(&tmp_options); } - Z_ADDREF_P(value); - zend_hash_index_update(Z_ARRVAL_P(options), type, (void **)&value, sizeof(zval *), NULL); + Z_TRY_ADDREF_P(value); + zend_hash_index_update(Z_ARRVAL_P(options), type, value); break; } default: @@ -213,92 +216,94 @@ static int php_yar_client_set_opt(zval *client, long type, zval *value TSRMLS_DC return 1; } /* }}} */ -static zval * php_yar_client_handle(int protocol, zval *client, char *method, long mlen, zval *params TSRMLS_DC) /* {{{ */ { +static zval * php_yar_client_handle(int protocol, zval *client, char *method, long mlen, zval *params, zval *rret) /* {{{ */ { char *msg; zval *uri, *options, *retval; + zval zerr, rv; yar_transport_t *factory; yar_transport_interface_t *transport; yar_request_t *request; yar_response_t *response; int flags = 0; - uri = zend_read_property(yar_client_ce, client, ZEND_STRL("_uri"), 0 TSRMLS_CC); + uri = zend_read_property(yar_client_ce, client, ZEND_STRL("_uri"), 0, &rv); if (protocol == YAR_CLIENT_PROTOCOL_HTTP) { - factory = php_yar_transport_get(ZEND_STRL("curl") TSRMLS_CC); + factory = php_yar_transport_get(ZEND_STRL("curl")); } else if (protocol == YAR_CLIENT_PROTOCOL_TCP || protocol == YAR_CLIENT_PROTOCOL_UNIX) { - factory = php_yar_transport_get(ZEND_STRL("sock") TSRMLS_CC); + factory = php_yar_transport_get(ZEND_STRL("sock")); } else { return NULL; } - transport = factory->init(TSRMLS_C); + transport = factory->init(); - options = zend_read_property(yar_client_ce, client, ZEND_STRL("_options"), 1 TSRMLS_CC); + options = zend_read_property(yar_client_ce, client, ZEND_STRL("_options"), 1, &rv); if (IS_ARRAY != Z_TYPE_P(options)) { options = NULL; } - if (!(request = php_yar_request_instance(method, mlen, params, options TSRMLS_CC))) { - transport->close(transport TSRMLS_CC); - factory->destroy(transport TSRMLS_CC); + if (!(request = php_yar_request_instance(method, mlen, params, options))) { + transport->close(transport); + factory->destroy(transport); return NULL; } if (YAR_G(allow_persistent)) { if (options) { - zval *flag = php_yar_client_get_opt(options, YAR_OPT_PERSISTENT TSRMLS_CC); - if (flag && (Z_TYPE_P(flag) == IS_BOOL || Z_TYPE_P(flag) == IS_LONG) && Z_LVAL_P(flag)) { + zval *flag = php_yar_client_get_opt(options, YAR_OPT_PERSISTENT); + if (flag && (Z_TYPE_P(flag) == IS_TRUE || (Z_TYPE_P(flag) == IS_LONG && Z_LVAL_P(flag)))) { flags |= YAR_PROTOCOL_PERSISTENT; } } } - if (!transport->open(transport, Z_STRVAL_P(uri), Z_STRLEN_P(uri), flags, &msg TSRMLS_CC)) { - php_yar_client_trigger_error(1 TSRMLS_CC, YAR_ERR_TRANSPORT, msg TSRMLS_CC); - php_yar_request_destroy(request TSRMLS_CC); + if (!transport->open(transport, Z_STRVAL_P(uri), Z_STRLEN_P(uri), flags, &msg)) { + php_yar_client_trigger_error(1, YAR_ERR_TRANSPORT, msg); + php_yar_request_destroy(request); efree(msg); return NULL; } DEBUG_C("%ld: call api '%s' at (%c)'%s' with '%d' parameters", - request->id, request->method, (flags & YAR_PROTOCOL_PERSISTENT)? 'p' : 'r', Z_STRVAL_P(uri), zend_hash_num_elements(Z_ARRVAL_P(request->parameters))); + request->id, request->method, (flags & YAR_PROTOCOL_PERSISTENT)? 'p' : 'r', Z_STRVAL_P(uri), + zend_hash_num_elements(Z_ARRVAL_P(request->parameters))); - if (!transport->send(transport, request, &msg TSRMLS_CC)) { - php_yar_client_trigger_error(1 TSRMLS_CC, YAR_ERR_TRANSPORT, msg TSRMLS_CC); - php_yar_request_destroy(request TSRMLS_CC); + if (!transport->send(transport, request, &msg)) { + php_yar_client_trigger_error(1, YAR_ERR_TRANSPORT, msg); + php_yar_request_destroy(request); efree(msg); return NULL; } - response = transport->exec(transport, request TSRMLS_CC); + response = transport->exec(transport, request, &zerr); if (response->status != YAR_ERR_OKEY) { - php_yar_client_handle_error(1, response TSRMLS_CC); - retval = NULL; + php_yar_client_handle_error(1, response); + rret = NULL; } else { - if (response->olen) { - PHPWRITE(response->out, response->olen); - } - if ((retval = response->retval)) { - Z_ADDREF_P(retval); + if (response->out && response->out->len) { + PHPWRITE(response->out->val, response->out->len); } + //rret = response->retval; + ZVAL_COPY(rret, &response->retval); } - php_yar_request_destroy(request TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); - transport->close(transport TSRMLS_CC); - factory->destroy(transport TSRMLS_CC); + php_yar_request_destroy(request); + php_yar_response_destroy(response); + transport->close(transport); + factory->destroy(transport); + retval = rret; return retval; } /* }}} */ -int php_yar_concurrent_client_callback(yar_call_data_t *calldata, int status, yar_response_t *response TSRMLS_DC) /* {{{ */ { - zval *code, *retval, *retval_ptr = NULL; - zval *callinfo, *callback, ***func_params; +int php_yar_concurrent_client_callback(yar_call_data_t *calldata, int status, yar_response_t *response) /* {{{ */ { + zval code, retval, retval_ptr; + zval callinfo, *callback, *func_params; zend_bool bailout = 0; - uint params_count; + uint params_count, i; if (calldata) { /* data callback */ @@ -306,89 +311,89 @@ int php_yar_concurrent_client_callback(yar_call_data_t *calldata, int status, ya if (calldata->callback) { callback = calldata->callback; } else { - callback = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callback"), 0 TSRMLS_CC); + callback = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callback"), 0); } params_count = 2; } else { if (calldata->ecallback) { callback = calldata->ecallback; } else { - callback = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_error_callback"), 0 TSRMLS_CC); + callback = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_error_callback"), 0); } params_count = 3; } if (ZVAL_IS_NULL(callback)) { if (status != YAR_ERR_OKEY) { - if (response->err) { - php_yar_client_handle_error(0, response TSRMLS_CC); + if (!Z_ISUNDEF(response->err)) { + php_yar_client_handle_error(0, response); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d]:unknown Error", status); + php_error_docref(NULL, E_WARNING, "[%d]:unknown Error", status); } - } else if (response->retval) { - zend_print_zval(response->retval, 1); + } else if (!Z_ISUNDEF(response->retval)) { + zend_print_zval(&response->retval, 1); } return 1; } if (status == YAR_ERR_OKEY) { - if (!response->retval) { - php_yar_client_trigger_error(0 TSRMLS_CC, YAR_ERR_REQUEST, "%s", "server responsed empty response"); + if (Z_ISUNDEF(response->retval)) { + php_yar_client_trigger_error(0, YAR_ERR_REQUEST, "%s", "server responsed empty response"); return 1; } - Z_ADDREF_P(response->retval); - retval = response->retval; + ZVAL_COPY(&retval, &response->retval); } else { - MAKE_STD_ZVAL(code); - ZVAL_LONG(code, status); - Z_ADDREF_P(response->err); - retval = response->err; + ZVAL_LONG(&code, status); + ZVAL_COPY(&retval, &response->err); } - MAKE_STD_ZVAL(callinfo); - array_init(callinfo); + array_init(&callinfo); - add_assoc_long_ex(callinfo, "sequence", sizeof("sequence"), calldata->sequence); - add_assoc_stringl_ex(callinfo, "uri", sizeof("uri"), calldata->uri, calldata->ulen, 1); - add_assoc_stringl_ex(callinfo, "method", sizeof("method"), calldata->method, calldata->mlen, 1); + add_assoc_long_ex(&callinfo, "sequence", sizeof("sequence"), calldata->sequence); + add_assoc_stringl_ex(&callinfo, "uri", sizeof("uri"), calldata->uri, calldata->ulen); + add_assoc_stringl_ex(&callinfo, "method", sizeof("method"), calldata->method, calldata->mlen); } else { - callback = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callback"), 0 TSRMLS_CC); + callback = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callback"), 0); if (ZVAL_IS_NULL(callback)) { return 1; } params_count = 2; } - func_params = emalloc(sizeof(zval **) * params_count); if (calldata && (status != YAR_ERR_OKEY)) { - func_params[0] = &code; - func_params[1] = &retval; - func_params[2] = &callinfo; + func_params = safe_emalloc(sizeof(zval), 3, 0); + ZVAL_COPY(&func_params[0], &code); + ZVAL_COPY(&func_params[1], &retval); + ZVAL_COPY(&func_params[2], &callinfo); } else if (calldata) { - func_params[0] = &retval; - func_params[1] = &callinfo; + func_params = safe_emalloc(sizeof(zval), 2, 0); + ZVAL_COPY(&func_params[0], &retval); + ZVAL_COPY(&func_params[1], &callinfo); } else { - MAKE_STD_ZVAL(retval); - MAKE_STD_ZVAL(callinfo); - ZVAL_NULL(retval); - ZVAL_NULL(callinfo); - func_params[0] = &retval; - func_params[1] = &callinfo; + func_params = safe_emalloc(sizeof(zval), 2, 0); + ZVAL_NULL(&retval); + ZVAL_NULL(&callinfo); + ZVAL_COPY(&func_params[0], &retval); + ZVAL_COPY(&func_params[1], &callinfo); } + ZVAL_UNDEF(&retval_ptr); zend_try { if (call_user_function_ex(EG(function_table), NULL, callback, - &retval_ptr, params_count, func_params, 0, NULL TSRMLS_CC) != SUCCESS) { + &retval_ptr, params_count, func_params, 0, NULL) != SUCCESS) { if (status) { zval_ptr_dtor(&code); } zval_ptr_dtor(&retval); zval_ptr_dtor(&callinfo); + for (i = 0; i < params_count; i++) { + zval_ptr_dtor(&func_params[i]); + } efree(func_params); if (calldata) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "call to callback failed for request: '%s'", calldata->method); + php_error_docref(NULL, E_WARNING, "call to callback failed for request: '%s'", calldata->method); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "call to initial callback failed"); + php_error_docref(NULL, E_WARNING, "call to initial callback failed"); } return 1; } @@ -402,72 +407,67 @@ int php_yar_concurrent_client_callback(yar_call_data_t *calldata, int status, ya zval_ptr_dtor(&code); } - if (retval_ptr) { + if (Z_TYPE(retval_ptr) != IS_UNDEF) { zval_ptr_dtor(&retval_ptr); } + for (i = 0; i < params_count; i++) { + zval_ptr_dtor(&func_params[i]); + } efree(func_params); return bailout? 0 : 1; } /* }}} */ -int php_yar_concurrent_client_handle(zval *callstack TSRMLS_DC) /* {{{ */ { - char *dummy, *msg; - ulong sequence; - zval **calldata; +int php_yar_concurrent_client_handle(zval *callstack) /* {{{ */ { + char *msg; + zend_string *dummy; + zend_ulong sequence; + zval *calldata; yar_request_t *request; yar_transport_t *factory; yar_transport_interface_t *transport; yar_transport_multi_interface_t *multi; - factory = php_yar_transport_get(ZEND_STRL("curl") TSRMLS_CC); - multi = factory->multi->init(TSRMLS_C); + factory = php_yar_transport_get(ZEND_STRL("curl")); + multi = factory->multi->init(); - for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(callstack)); - zend_hash_has_more_elements(Z_ARRVAL_P(callstack)) == SUCCESS; - zend_hash_move_forward(Z_ARRVAL_P(callstack))) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(callstack), sequence, dummy, calldata) { yar_call_data_t *entry; long flags = 0; - if (zend_hash_get_current_data(Z_ARRVAL_P(callstack), (void**)&calldata) == FAILURE) { - continue; - } - - ZEND_FETCH_RESOURCE_NO_RETURN(entry, yar_call_data_t *, calldata, -1, "Yar Call Data", le_calldata); + entry = (yar_call_data_t *)zend_fetch_resource(Z_RES_P(calldata), "Yar Call Data", le_calldata); if (!entry) { continue; } - zend_hash_get_current_key(Z_ARRVAL_P(callstack), &dummy, &sequence, 0); - if (!entry->parameters) { - zval *tmp; - MAKE_STD_ZVAL(tmp); - array_init(tmp); - entry->parameters = tmp; + zval tmp; + array_init(&tmp); + entry->parameters = &tmp; } - transport = factory->init(TSRMLS_C); + transport = factory->init(); if (YAR_G(allow_persistent)) { if (entry->options) { - zval *flag = php_yar_client_get_opt(entry->options, YAR_OPT_PERSISTENT TSRMLS_CC); - if (flag && (Z_TYPE_P(flag) == IS_BOOL || Z_TYPE_P(flag) == IS_LONG) && Z_LVAL_P(flag)) { + zval *flag = php_yar_client_get_opt(entry->options, YAR_OPT_PERSISTENT); + if (flag && (Z_TYPE_P(flag) == IS_TRUE || (Z_TYPE_P(flag) == IS_LONG && Z_LVAL_P(flag)))) { flags |= YAR_PROTOCOL_PERSISTENT; } } } - if (!(request = php_yar_request_instance(entry->method, entry->mlen, entry->parameters, entry->options TSRMLS_CC))) { - transport->close(transport TSRMLS_CC); - factory->destroy(transport TSRMLS_CC); + if (!(request = php_yar_request_instance(entry->method, entry->mlen, entry->parameters, entry->options))) { + transport->close(transport); + factory->destroy(transport); return 0; } - if (!transport->open(transport, entry->uri, entry->ulen, flags, &msg TSRMLS_CC)) { - php_yar_client_trigger_error(1 TSRMLS_CC, YAR_ERR_TRANSPORT, msg TSRMLS_CC); - transport->close(transport TSRMLS_CC); - factory->destroy(transport TSRMLS_CC); + if (!transport->open(transport, entry->uri, entry->ulen, flags, &msg)) { + php_yar_client_trigger_error(1, YAR_ERR_TRANSPORT, msg); + transport->close(transport); + factory->destroy(transport); efree(msg); return 0; } @@ -476,79 +476,80 @@ int php_yar_concurrent_client_handle(zval *callstack TSRMLS_DC) /* {{{ */ { request->id, request->method, (flags & YAR_PROTOCOL_PERSISTENT)? 'p' : 'r', entry->uri, zend_hash_num_elements(Z_ARRVAL_P(request->parameters))); - if (!transport->send(transport, request, &msg TSRMLS_CC)) { - php_yar_client_trigger_error(1 TSRMLS_CC, YAR_ERR_TRANSPORT, msg TSRMLS_CC); - transport->close(transport TSRMLS_CC); - factory->destroy(transport TSRMLS_CC); + if (!transport->send(transport, request, &msg)) { + php_yar_client_trigger_error(1, YAR_ERR_TRANSPORT, msg); + transport->close(transport); + factory->destroy(transport); efree(msg); return 0; } - transport->calldata(transport, entry TSRMLS_CC); - multi->add(multi, transport TSRMLS_CC); - php_yar_request_destroy(request TSRMLS_CC); - } + transport->calldata(transport, entry); + multi->add(multi, transport); + php_yar_request_destroy(request); + } ZEND_HASH_FOREACH_END(); - if (!multi->exec(multi, php_yar_concurrent_client_callback TSRMLS_CC)) { - multi->close(multi TSRMLS_CC); + if (!multi->exec(multi, php_yar_concurrent_client_callback)) { + multi->close(multi); return 0; } - multi->close(multi TSRMLS_CC); + multi->close(multi); return 1; } /* }}} */ /* {{{ proto Yar_Client::__construct($uri[, array $options = NULL]) */ PHP_METHOD(yar_client, __construct) { - char *url; - long len; + zend_string *url; zval *options = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &url, &len, &options) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|a!", &url, &options) == FAILURE) { return; } - zend_update_property_stringl(yar_client_ce, getThis(), ZEND_STRL("_uri"), url, len TSRMLS_CC); + zend_update_property_str(yar_client_ce, getThis(), ZEND_STRL("_uri"), url); - if (strncasecmp(url, ZEND_STRL("http://")) == 0 || strncasecmp(url, ZEND_STRL("https://")) == 0) { - } else if (strncasecmp(url, ZEND_STRL("tcp://")) == 0) { - zend_update_property_long(yar_client_ce, getThis(), ZEND_STRL("_protocol"), YAR_CLIENT_PROTOCOL_TCP TSRMLS_CC); - } else if (strncasecmp(url, ZEND_STRL("unix://")) == 0) { - zend_update_property_long(yar_client_ce, getThis(), ZEND_STRL("_protocol"), YAR_CLIENT_PROTOCOL_UNIX TSRMLS_CC); + if (strncasecmp(url->val, "http://", sizeof("http://") - 1) == 0 + || strncasecmp(url->val, "https://", sizeof("https://") - 1) == 0) { + } else if (strncasecmp(url->val, "tcp://", sizeof("tcp://") - 1) == 0) { + zend_update_property_long(yar_client_ce, getThis(), ZEND_STRL("_protocol"), YAR_CLIENT_PROTOCOL_TCP); + } else if (strncasecmp(url->val, "unix://", sizeof("unix://") - 1) == 0) { + zend_update_property_long(yar_client_ce, getThis(), ZEND_STRL("_protocol"), YAR_CLIENT_PROTOCOL_UNIX); } else { - php_yar_client_trigger_error(1 TSRMLS_CC, YAR_ERR_PROTOCOL, "unsupported protocol address %s", url); + php_yar_client_trigger_error(1, YAR_ERR_PROTOCOL, "unsupported protocol address %s", url->val); return; } if (options) { - zend_update_property(yar_client_ce, getThis(), ZEND_STRL("_options"), options TSRMLS_CC); + zend_update_property(yar_client_ce, getThis(), ZEND_STRL("_options"), options); } } /* }}} */ /* {{{ proto Yar_Client::__call($method, $parameters = NULL) */ PHP_METHOD(yar_client, __call) { - zval *params, *protocol, *ret; + zval *params, *protocol, *ret, rret, rv; char *method; - long mlen; + size_t mlen; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &method, &mlen, ¶ms) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &method, &mlen, ¶ms) == FAILURE) { return; } - protocol = zend_read_property(yar_client_ce, getThis(), ZEND_STRL("_protocol"), 0 TSRMLS_CC); + protocol = zend_read_property(yar_client_ce, getThis(), ZEND_STRL("_protocol"), 0, &rv); switch (Z_LVAL_P(protocol)) { case YAR_CLIENT_PROTOCOL_TCP: case YAR_CLIENT_PROTOCOL_UNIX: case YAR_CLIENT_PROTOCOL_HTTP: - if ((ret = php_yar_client_handle(Z_LVAL_P(protocol), getThis(), method, mlen, params TSRMLS_CC))) { - RETVAL_ZVAL(ret, 1, 1); + ZVAL_UNDEF(&rret); + if ((ret = php_yar_client_handle(Z_LVAL_P(protocol), getThis(), method, mlen, params, &rret))) { + RETVAL_ZVAL(ret, 0, 1); return; } break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unsupported protocol %ld", Z_LVAL_P(protocol)); + php_error_docref(NULL, E_WARNING, "unsupported protocol %ld", Z_LVAL_P(protocol)); break; } @@ -565,13 +566,13 @@ PHP_METHOD(yar_client, call) { /* {{{ proto Yar_Client::getOpt(int $type) */ PHP_METHOD(yar_client, getOpt) { long type; - zval *value; + zval *value, rv; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &type, &value) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &type, &value) == FAILURE) { return; } else { - zval * options = zend_read_property(yar_client_ce, getThis(), ZEND_STRL("_options"), 0 TSRMLS_CC); - if (!(value = php_yar_client_get_opt(options, type TSRMLS_CC))) { + zval * options = zend_read_property(yar_client_ce, getThis(), ZEND_STRL("_options"), 0, &rv); + if (!(value = php_yar_client_get_opt(options, type))) { RETURN_FALSE; } @@ -585,11 +586,11 @@ PHP_METHOD(yar_client, setOpt) { long type; zval *value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &type, &value) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &type, &value) == FAILURE) { return; } - if (!php_yar_client_set_opt(getThis(), type, value TSRMLS_CC)) { + if (!php_yar_client_set_opt(getThis(), type, value)) { RETURN_FALSE; } @@ -599,65 +600,60 @@ PHP_METHOD(yar_client, setOpt) { /* {{{ proto Yar_Concurrent_Client::call($uri, $method, $parameters = NULL, $callback = NULL, $error_callback = NULL, $options = array()) */ PHP_METHOD(yar_concurrent_client, call) { - char *uri, *method, *name = NULL; - long sequence, ulen = 0, mlen = 0; - zval *callstack, *item, *status; + char *uri, *method; + zend_string *name = NULL; + long sequence; + size_t ulen = 0, mlen = 0; + zval *callstack, item, *status; zval *error_callback = NULL, *callback = NULL, *parameters = NULL, *options = NULL; yar_call_data_t *entry; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a!z!za", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a!z!za", &uri, &ulen, &method, &mlen, ¶meters, &callback, &error_callback, &options) == FAILURE) { return; } if (!ulen) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "first parameter is expected to be a valid rpc server uri"); + php_error_docref(NULL, E_WARNING, "first parameter is expected to be a valid rpc server uri"); return; } - if (strncasecmp(uri, ZEND_STRL("http://")) && strncasecmp(uri, ZEND_STRL("https://"))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "only http protocol is supported in concurrent client for now"); + if (strncasecmp(uri, "http://", sizeof("http://") - 1) + && strncasecmp(uri, "https://", sizeof("https://") - 1)) { + php_error_docref(NULL, E_WARNING, "only http protocol is supported in concurrent client for now"); return; } if (!mlen) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "second parameter is expected to be a valid rpc api name"); + php_error_docref(NULL, E_WARNING, "second parameter is expected to be a valid rpc api name"); return; } if (callback && !ZVAL_IS_NULL(callback) && - !zend_is_callable(callback, 0, &name -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) - TSRMLS_CC -#endif - )) { - php_error_docref1(NULL TSRMLS_CC, name, E_ERROR, "fourth parameter is expected to be a valid callback"); - efree(name); + !zend_is_callable(callback, 0, &name)) { + php_error_docref1(NULL, name->val, E_ERROR, "fourth parameter is expected to be a valid callback"); + zend_string_release(name); RETURN_FALSE; } if (name) { - efree(name); + zend_string_release(name); name = NULL; } if (error_callback && !ZVAL_IS_NULL(error_callback) && - !zend_is_callable(error_callback, 0, &name -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) - TSRMLS_CC -#endif - )) { - php_error_docref1(NULL TSRMLS_CC, name, E_ERROR, "fifth parameter is expected to be a valid error callback"); - efree(name); + !zend_is_callable(error_callback, 0, &name)) { + php_error_docref1(NULL, name->val, E_ERROR, "fifth parameter is expected to be a valid error callback"); + zend_string_release(name); RETURN_FALSE; } if (name) { - efree(name); + zend_string_release(name); } - status = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_start"), 0 TSRMLS_CC); - if (Z_BVAL_P(status)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "concurrent client has already started"); + status = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_start"), 0); + if (Z_TYPE_P(status) == IS_TRUE) { + php_error_docref(NULL, E_WARNING, "concurrent client has already started"); RETURN_FALSE; } @@ -670,106 +666,110 @@ PHP_METHOD(yar_concurrent_client, call) { entry->mlen = mlen; if (callback && !ZVAL_IS_NULL(callback)) { - Z_ADDREF_P(callback); + Z_TRY_ADDREF_P(callback); entry->callback = callback; } if (error_callback && !ZVAL_IS_NULL(error_callback)) { - Z_ADDREF_P(error_callback); + Z_TRY_ADDREF_P(error_callback); entry->ecallback = error_callback; } if (parameters && IS_ARRAY == Z_TYPE_P(parameters)) { - Z_ADDREF_P(parameters); + Z_TRY_ADDREF_P(parameters); entry->parameters = parameters; } if (options && IS_ARRAY == Z_TYPE_P(options)) { - Z_ADDREF_P(options); + Z_TRY_ADDREF_P(options); entry->options = options; } - callstack = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), 0 TSRMLS_CC); + callstack = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), 0); if (ZVAL_IS_NULL(callstack)) { - MAKE_STD_ZVAL(callstack); - array_init(callstack); - zend_update_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), callstack TSRMLS_CC); - zval_ptr_dtor(&callstack); + zval tmp; + array_init(&tmp); + zend_update_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), &tmp); + zval_ptr_dtor(&tmp); } - MAKE_STD_ZVAL(item); - - ZEND_REGISTER_RESOURCE(item, entry, le_calldata); + ZVAL_RES(&item, zend_register_resource(entry, le_calldata)); sequence = zend_hash_next_free_element(Z_ARRVAL_P(callstack)); entry->sequence = sequence + 1; - zend_hash_next_index_insert(Z_ARRVAL_P(callstack), &item, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(callstack), &item); RETURN_LONG(entry->sequence); } /* }}} */ +/* {{{ proto Yar_Concurrent_Client::reset(void) */ +PHP_METHOD(yar_concurrent_client, reset) { + zval *callstack; + + + callstack = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), 0); + if (ZVAL_IS_NULL(callstack) || zend_hash_num_elements(Z_ARRVAL_P(callstack)) == 0) { + RETURN_TRUE; + } + zend_hash_clean(Z_ARRVAL_P(callstack)); + RETURN_TRUE; +} +/* }}} */ + /* {{{ proto Yar_Concurrent_Client::loop($callback = NULL, $error_callback) */ PHP_METHOD(yar_concurrent_client, loop) { - char *name = NULL; + zend_string *name = NULL; zval *callstack; zval *callback = NULL, *error_callback = NULL; zval *status; uint ret = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &callback, &error_callback) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &callback, &error_callback) == FAILURE) { return; } - status = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_start"), 0 TSRMLS_CC); - if (Z_BVAL_P(status)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "concurrent client has already started"); + status = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_start"), 0); + if (Z_TYPE_P(status) == IS_TRUE) { + php_error_docref(NULL, E_WARNING, "concurrent client has already started"); RETURN_FALSE; } if (callback && !ZVAL_IS_NULL(callback) && - !zend_is_callable(callback, 0, &name -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) - TSRMLS_CC -#endif - )) { - php_error_docref1(NULL TSRMLS_CC, name, E_ERROR, "first argument is expected to be a valid callback"); - efree(name); + !zend_is_callable(callback, 0, &name)) { + php_error_docref1(NULL, name->val, E_ERROR, "first argument is expected to be a valid callback"); + zend_string_release(name); RETURN_FALSE; } if (name) { - efree(name); + zend_string_release(name); name = NULL; } if (error_callback && !ZVAL_IS_NULL(error_callback) && - !zend_is_callable(error_callback, 0, &name -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 2)) - TSRMLS_CC -#endif - )) { - php_error_docref1(NULL TSRMLS_CC, name, E_ERROR, "second argument is expected to be a valid error callback"); - efree(name); + !zend_is_callable(error_callback, 0, &name)) { + php_error_docref1(NULL, name->val, E_ERROR, "second argument is expected to be a valid error callback"); + zend_string_release(name); RETURN_FALSE; } if (name) { - efree(name); + zend_string_release(name); } - callstack = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), 0 TSRMLS_CC); + callstack = zend_read_static_property(yar_concurrent_client_ce, ZEND_STRL("_callstack"), 0); if (ZVAL_IS_NULL(callstack) || zend_hash_num_elements(Z_ARRVAL_P(callstack)) == 0) { RETURN_TRUE; } if (callback && !ZVAL_IS_NULL(callback)) { - zend_update_static_property(yar_concurrent_client_ce, ZEND_STRL("_callback"), callback TSRMLS_CC); + zend_update_static_property(yar_concurrent_client_ce, ZEND_STRL("_callback"), callback); } if (error_callback && !ZVAL_IS_NULL(error_callback)) { - zend_update_static_property(yar_concurrent_client_ce, ZEND_STRL("_error_callback"), error_callback TSRMLS_CC); + zend_update_static_property(yar_concurrent_client_ce, ZEND_STRL("_error_callback"), error_callback); } ZVAL_BOOL(status, 1); - ret = php_yar_concurrent_client_handle(callstack TSRMLS_CC); + ret = php_yar_concurrent_client_handle(callstack); ZVAL_BOOL(status, 0); RETURN_BOOL(ret); } @@ -790,6 +790,7 @@ zend_function_entry yar_client_methods[] = { zend_function_entry yar_concurrent_client_methods[] = { PHP_ME(yar_concurrent_client, call, arginfo_client_async, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(yar_concurrent_client, loop, arginfo_client_loop, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(yar_concurrent_client, reset, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_FE_END }; /* }}} */ @@ -798,19 +799,19 @@ YAR_STARTUP_FUNCTION(client) /* {{{ */ { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Yar_Client", yar_client_methods); - yar_client_ce = zend_register_internal_class(&ce TSRMLS_CC); + yar_client_ce = zend_register_internal_class(&ce); - zend_declare_property_long(yar_client_ce, ZEND_STRL("_protocol"), YAR_CLIENT_PROTOCOL_HTTP, ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_null(yar_client_ce, ZEND_STRL("_uri"), ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_null(yar_client_ce, ZEND_STRL("_options"), ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_null(yar_client_ce, ZEND_STRL("_running"), ZEND_ACC_PROTECTED TSRMLS_CC); + zend_declare_property_long(yar_client_ce, ZEND_STRL("_protocol"), YAR_CLIENT_PROTOCOL_HTTP, ZEND_ACC_PROTECTED); + zend_declare_property_null(yar_client_ce, ZEND_STRL("_uri"), ZEND_ACC_PROTECTED); + zend_declare_property_null(yar_client_ce, ZEND_STRL("_options"), ZEND_ACC_PROTECTED); + zend_declare_property_null(yar_client_ce, ZEND_STRL("_running"), ZEND_ACC_PROTECTED); INIT_CLASS_ENTRY(ce, "Yar_Concurrent_Client", yar_concurrent_client_methods); - yar_concurrent_client_ce = zend_register_internal_class(&ce TSRMLS_CC); - zend_declare_property_null(yar_concurrent_client_ce, ZEND_STRL("_callstack"), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC); - zend_declare_property_null(yar_concurrent_client_ce, ZEND_STRL("_callback"), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC); - zend_declare_property_null(yar_concurrent_client_ce, ZEND_STRL("_error_callback"), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC); - zend_declare_property_bool(yar_concurrent_client_ce, ZEND_STRL("_start"), 0, ZEND_ACC_PROTECTED|ZEND_ACC_STATIC TSRMLS_CC); + yar_concurrent_client_ce = zend_register_internal_class(&ce); + zend_declare_property_null(yar_concurrent_client_ce, ZEND_STRL("_callstack"), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC); + zend_declare_property_null(yar_concurrent_client_ce, ZEND_STRL("_callback"), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC); + zend_declare_property_null(yar_concurrent_client_ce, ZEND_STRL("_error_callback"), ZEND_ACC_PROTECTED|ZEND_ACC_STATIC); + zend_declare_property_bool(yar_concurrent_client_ce, ZEND_STRL("_start"), 0, ZEND_ACC_PROTECTED|ZEND_ACC_STATIC); REGISTER_LONG_CONSTANT("YAR_CLIENT_PROTOCOL_HTTP", YAR_CLIENT_PROTOCOL_HTTP, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("YAR_CLIENT_PROTOCOL_TCP", YAR_CLIENT_PROTOCOL_TCP, CONST_PERSISTENT | CONST_CS); diff --git a/yar_client.h b/yar_client.h index eb84cf7..a696b8f 100644 --- a/yar_client.h +++ b/yar_client.h @@ -27,6 +27,10 @@ #define YAR_CLIENT_PROTOCOL_UDP 3 #define YAR_CLIENT_PROTOCOL_UNIX 4 +#ifndef ZEND_FETCH_RESOURCE_NO_RETURN +#define ZEND_FETCH_RESOURCE_NO_RETURN(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type) \ + (rsrc = (rsrc_type) zend_fetch_resource(passed_id, default_id, resource_type_name, NULL, 1, resource_type)) +#endif YAR_STARTUP_FUNCTION(client); YAR_SHUTDOWN_FUNCTION(client); diff --git a/yar_exception.c b/yar_exception.c index a25b0ff..4b7c7e2 100644 --- a/yar_exception.c +++ b/yar_exception.c @@ -40,15 +40,15 @@ zend_class_entry *yar_client_transport_exception_ce; zend_class_entry *yar_client_packager_exception_ce; zend_class_entry *yar_client_protocol_exception_ce; -zend_class_entry * php_yar_get_exception_base(int root TSRMLS_DC) /* {{{ */ { +zend_class_entry * php_yar_get_exception_base(int root) /* {{{ */ { #if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)) if (!root) { if (!spl_ce_RuntimeException) { - zend_class_entry **pce; + zend_class_entry *pce; - if (zend_hash_find(CG(class_table), "runtimeexception", sizeof("RuntimeException"), (void **) &pce) == SUCCESS) { - spl_ce_RuntimeException = *pce; - return *pce; + if ((pce = zend_hash_str_find_ptr(CG(class_table), "runtimeexception", sizeof("RuntimeException") - 1)) != NULL) { + spl_ce_RuntimeException = pce; + return pce; } } else { return spl_ce_RuntimeException; @@ -56,30 +56,26 @@ zend_class_entry * php_yar_get_exception_base(int root TSRMLS_DC) /* {{{ */ { } #endif -#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) return zend_exception_get_default(); -#else - return zend_exception_get_default(TSRMLS_C); -#endif } /* }}} */ -void php_yar_error_ex(yar_response_t *response, int type TSRMLS_DC, const char *format, va_list args) /* {{{ */ { +void php_yar_error_ex(yar_response_t *response, int type, zval *zerr, const char *format, va_list args) /* {{{ */ { char *msg; uint len; len = vspprintf(&msg, 0, format, args); - php_yar_response_set_error(response, type, msg, len TSRMLS_CC); + php_yar_response_set_error(response, type, msg, len, zerr); efree(msg); return; } /* }}} */ -void php_yar_error(yar_response_t *response, int type TSRMLS_DC, const char *format, ...) /* {{{ */ { +void php_yar_error(yar_response_t *response, int type, zval *zerr, const char *format, ...) /* {{{ */ { va_list ap; va_start(ap, format); - php_yar_error_ex(response, type TSRMLS_CC, format, ap); + php_yar_error_ex(response, type, zerr, format, ap); va_end(ap); return; @@ -90,8 +86,8 @@ void php_yar_error(yar_response_t *response, int type TSRMLS_DC, const char *for */ PHP_METHOD(yar_exception_server, getType) { - zval *type; - type = zend_read_property(yar_server_exception_ce, getThis(), ZEND_STRL("_type"), 0 TSRMLS_CC); + zval *type, rv; + type = zend_read_property(yar_server_exception_ce, getThis(), ZEND_STRL("_type"), 0, &rv); RETURN_ZVAL(type, 1, 0); } @@ -101,7 +97,7 @@ PHP_METHOD(yar_exception_server, getType) */ PHP_METHOD(yar_exception_client, getType) { - RETURN_STRINGL("Yar_Exception_Client", sizeof("Yar_Exception_Client") - 1, 1); + RETURN_STRINGL("Yar_Exception_Client", sizeof("Yar_Exception_Client") - 1); } /* }}} */ @@ -123,32 +119,32 @@ YAR_STARTUP_FUNCTION(exception) /* {{{ */ { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Yar_Server_Exception", yar_exception_server_methods); - yar_server_exception_ce = zend_register_internal_class_ex(&ce, php_yar_get_exception_base(0 TSRMLS_CC), NULL TSRMLS_CC); + yar_server_exception_ce = zend_register_internal_class_ex(&ce, php_yar_get_exception_base(0)); INIT_CLASS_ENTRY(ce, "Yar_Server_Request_Exception", NULL); - yar_server_request_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce, NULL TSRMLS_CC); + yar_server_request_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce); INIT_CLASS_ENTRY(ce, "Yar_Server_Protocol_Exception", NULL); - yar_server_protocol_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce, NULL TSRMLS_CC); + yar_server_protocol_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce); INIT_CLASS_ENTRY(ce, "Yar_Server_Packager_Exception", NULL); - yar_server_packager_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce, NULL TSRMLS_CC); + yar_server_packager_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce); INIT_CLASS_ENTRY(ce, "Yar_Server_Output_Exception", NULL); - yar_server_output_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce, NULL TSRMLS_CC); + yar_server_output_exception_ce = zend_register_internal_class_ex(&ce, yar_server_exception_ce); INIT_CLASS_ENTRY(ce, "Yar_Client_Exception", yar_exception_client_methods); - yar_client_exception_ce = zend_register_internal_class_ex(&ce, php_yar_get_exception_base(0 TSRMLS_CC), NULL TSRMLS_CC); - zend_declare_property_stringl(yar_server_exception_ce, ZEND_STRL("_type"), ZEND_STRL("Yar_Exception_Server"), ZEND_ACC_PROTECTED TSRMLS_CC); + yar_client_exception_ce = zend_register_internal_class_ex(&ce, php_yar_get_exception_base(0)); + zend_declare_property_stringl(yar_server_exception_ce, ZEND_STRL("_type"), ZEND_STRL("Yar_Exception_Server"), ZEND_ACC_PROTECTED); INIT_CLASS_ENTRY(ce, "Yar_Client_Transport_Exception", NULL); - yar_client_transport_exception_ce = zend_register_internal_class_ex(&ce, yar_client_exception_ce, NULL TSRMLS_CC); + yar_client_transport_exception_ce = zend_register_internal_class_ex(&ce, yar_client_exception_ce); INIT_CLASS_ENTRY(ce, "Yar_Client_Packager_Exception", NULL); - yar_client_packager_exception_ce = zend_register_internal_class_ex(&ce, yar_client_exception_ce, NULL TSRMLS_CC); + yar_client_packager_exception_ce = zend_register_internal_class_ex(&ce, yar_client_exception_ce); INIT_CLASS_ENTRY(ce, "Yar_Client_Protocol_Exception", NULL); - yar_client_protocol_exception_ce = zend_register_internal_class_ex(&ce, yar_client_exception_ce, NULL TSRMLS_CC); + yar_client_protocol_exception_ce = zend_register_internal_class_ex(&ce, yar_client_exception_ce); REGISTER_LONG_CONSTANT("YAR_ERR_OKEY", YAR_ERR_OKEY, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("YAR_ERR_OUTPUT", YAR_ERR_OUTPUT, CONST_CS|CONST_PERSISTENT); diff --git a/yar_exception.h b/yar_exception.h index cf23fe9..ac0aa85 100644 --- a/yar_exception.h +++ b/yar_exception.h @@ -45,8 +45,8 @@ extern zend_class_entry *yar_client_protocol_exception_ce; extern void (*zend_orig_error_cb)(int, const char *, const uint, const char *, va_list); -void php_yar_error_ex(struct _yar_response *response, int type TSRMLS_DC, const char *format, va_list args); -void php_yar_error(struct _yar_response *response, int type TSRMLS_DC, const char *format, ...); +void php_yar_error_ex(struct _yar_response *response, int type, zval *zerr, const char *format, va_list args); +void php_yar_error(struct _yar_response *response, int type, zval *zerr, const char *format, ...); YAR_STARTUP_FUNCTION(exception); #ifndef EXPECTED diff --git a/yar_packager.c b/yar_packager.c index 838033d..822238e 100644 --- a/yar_packager.c +++ b/yar_packager.c @@ -33,7 +33,7 @@ struct _yar_packagers_list { yar_packager_t **packagers; } yar_packagers_list; -PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen TSRMLS_DC) /* {{{ */ { +PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen) /* {{{ */ { int i = 0; for (;iname, name, nlen) == 0) { @@ -44,7 +44,7 @@ PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen TSRMLS_DC return NULL; } /* }}} */ -PHP_YAR_API int php_yar_packager_register(yar_packager_t *packager TSRMLS_DC) /* {{{ */ { +PHP_YAR_API int php_yar_packager_register(yar_packager_t *packager) /* {{{ */ { if (!yar_packagers_list.size) { yar_packagers_list.size = 5; @@ -58,25 +58,25 @@ PHP_YAR_API int php_yar_packager_register(yar_packager_t *packager TSRMLS_DC) /* return yar_packagers_list.num++; } /* }}} */ -size_t php_yar_packager_pack(char *packager_name, zval *pzval, char **payload, char **msg TSRMLS_DC) /* {{{ */ { +size_t php_yar_packager_pack(char *packager_name, zval *pzval, zend_string **payload, char **msg) /* {{{ */ { smart_str buf = {0}; char header[8]; size_t newlen; - yar_packager_t *packager = packager_name? php_yar_packager_get(packager_name, strlen(packager_name) TSRMLS_CC) : YAR_G(packager); + yar_packager_t *packager = packager_name? php_yar_packager_get(packager_name, strlen(packager_name)) : YAR_G(packager); if (!packager) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "unsupported packager %s", packager_name); + php_error_docref(NULL, E_ERROR, "unsupported packager %s", packager_name); return 0; } memcpy(header, packager->name, 8); smart_str_alloc(&buf, YAR_PACKAGER_BUFFER_SIZE /* 1M */, 0); smart_str_appendl(&buf, header, 8); - packager->pack(packager, pzval, &buf, msg TSRMLS_CC); + packager->pack(packager, pzval, &buf, msg); - if (buf.c) { - *payload = buf.c; + if (buf.s) { + *payload = buf.s; smart_str_0(&buf); - return buf.len; + return buf.s->len; } smart_str_free(&buf); @@ -84,30 +84,30 @@ size_t php_yar_packager_pack(char *packager_name, zval *pzval, char **payload, c return 0; } /* }}} */ -zval * php_yar_packager_unpack(char *content, size_t len, char **msg TSRMLS_DC) /* {{{ */ { +zval * php_yar_packager_unpack(char *content, size_t len, char **msg, zval *rret) /* {{{ */ { char *pack_info = content; /* 4 bytes, last byte is version */ yar_packager_t *packager; content = content + 8; len -= 8; *(pack_info + 7) = '\0'; - packager = php_yar_packager_get(pack_info, strlen(pack_info) TSRMLS_CC); + packager = php_yar_packager_get(pack_info, strlen(pack_info)); if (!packager) { spprintf(msg, 0, "unsupported packager '%s'", pack_info); return NULL; } - return packager->unpack(packager, content, len, msg TSRMLS_CC); + return packager->unpack(packager, content, len, msg, rret); } /* }}} */ YAR_STARTUP_FUNCTION(packager) /* {{{ */ { #ifdef ENABLE_MSGPACK - php_yar_packager_register(&yar_packager_msgpack TSRMLS_CC); + php_yar_packager_register(&yar_packager_msgpack); #endif - php_yar_packager_register(&yar_packager_php TSRMLS_CC); - php_yar_packager_register(&yar_packager_json TSRMLS_CC); + php_yar_packager_register(&yar_packager_php); + php_yar_packager_register(&yar_packager_json); REGISTER_STRINGL_CONSTANT("YAR_PACKAGER_PHP", YAR_PACKAGER_PHP, sizeof(YAR_PACKAGER_PHP)-1, CONST_CS|CONST_PERSISTENT); REGISTER_STRINGL_CONSTANT("YAR_PACKAGER_JSON", YAR_PACKAGER_JSON, sizeof(YAR_PACKAGER_JSON)-1, CONST_CS|CONST_PERSISTENT); @@ -119,7 +119,7 @@ YAR_STARTUP_FUNCTION(packager) /* {{{ */ { } /* }}} */ YAR_ACTIVATE_FUNCTION(packager) /* {{{ */ { - yar_packager_t *packager = php_yar_packager_get(YAR_G(default_packager), strlen(YAR_G(default_packager)) TSRMLS_CC); + yar_packager_t *packager = php_yar_packager_get(YAR_G(default_packager), strlen(YAR_G(default_packager))); if (packager) { YAR_G(packager) = packager; diff --git a/yar_packager.h b/yar_packager.h index 9825fab..eaa97d8 100644 --- a/yar_packager.h +++ b/yar_packager.h @@ -22,7 +22,7 @@ #ifndef PHP_YAR_PACKAGER_H #define PHP_YAR_PACKAGER_H -#include "ext/standard/php_smart_str.h" +#include "zend_smart_str.h" #define YAR_PACKAGER_PHP "PHP" #define YAR_PACKAGER_JSON "JSON" @@ -32,12 +32,12 @@ typedef struct _yar_packager { const char *name; - int (*pack) (struct _yar_packager *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC); - zval * (*unpack) (struct _yar_packager *self, char *content, size_t len, char **msg TSRMLS_DC); + int (*pack) (struct _yar_packager *self, zval *pzval, smart_str *buf, char **msg); + zval * (*unpack) (struct _yar_packager *self, char *content, size_t len, char **msg, zval *rret); } yar_packager_t; -PHP_YAR_API int php_yar_packager_register(yar_packager_t *packager TSRMLS_DC); -PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen TSRMLS_DC); +PHP_YAR_API int php_yar_packager_register(yar_packager_t *packager); +PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen); YAR_STARTUP_FUNCTION(packager); YAR_ACTIVATE_FUNCTION(packager); @@ -48,8 +48,8 @@ extern yar_packager_t yar_packager_json; extern yar_packager_t yar_packager_msgpack; #endif -size_t php_yar_packager_pack(char *packager_name, zval *pzval, char **payload, char **msg TSRMLS_DC); -zval * php_yar_packager_unpack(char *content, size_t len, char **msg TSRMLS_DC); +size_t php_yar_packager_pack(char *packager_name, zval *pzval, zend_string **payload, char **msg); +zval * php_yar_packager_unpack(char *content, size_t len, char **msg, zval *rret); YAR_STARTUP_FUNCTION(packager); YAR_ACTIVATE_FUNCTION(packager); diff --git a/yar_protocol.c b/yar_protocol.c index c45a2b2..c9db38d 100644 --- a/yar_protocol.c +++ b/yar_protocol.c @@ -26,9 +26,11 @@ #include "php.h" #include "php_yar.h" #include "yar_protocol.h" +#if HAVE_ARPA_INET_H #include +#endif -void php_yar_protocol_render(yar_header_t *header, uint id, char *provider, char *token, uint body_len, uint reserved TSRMLS_DC) /* {{{ */ { +void php_yar_protocol_render(yar_header_t *header, uint id, char *provider, char *token, uint body_len, uint reserved) /* {{{ */ { header->magic_num = htonl(YAR_PROTOCOL_MAGIC_NUM); header->id = htonl(id); header->body_len = htonl(body_len); @@ -42,7 +44,7 @@ void php_yar_protocol_render(yar_header_t *header, uint id, char *provider, char return; } /* }}} */ -yar_header_t * php_yar_protocol_parse(char *payload TSRMLS_DC) /* {{{ */ { +yar_header_t * php_yar_protocol_parse(char *payload) /* {{{ */ { yar_header_t *header = (yar_header_t *)payload; header->magic_num = ntohl(header->magic_num); diff --git a/yar_protocol.h b/yar_protocol.h index 910ee59..75e50aa 100644 --- a/yar_protocol.h +++ b/yar_protocol.h @@ -49,8 +49,8 @@ yar_header_t; #pragma pack(pop) #endif -yar_header_t * php_yar_protocol_parse(char *payload TSRMLS_DC); -void php_yar_protocol_render(yar_header_t *header, uint id, char *provider, char *token, uint body_len, uint reserved TSRMLS_DC); +yar_header_t * php_yar_protocol_parse(char *payload); +void php_yar_protocol_render(yar_header_t *header, uint id, char *provider, char *token, uint body_len, uint reserved); #endif /* PHP_YAR_PROTOCOL_H */ diff --git a/yar_request.c b/yar_request.c index a9c405b..6222c3a 100644 --- a/yar_request.c +++ b/yar_request.c @@ -33,14 +33,14 @@ #include "yar_request.h" #include "yar_packager.h" -yar_request_t * php_yar_request_instance(char *method, long mlen, zval *params, zval *options TSRMLS_DC) /* {{{ */ { +yar_request_t * php_yar_request_instance(char *method, long mlen, zval *params, zval *options) /* {{{ */ { yar_request_t *request = ecalloc(1, sizeof(yar_request_t)); if (!BG(mt_rand_is_seeded)) { - php_mt_srand(GENERATE_SEED() TSRMLS_CC); + php_mt_srand(GENERATE_SEED()); } - request->id = (long)php_mt_rand(TSRMLS_C); + request->id = (long)php_mt_rand(); request->method = estrndup(method, mlen); request->mlen = mlen; @@ -57,9 +57,9 @@ yar_request_t * php_yar_request_instance(char *method, long mlen, zval *params, } /* }}} */ -yar_request_t * php_yar_request_unpack(zval *body TSRMLS_DC) /* {{{ */ { +yar_request_t * php_yar_request_unpack(zval *body) /* {{{ */ { yar_request_t *req; - zval **ppzval; + zval *pzval; HashTable *ht; req = (yar_request_t *)ecalloc(sizeof(yar_request_t), 1); @@ -69,95 +69,95 @@ yar_request_t * php_yar_request_unpack(zval *body TSRMLS_DC) /* {{{ */ { } ht = Z_ARRVAL_P(body); - if (zend_hash_find(ht, "i", sizeof("i"), (void**)&ppzval) == SUCCESS) { - if (IS_LONG != Z_TYPE_PP(ppzval)) { - convert_to_long(*ppzval); + if ((pzval = zend_hash_str_find(ht, "i", sizeof("i") - 1)) != NULL) { + if (IS_LONG != Z_TYPE_P(pzval)) { + convert_to_long(pzval); } - req->id = Z_LVAL_PP(ppzval); + req->id = Z_LVAL_P(pzval); } - if (zend_hash_find(ht, "m", sizeof("m"), (void**)&ppzval) == SUCCESS) { - if (IS_STRING != Z_TYPE_PP(ppzval)) { - convert_to_string(*ppzval); + if ((pzval = zend_hash_str_find(ht, "m", sizeof("m") - 1)) != NULL) { + if (IS_STRING != Z_TYPE_P(pzval)) { + convert_to_string(pzval); } - req->method = Z_STRVAL_PP(ppzval); - req->mlen = Z_STRLEN_PP(ppzval); - ZVAL_NULL(*ppzval); + req->method = Z_STRVAL_P(pzval); + req->mlen = Z_STRLEN_P(pzval); + ZVAL_NULL(pzval); } - if (zend_hash_find(ht, "p", sizeof("p"), (void**)&ppzval) == SUCCESS) { - if (IS_ARRAY != Z_TYPE_PP(ppzval)) { - convert_to_array(*ppzval); + if ((pzval = zend_hash_str_find(ht, "p", sizeof("p") - 1)) != NULL) { + if (IS_ARRAY != Z_TYPE_P(pzval)) { + convert_to_array(pzval); } - Z_ADDREF_P(*ppzval); - req->parameters = *ppzval; + Z_TRY_ADDREF_P(pzval); + req->parameters = pzval; } return req; } /* }}} */ -zval * php_yar_request_pack(yar_request_t *request, char **msg TSRMLS_DC) /* {{{ */ { +zval * php_yar_request_pack(yar_request_t *request, char **msg, zval *rret) /* {{{ */ { zval zreq, *ret; - char *payload, *packager_name = NULL; + zend_string *payload; + char *packager_name = NULL; size_t payload_len; /* @TODO: this is ugly, which needs options stash in request */ if (request->options && IS_ARRAY == Z_TYPE_P(request->options)) { - zval **ppzval; - if (zend_hash_index_find(Z_ARRVAL_P(request->options), YAR_OPT_PACKAGER, (void **)&ppzval) == SUCCESS - && IS_STRING == Z_TYPE_PP(ppzval)) { - packager_name = Z_STRVAL_PP(ppzval); + zval *pzval; + if ((pzval = zend_hash_index_find(Z_ARRVAL_P(request->options), YAR_OPT_PACKAGER)) != NULL + && IS_STRING == Z_TYPE_P(pzval)) { + packager_name = Z_STRVAL_P(pzval); } } - INIT_ZVAL(zreq); + ZVAL_UNDEF(&zreq); array_init(&zreq); - add_assoc_long_ex(&zreq, ZEND_STRS("i"), request->id); - add_assoc_stringl_ex(&zreq, ZEND_STRS("m"), request->method, request->mlen, 1); + add_assoc_long_ex(&zreq, ZEND_STRL("i"), request->id); + add_assoc_stringl_ex(&zreq, ZEND_STRL("m"), request->method, request->mlen); if (request->parameters) { - Z_ADDREF_P(request->parameters); - add_assoc_zval_ex(&zreq, ZEND_STRS("p"), request->parameters); + Z_TRY_ADDREF_P(request->parameters); + add_assoc_zval_ex(&zreq, ZEND_STRL("p"), request->parameters); } else { - zval *tmp; - MAKE_STD_ZVAL(tmp); - array_init(tmp); - add_assoc_zval_ex(&zreq, ZEND_STRS("p"), tmp); + zval tmp; + array_init(&tmp); + add_assoc_zval_ex(&zreq, ZEND_STRL("p"), &tmp); } - if (!(payload_len = php_yar_packager_pack(packager_name, &zreq, &payload, msg TSRMLS_CC))) { + if (!(payload_len = php_yar_packager_pack(packager_name, &zreq, &payload, msg))) { zval_dtor(&zreq); return NULL; } zval_dtor(&zreq); - MAKE_STD_ZVAL(ret); - ZVAL_STRINGL(ret, payload, payload_len, 0); + ZVAL_STR(rret, payload); + ret = rret; return ret; } /* }}} */ -void php_yar_request_destroy(yar_request_t *request TSRMLS_DC) /* {{{ */ { +void php_yar_request_destroy(yar_request_t *request) /* {{{ */ { if (request->method) { efree(request->method); } if (request->parameters) { - zval_ptr_dtor(&request->parameters); + zval_ptr_dtor(request->parameters); } if (request->options) { - zval_ptr_dtor(&request->options); + zval_ptr_dtor(request->options); } efree(request); } /* }}} */ -int php_yar_request_valid(yar_request_t *req, yar_response_t *response, char **msg TSRMLS_DC) /* {{{ */ { +int php_yar_request_valid(yar_request_t *req, yar_response_t *response, char **msg) /* {{{ */ { response->id = req->id; if (!req->method) { diff --git a/yar_request.h b/yar_request.h index 47ab3fd..7ac88ed 100644 --- a/yar_request.h +++ b/yar_request.h @@ -31,11 +31,11 @@ typedef struct _yar_request { zval *options; } yar_request_t; -yar_request_t * php_yar_request_unpack(zval *body TSRMLS_DC); -void php_yar_request_destroy(yar_request_t *request TSRMLS_DC); -zval * php_yar_request_pack(yar_request_t *request, char **msg TSRMLS_DC); -int php_yar_request_valid(yar_request_t *req, struct _yar_response *response, char **msg TSRMLS_DC); -yar_request_t * php_yar_request_instance(char *method, long mlen, zval *params, zval *options TSRMLS_DC); +yar_request_t * php_yar_request_unpack(zval *body); +void php_yar_request_destroy(yar_request_t *request); +zval * php_yar_request_pack(yar_request_t *request, char **msg, zval *rret); +int php_yar_request_valid(yar_request_t *req, struct _yar_response *response, char **msg); +yar_request_t * php_yar_request_instance(char *method, long mlen, zval *params, zval *options); #endif /* PHP_YAR_REQUEST_H */ diff --git a/yar_response.c b/yar_response.c index bc21cbb..cc0cece 100644 --- a/yar_response.c +++ b/yar_response.c @@ -29,110 +29,102 @@ #include "yar_request.h" #include "yar_response.h" -yar_response_t * php_yar_response_instance(TSRMLS_D) /* {{{ */ { - yar_response_t *response = ecalloc(sizeof(yar_response_t), 1); +yar_response_t * php_yar_response_instance() /* {{{ */ { + yar_response_t *response = ecalloc(1, sizeof(yar_response_t)); + ZVAL_UNDEF(&response->err); + ZVAL_UNDEF(&response->retval); return response; } /* }}} */ -int php_yar_response_bind_request(yar_response_t *response, yar_request_t *request TSRMLS_DC) /* {{{ */ { +int php_yar_response_bind_request(yar_response_t *response, yar_request_t *request) /* {{{ */ { response->id = request->id; return 1; } /* }}} */ -void php_yar_response_alter_body(yar_response_t *response, char *body, uint len, int method TSRMLS_DC) /* {{{ */ { +void php_yar_response_alter_body(yar_response_t *response, zend_string *body, int method) /* {{{ */ { response->out = body; - response->olen = len; } /* }}} */ -void php_yar_response_set_error(yar_response_t *response, int type, char *message, uint len TSRMLS_DC) /* {{{ */ { - zval *msg; +void php_yar_response_set_error(yar_response_t *response, int type, char *message, uint len, zval *zerr) /* {{{ */ { + ZVAL_STRINGL(&response->err, message, len); response->status = type; - MAKE_STD_ZVAL(msg); - ZVAL_STRINGL(msg, message, len, 1); - response->err = msg; } /* }}} */ -void php_yar_response_set_exception(yar_response_t *response, zval *ex TSRMLS_DC) /* {{{ */ { - zval *msg, *code, *file, *line, *ret; +void php_yar_response_set_exception(yar_response_t *response, zend_object *ex, zval *zerr) /* {{{ */ { + zval *msg, *code, *file, *line, ret; zend_class_entry *ce; + zval zv, rv; - ce = Z_OBJCE_P(ex); - msg = zend_read_property(ce, ex, ZEND_STRL("message"), 0 TSRMLS_CC); - code = zend_read_property(ce, ex, ZEND_STRL("code"), 0 TSRMLS_CC); - file = zend_read_property(ce, ex, ZEND_STRL("file"), 0 TSRMLS_CC); - line = zend_read_property(ce, ex, ZEND_STRL("line"), 0 TSRMLS_CC); + ZVAL_OBJ(&zv, ex); + ce = Z_OBJCE(zv); - MAKE_STD_ZVAL(ret); - array_init(ret); + msg = zend_read_property(ce, &zv, ZEND_STRL("message"), 0, &rv); + code = zend_read_property(ce, &zv, ZEND_STRL("code"), 0, &rv); + file = zend_read_property(ce, &zv, ZEND_STRL("file"), 0, &rv); + line = zend_read_property(ce, &zv, ZEND_STRL("line"), 0, &rv); - Z_ADDREF_P(msg); - Z_ADDREF_P(code); - Z_ADDREF_P(file); - Z_ADDREF_P(line); + array_init(zerr); - add_assoc_zval_ex(ret, ZEND_STRS("message"), msg); - add_assoc_zval_ex(ret, ZEND_STRS("code"), code); - add_assoc_zval_ex(ret, ZEND_STRS("file"), file); - add_assoc_zval_ex(ret, ZEND_STRS("line"), line); + Z_TRY_ADDREF_P(msg); + Z_TRY_ADDREF_P(code); + Z_TRY_ADDREF_P(file); + Z_TRY_ADDREF_P(line); - add_assoc_string_ex(ret, ZEND_STRS("_type"), (char *)ce->name, 1); + add_assoc_zval_ex(zerr, ZEND_STRL("message"), msg); + add_assoc_zval_ex(zerr, ZEND_STRL("code"), code); + add_assoc_zval_ex(zerr, ZEND_STRL("file"), file); + add_assoc_zval_ex(zerr, ZEND_STRL("line"), line); + + add_assoc_str_ex(zerr, ZEND_STRL("_type"), ce->name); response->status = YAR_ERR_EXCEPTION; - response->err = ret; - zval_ptr_dtor(&ex); + ZVAL_COPY(&response->err, zerr); } /* }}} */ -void php_yar_response_set_retval(yar_response_t *response, zval *retval TSRMLS_DC) /* {{{ */ { - response->retval = retval; +void php_yar_response_set_retval(yar_response_t *response, zval *retval) /* {{{ */ { + ZVAL_COPY(&response->retval, retval); } /* }}} */ -void php_yar_response_map_retval(yar_response_t *response, zval *ret TSRMLS_DC) /* {{{ */ { +void php_yar_response_map_retval(yar_response_t *response, zval *ret) /* {{{ */ { if (IS_ARRAY != Z_TYPE_P(ret)) { return; } else { - zval **ppzval; + zval *pzval; HashTable *ht = Z_ARRVAL_P(ret); - if (zend_hash_find(ht, ZEND_STRS("i"), (void **)&ppzval) == FAILURE) { + if ((pzval = zend_hash_str_find(ht, ZEND_STRL("i"))) == NULL) { return; } - convert_to_long(*ppzval); - response->id = Z_LVAL_PP(ppzval); + convert_to_long(pzval); + response->id = Z_LVAL_P(pzval); - if (zend_hash_find(ht, ZEND_STRS("s"), (void **)&ppzval) == FAILURE) { + if ((pzval = zend_hash_str_find(ht, ZEND_STRL("s"))) == NULL) { return; } - convert_to_long(*ppzval); - if ((response->status = Z_LVAL_PP(ppzval)) == YAR_ERR_OKEY) { - if (zend_hash_find(ht, ZEND_STRS("o"), (void **)&ppzval) == SUCCESS) { - response->out = Z_STRVAL_PP(ppzval); - response->olen = Z_STRLEN_PP(ppzval); - ZVAL_NULL(*ppzval); + convert_to_long(pzval); + if ((response->status = Z_LVAL_P(pzval)) == YAR_ERR_OKEY) { + if ((pzval = zend_hash_str_find(ht, ZEND_STRL("o"))) != NULL) { + response->out = Z_STR_P(pzval); + ZVAL_NULL(pzval); } - if (zend_hash_find(ht, ZEND_STRS("r"), (void **)&ppzval) == SUCCESS) { - Z_ADDREF_P(*ppzval); - response->retval = *ppzval; + if ((pzval = zend_hash_str_find(ht, ZEND_STRL("r"))) != NULL) { + ZVAL_COPY(&response->retval, pzval); } - } else if (zend_hash_find(ht, ZEND_STRS("e"), (void **)&ppzval) == SUCCESS) { - Z_ADDREF_P(*ppzval); - response->err = *ppzval; + } else if ((pzval = zend_hash_str_find(ht, ZEND_STRL("e"))) != NULL) { + ZVAL_COPY(&response->err, pzval); } } } /* }}} */ -void php_yar_response_destroy(yar_response_t *response TSRMLS_DC) /* {{{ */ { +void php_yar_response_destroy(yar_response_t *response) /* {{{ */ { if (response->out) { - efree(response->out); - } - - if (response->retval) { - zval_ptr_dtor(&response->retval); + zend_string_release(response->out); } - if (response->err) { + if (!Z_ISUNDEF(response->err)) { zval_ptr_dtor(&response->err); } diff --git a/yar_response.h b/yar_response.h index e3d3c29..e4beb01 100644 --- a/yar_response.h +++ b/yar_response.h @@ -29,20 +29,19 @@ typedef struct _yar_response { long id; int status; - char *out; - size_t olen; - zval *err; - zval *retval; + zend_string *out; + zval err; + zval retval; } yar_response_t; -yar_response_t * php_yar_response_instance(TSRMLS_D); -int php_yar_response_bind_request(yar_response_t *response, struct _yar_request *request TSRMLS_DC); -void php_yar_response_alter_body(yar_response_t *response, char *body, uint len, int method TSRMLS_DC); -void php_yar_response_set_error(yar_response_t *response, int type, char *message, uint len TSRMLS_DC); -void php_yar_response_set_exception(yar_response_t *response, zval *ex TSRMLS_DC); -void php_yar_response_set_retval(yar_response_t *response, zval *retval TSRMLS_DC); -void php_yar_response_map_retval(yar_response_t *response, zval *ret TSRMLS_DC); -void php_yar_response_destroy(yar_response_t *response TSRMLS_DC); +yar_response_t * php_yar_response_instance(); +int php_yar_response_bind_request(yar_response_t *response, struct _yar_request *request); +void php_yar_response_alter_body(yar_response_t *response, zend_string *body, int method); +void php_yar_response_set_error(yar_response_t *response, int type, char *message, uint len, zval *zerr); +void php_yar_response_set_exception(yar_response_t *response, zend_object *ex, zval *zerr); +void php_yar_response_set_retval(yar_response_t *response, zval *retval); +void php_yar_response_map_retval(yar_response_t *response, zval *ret); +void php_yar_response_destroy(yar_response_t *response); #endif /* PHP_YAR_RESPONSE_H */ diff --git a/yar_server.c b/yar_server.c index 20b1f50..566da52 100644 --- a/yar_server.c +++ b/yar_server.c @@ -105,9 +105,9 @@ ZEND_END_ARG_INFO() "" /* }}} */ -static char * php_yar_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{{ */ { +static char * php_yar_get_function_declaration(zend_function *fptr) /* {{{ */ { char *offset, *buf; - zend_uint length = 1024; + uint32_t length = 1024; #define REALLOC_BUF_IF_EXCEED(buf, offset, length, size) \ if (offset - buf + size >= length) { \ @@ -121,67 +121,57 @@ static char * php_yar_get_function_declaration(zend_function *fptr TSRMLS_DC) /* offset = buf = (char *)emalloc(length * sizeof(char)); -#if PHP_API_VERSION > 20090626 if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) { *(offset++) = '&'; *(offset++) = ' '; } -#endif if (fptr->common.scope) { - memcpy(offset, fptr->common.scope->name, fptr->common.scope->name_length); - offset += fptr->common.scope->name_length; + memcpy(offset, fptr->common.scope->name->val, fptr->common.scope->name->len); + offset += fptr->common.scope->name->len; *(offset++) = ':'; *(offset++) = ':'; } { - size_t name_len = strlen(fptr->common.function_name); + size_t name_len = fptr->common.function_name->len; REALLOC_BUF_IF_EXCEED(buf, offset, length, name_len); - memcpy(offset, fptr->common.function_name, name_len); + memcpy(offset, fptr->common.function_name->val, name_len); offset += name_len; } *(offset++) = '('; if (fptr->common.arg_info) { - zend_uint i, required; + uint32_t i, required; zend_arg_info *arg_info = fptr->common.arg_info; required = fptr->common.required_num_args; for (i = 0; i < fptr->common.num_args;) { if (arg_info->class_name) { const char *class_name; - zend_uint class_name_len; - if (!strcasecmp(arg_info->class_name, "self") && fptr->common.scope ) { - class_name = fptr->common.scope->name; - class_name_len = fptr->common.scope->name_length; - } else if (!strcasecmp(arg_info->class_name, "parent") && fptr->common.scope->parent) { - class_name = fptr->common.scope->parent->name; - class_name_len = fptr->common.scope->parent->name_length; + uint32_t class_name_len; + if (!strcasecmp(arg_info->class_name->val, "self") && fptr->common.scope ) { + class_name = fptr->common.scope->name->val; + class_name_len = fptr->common.scope->name->len; + } else if (!strcasecmp(arg_info->class_name->val, "parent") && fptr->common.scope->parent) { + class_name = fptr->common.scope->parent->name->val; + class_name_len = fptr->common.scope->parent->name->len; } else { - class_name = arg_info->class_name; - class_name_len = arg_info->class_name_len; + class_name = arg_info->class_name->val; + class_name_len = arg_info->class_name->len; } REALLOC_BUF_IF_EXCEED(buf, offset, length, class_name_len); memcpy(offset, class_name, class_name_len); offset += class_name_len; *(offset++) = ' '; -#if PHP_API_VERSION > 20090626 } else if (arg_info->type_hint) { - zend_uint type_name_len; + uint32_t type_name_len; char *type_name = zend_get_type_by_const(arg_info->type_hint); type_name_len = strlen(type_name); REALLOC_BUF_IF_EXCEED(buf, offset, length, type_name_len); memcpy(offset, type_name, type_name_len); offset += type_name_len; *(offset++) = ' '; -#else - } else if (arg_info->array_type_hint) { - REALLOC_BUF_IF_EXCEED(buf, offset, length, 5); - memcpy(offset, "array", 5); - offset += 5; - *(offset++) = ' '; -#endif } if (arg_info->pass_by_reference) { @@ -190,11 +180,11 @@ static char * php_yar_get_function_declaration(zend_function *fptr TSRMLS_DC) /* *(offset++) = '$'; if (arg_info->name) { - REALLOC_BUF_IF_EXCEED(buf, offset, length, arg_info->name_len); - memcpy(offset, arg_info->name, arg_info->name_len); - offset += arg_info->name_len; + REALLOC_BUF_IF_EXCEED(buf, offset, length, arg_info->name->len); + memcpy(offset, arg_info->name->val, arg_info->name->len); + offset += arg_info->name->len; } else { - zend_uint idx = i; + uint32_t idx = i; memcpy(offset, "param", 5); offset += 5; do { @@ -209,18 +199,14 @@ static char * php_yar_get_function_declaration(zend_function *fptr TSRMLS_DC) /* if (fptr->type == ZEND_USER_FUNCTION) { zend_op *precv = NULL; { - zend_uint idx = i; + uint32_t idx = i; zend_op *op = ((zend_op_array *)fptr)->opcodes; zend_op *end = op + ((zend_op_array *)fptr)->last; ++idx; while (op < end) { if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) - && op->op1.u.constant.value.lval == (long)idx -#else && op->op1.num == (long)idx -#endif ) { precv = op; } @@ -228,50 +214,37 @@ static char * php_yar_get_function_declaration(zend_function *fptr TSRMLS_DC) /* } } if (precv && precv->opcode == ZEND_RECV_INIT -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) - && precv->op2.op_type != IS_UNUSED -#else && precv->op2_type != IS_UNUSED -#endif ) { - zval *zv, zv_copy; + zval zv, zv_copy; int use_copy; - ALLOC_ZVAL(zv); -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) - *zv = precv->op2.u.constant; -#else - *zv = *precv->op2.zv; -#endif - zval_copy_ctor(zv); - INIT_PZVAL(zv); - zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); - if (Z_TYPE_P(zv) == IS_BOOL) { - if (Z_LVAL_P(zv)) { - memcpy(offset, "true", 4); - offset += 4; - } else { + ZVAL_DUP(&zv, RT_CONSTANT(&fptr->op_array, precv->op2)); + zval_update_constant_ex(&zv, 1, fptr->common.scope); + if (Z_TYPE(zv) == IS_TRUE) { + memcpy(offset, "true", 4); + offset += 4; + } else if (Z_TYPE(zv) == IS_FALSE) { memcpy(offset, "false", 5); offset += 5; - } - } else if (Z_TYPE_P(zv) == IS_NULL) { + } else if (Z_TYPE(zv) == IS_NULL) { memcpy(offset, "NULL", 4); offset += 4; - } else if (Z_TYPE_P(zv) == IS_STRING) { + } else if (Z_TYPE(zv) == IS_STRING) { *(offset++) = '\''; - REALLOC_BUF_IF_EXCEED(buf, offset, length, MIN(Z_STRLEN_P(zv), 10)); - memcpy(offset, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 10)); - offset += MIN(Z_STRLEN_P(zv), 10); - if (Z_STRLEN_P(zv) > 10) { + REALLOC_BUF_IF_EXCEED(buf, offset, length, MIN(Z_STRLEN(zv), 10)); + memcpy(offset, Z_STRVAL(zv), MIN(Z_STRLEN(zv), 10)); + offset += MIN(Z_STRLEN(zv), 10); + if (Z_STRLEN(zv) > 10) { *(offset++) = '.'; *(offset++) = '.'; *(offset++) = '.'; } *(offset++) = '\''; - } else if (Z_TYPE_P(zv) == IS_ARRAY) { + } else if (Z_TYPE(zv) == IS_ARRAY) { memcpy(offset, "Array", 5); offset += 5; } else { - zend_make_printable_zval(zv, &zv_copy, &use_copy); + use_copy = zend_make_printable_zval(&zv, &zv_copy); REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN(zv_copy)); memcpy(offset, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy)); offset += Z_STRLEN(zv_copy); @@ -302,13 +275,13 @@ static char * php_yar_get_function_declaration(zend_function *fptr TSRMLS_DC) /* } /* }}} */ -static int php_yar_print_info(void *ptr, void *argument TSRMLS_DC) /* {{{ */ { - zend_function *f = ptr; +static int php_yar_print_info(zval *ptr, void *argument) /* {{{ */ { + zend_function *f = Z_FUNC_P(ptr); if (f->common.fn_flags & ZEND_ACC_PUBLIC - && f->common.function_name && *(f->common.function_name) != '_') { + && f->common.function_name && *(f->common.function_name->val) != '_') { char *prototype = NULL; - if ((prototype = php_yar_get_function_declaration(f TSRMLS_CC))) { + if ((prototype = php_yar_get_function_declaration(f))) { char *buf, *doc_comment = NULL; if (f->type == ZEND_USER_FUNCTION) { doc_comment = (char *)f->op_array.doc_comment; @@ -323,99 +296,98 @@ static int php_yar_print_info(void *ptr, void *argument TSRMLS_DC) /* {{{ */ { return ZEND_HASH_APPLY_KEEP; } /* }}} */ -static void php_yar_server_response_header(size_t content_lenth, void *packager_info TSRMLS_DC) /* {{{ */ { +static void php_yar_server_response_header(size_t content_lenth, void *packager_info) /* {{{ */ { sapi_header_line ctr = {0}; char header_line[512]; ctr.line_len = snprintf(header_line, sizeof(header_line), "Content-Length: %ld", content_lenth); ctr.line = header_line; - sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_header_op(SAPI_HEADER_REPLACE, &ctr); ctr.line_len = snprintf(header_line, sizeof(header_line), "Content-Type: %s", YAR_G(content_type)); ctr.line = header_line; - sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_header_op(SAPI_HEADER_REPLACE, &ctr); ctr.line_len = snprintf(header_line, sizeof(header_line), "Cache-Control: no-cache"); ctr.line = header_line; - sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_header_op(SAPI_HEADER_REPLACE, &ctr); /* ctr.line_len = snprintf(header_line, sizeof(header_line), "Connection: Keep-Alive"); ctr.line = header_line; - sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_header_op(SAPI_HEADER_REPLACE, &ctr); */ - php_header(TSRMLS_C); + php_header(); return; } /* }}} */ -static void php_yar_server_response(yar_request_t *request, yar_response_t *response, char *pkg_name TSRMLS_DC) /* {{{ */ { - zval ret; - char *payload, *err_msg; +static void php_yar_server_response(yar_request_t *request, yar_response_t *response, char *pkg_name) /* {{{ */ { + zval ret, zerr; + char *err_msg; + zend_string *payload; size_t payload_len; yar_header_t header = {0}; - INIT_ZVAL(ret); array_init(&ret); - add_assoc_long_ex(&ret, ZEND_STRS("i"), response->id); - add_assoc_long_ex(&ret, ZEND_STRS("s"), response->status); - if (response->out) { - add_assoc_string_ex(&ret, ZEND_STRS("o"), response->out, 1); + add_assoc_long_ex(&ret, ZEND_STRL("i"), response->id); + add_assoc_long_ex(&ret, ZEND_STRL("s"), response->status); + if (response->out && response->out->len) { + add_assoc_str_ex(&ret, ZEND_STRL("o"), response->out); } - if (response->retval) { - Z_ADDREF_P(response->retval); - add_assoc_zval_ex(&ret, ZEND_STRS("r"), response->retval); + if (!Z_ISUNDEF(response->retval)) { + Z_TRY_ADDREF(response->retval); + add_assoc_zval_ex(&ret, ZEND_STRL("r"), &response->retval); } - if (response->err) { - Z_ADDREF_P(response->err); - add_assoc_zval_ex(&ret, ZEND_STRS("e"), response->err); + if (!Z_ISUNDEF(response->err)) { + Z_TRY_ADDREF(response->err); + add_assoc_zval_ex(&ret, ZEND_STRL("e"), &response->err); } - if (!(payload_len = php_yar_packager_pack(pkg_name, &ret, &payload, &err_msg TSRMLS_CC))) { + if (!(payload_len = php_yar_packager_pack(pkg_name, &ret, &payload, &err_msg))) { zval_dtor(&ret); - php_yar_error(response, YAR_ERR_PACKAGER TSRMLS_CC, "%s", err_msg); + php_yar_error(response, YAR_ERR_PACKAGER, &zerr, "%s", err_msg); efree(err_msg); return; } zval_dtor(&ret); - php_yar_protocol_render(&header, request->id, "PHP Yar Server", NULL, payload_len, 0 TSRMLS_CC); + php_yar_protocol_render(&header, request? request->id : 0, "PHP Yar Server", NULL, payload_len, 0); DEBUG_S("%ld: server response: packager '%s', len '%ld', content '%.32s'", - request->id, payload, payload_len - 8, payload + 8); + request? request->id : 0, payload->val, payload_len - 8, payload + 8); - php_yar_server_response_header(sizeof(yar_header_t) + payload_len, payload TSRMLS_CC); + php_yar_server_response_header(sizeof(yar_header_t) + payload_len, payload->val); PHPWRITE((char *)&header, sizeof(yar_header_t)); if (payload_len) { - PHPWRITE(payload, payload_len); - efree(payload); + PHPWRITE(payload->val, payload_len); return; } return; } /* }}} */ -static void php_yar_server_handle(zval *obj TSRMLS_DC) /* {{{ */ { +static void php_yar_server_handle(zval *obj) /* {{{ */ { char *payload, *err_msg, method[256]; char *pkg_name = NULL; size_t payload_len; zend_bool bailout = 0; - zval *post_data = NULL, output, func; + zval zerr; + zval *post_data = NULL, output, func, rret; zend_class_entry *ce; yar_response_t *response; yar_request_t *request = NULL; yar_header_t *header; -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 php_stream *s; smart_str raw_data = {0}; -#endif - response = php_yar_response_instance(TSRMLS_C); -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 + response = php_yar_response_instance(); s = SG(request_info).request_body; if (!s || FAILURE == php_stream_rewind(s)) { + php_yar_error(response, YAR_ERR_PACKAGER, &zerr, "empty request"); + DEBUG_S("0: empty request"); goto response_no_output; } memset(&raw_data, 0, sizeof(raw_data)); @@ -427,22 +399,17 @@ static void php_yar_server_handle(zval *obj TSRMLS_DC) /* {{{ */ { smart_str_appendl(&raw_data, buf, len); } } - payload = raw_data.c; - payload_len = raw_data.len; -#else - if (!SG(request_info).raw_post_data) { - goto response_no_output; - } - payload = SG(request_info).raw_post_data; - payload_len = SG(request_info).raw_post_data_length; -#endif + if (raw_data.s) { + payload = raw_data.s->val; + payload_len = raw_data.s->len; + } - if (!(header = php_yar_protocol_parse(payload TSRMLS_CC))) { -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 - smart_str_free(&raw_data); -#endif - php_yar_error(response, YAR_ERR_PACKAGER TSRMLS_CC, "malformed request header '%.10s'", payload TSRMLS_CC); + if (!(header = php_yar_protocol_parse(payload))) { + if (raw_data.s) { + smart_str_free(&raw_data); + } + php_yar_error(response, YAR_ERR_PACKAGER, &zerr, "malformed request header '%.10s'", payload); DEBUG_S("0: malformed request '%s'", payload); goto response_no_output; } @@ -454,169 +421,115 @@ static void php_yar_server_handle(zval *obj TSRMLS_DC) /* {{{ */ { payload += sizeof(yar_header_t); payload_len -= sizeof(yar_header_t); - if (!(post_data = php_yar_packager_unpack(payload, payload_len, &err_msg TSRMLS_CC))) { -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 + if (!(post_data = php_yar_packager_unpack(payload, payload_len, &err_msg, &rret))) { smart_str_free(&raw_data); -#endif - php_yar_error(response, YAR_ERR_PACKAGER TSRMLS_CC, err_msg); + php_yar_error(response, YAR_ERR_PACKAGER, &zerr, err_msg); efree(err_msg); goto response_no_output; } pkg_name = payload; - request = php_yar_request_unpack(post_data TSRMLS_CC); - zval_ptr_dtor(&post_data); - ce = Z_OBJCE_P(obj); + request = php_yar_request_unpack(post_data); + zval_ptr_dtor(post_data); - if (!php_yar_request_valid(request, response, &err_msg TSRMLS_CC)) { -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 + if (!php_yar_request_valid(request, response, &err_msg)) { smart_str_free(&raw_data); -#endif - php_yar_error(response, YAR_ERR_REQUEST TSRMLS_CC, "%s", err_msg); + php_yar_error(response, YAR_ERR_REQUEST, &zerr, "%s", err_msg); efree(err_msg); goto response_no_output; } -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) - if (php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC) != SUCCESS) { -#else - if (php_output_start_user(NULL, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC) == FAILURE) { -#endif -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 + if (php_output_start_user(NULL, 0, PHP_OUTPUT_HANDLER_STDFLAGS) == FAILURE) { smart_str_free(&raw_data); -#endif - php_yar_error(response, YAR_ERR_OUTPUT TSRMLS_CC, "start output buffer failed"); + php_yar_error(response, YAR_ERR_OUTPUT, &zerr, "start output buffer failed"); goto response_no_output; } ce = Z_OBJCE_P(obj); zend_str_tolower_copy(method, request->method, request->mlen); - if (!zend_hash_exists(&ce->function_table, method, strlen(method) + 1)) { -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 + if (!zend_hash_str_exists(&ce->function_table, method, strlen(method))) { smart_str_free(&raw_data); -#endif - php_yar_error(response, YAR_ERR_REQUEST TSRMLS_CC, "call to undefined api %s::%s()", ce->name, request->method); + php_yar_error(response, YAR_ERR_REQUEST, &zerr, "call to undefined api %s::%s()", ce->name, request->method); goto response; } zend_try { uint count; - zval ***func_params; - zval *retval_ptr = NULL; + zval *func_params; + zval *tmp_zval; + zval retval; HashTable *func_params_ht; - INIT_ZVAL(output); -#if 0 - if (zend_hash_exists(&ce->function_table, ZEND_STRS("__auth"))) { - zval *provider, *token; - MAKE_STD_ZVAL(provider); - MAKE_STD_ZVAL(token); - if (header->provider) { - ZVAL_STRING(provider, (char *)header->provider, 1); - } else { - ZVAL_NULL(provider); - } - - if (header->token) { - ZVAL_STRING(token, (char *)header->token, 1); - } else { - ZVAL_NULL(token); - } - - func_params = emalloc(sizeof(zval **) * 2); - func_params[0] = &provider; - func_params[1] = &token; - - ZVAL_STRINGL(&func, "__auth", sizeof("__auth") - 1, 0); - if (call_user_function_ex(NULL, &obj, &func, &retval_ptr, 2, func_params, 0, NULL TSRMLS_CC) != SUCCESS) { - efree(func_params); - zval_ptr_dtor(&token); - zval_ptr_dtor(&provider); - php_yar_error(response, YAR_ERR_REQUEST TSRMLS_CC, "call to api %s::%s() failed", ce->name, Z_STRVAL(func)); - goto response; - } - - efree(func_params); - func_params = NULL; - zval_ptr_dtor(&token); - zval_ptr_dtor(&provider); - - if (retval_ptr) { - if (Z_TYPE_P(retval_ptr) == IS_BOOL && !Z_BVAL_P(retval_ptr)) { - zval_ptr_dtor(&retval_ptr); - php_yar_error(response, YAR_ERR_REQUEST TSRMLS_CC, "%s::__auth() return false", ce->name); - goto response; - } - zval_ptr_dtor(&retval_ptr); - retval_ptr = NULL; - } - } -#endif - func_params_ht = Z_ARRVAL_P(request->parameters); count = zend_hash_num_elements(func_params_ht); + ZVAL_UNDEF(&retval); if (count) { - uint i = 0; - func_params = emalloc(sizeof(zval **) * count); + func_params = safe_emalloc(sizeof(zval), count, 0); + int i = 0; - for (zend_hash_internal_pointer_reset(func_params_ht); - zend_hash_get_current_data(func_params_ht, (void **) &func_params[i++]) == SUCCESS; - zend_hash_move_forward(func_params_ht) - ); + ZEND_HASH_FOREACH_VAL(func_params_ht, tmp_zval) { + ZVAL_COPY(&func_params[i], tmp_zval); + i++; + } ZEND_HASH_FOREACH_END(); } else { func_params = NULL; } - ZVAL_STRINGL(&func, request->method, request->mlen, 0); - if (call_user_function_ex(NULL, &obj, &func, &retval_ptr, count, func_params, 0, NULL TSRMLS_CC) != SUCCESS) { - if (func_params) { - efree(func_params); + ZVAL_STRINGL(&func, request->method, request->mlen); + efree(request->method); + if (FAILURE == call_user_function_ex(NULL, obj, &func, &retval, count, func_params, 0, NULL)) { + if (count) { + int i = 0; + for (; i < count; i++) { + zval_ptr_dtor(&func_params[i]); + } } - php_yar_error(response, YAR_ERR_REQUEST TSRMLS_CC, "call to api %s::%s() failed", ce->name, request->method); + zval_dtor(&func); + php_yar_error(response, YAR_ERR_REQUEST, &zerr, "call to api %s::%s() failed", ce->name, request->method); goto response; } - if (func_params) { - efree(func_params); + if (!Z_ISUNDEF(retval)) { + php_yar_response_set_retval(response, &retval); } - if (retval_ptr) { - php_yar_response_set_retval(response, retval_ptr TSRMLS_CC); + if (count) { + int i = 0; + for (; i < count; i++) { + zval_ptr_dtor(&func_params[i]); + } } + zval_dtor(&func); + zval_dtor(&retval); } zend_catch { bailout = 1; } zend_end_try(); if (EG(exception)) { - php_yar_response_set_exception(response, EG(exception) TSRMLS_CC); + php_yar_response_set_exception(response, EG(exception), &zerr); EG(exception) = NULL; } -#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 5 smart_str_free(&raw_data); -#endif response: -#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) - php_ob_get_buffer(&output TSRMLS_CC); - php_end_ob_buffer(0, 0 TSRMLS_CC); -#else - if (php_output_get_contents(&output TSRMLS_CC) == FAILURE) { - php_output_end(TSRMLS_C); - php_yar_error(response, YAR_ERR_OUTPUT TSRMLS_CC, "unable to get ob content"); + if (php_output_get_contents(&output) == FAILURE) { + php_output_end(); + php_yar_error(response, YAR_ERR_OUTPUT, &zerr, "unable to get ob content"); goto response_no_output; } - php_output_discard(TSRMLS_C); -#endif - php_yar_response_alter_body(response, Z_STRVAL(output), Z_STRLEN(output), YAR_RESPONSE_REPLACE TSRMLS_CC); + php_output_discard(); + php_yar_response_alter_body(response, Z_STR(output), YAR_RESPONSE_REPLACE); response_no_output: - php_yar_server_response(request, response, pkg_name TSRMLS_CC); - php_yar_request_destroy(request TSRMLS_CC); - php_yar_response_destroy(response TSRMLS_CC); + php_yar_server_response(request, response, pkg_name); + if (request) { + php_yar_request_destroy(request); + } + php_yar_response_destroy(response); if (bailout) { zend_bailout(); @@ -625,20 +538,20 @@ static void php_yar_server_handle(zval *obj TSRMLS_DC) /* {{{ */ { return; } /* }}} */ -static void php_yar_server_info(zval *obj TSRMLS_DC) /* {{{ */ { +static void php_yar_server_info(zval *obj) /* {{{ */ { char buf[1024]; zend_class_entry *ce = Z_OBJCE_P(obj); - snprintf(buf, sizeof(buf), HTML_MARKUP_HEADER, ce->name); + snprintf(buf, sizeof(buf), HTML_MARKUP_HEADER, ce->name->val); PHPWRITE(buf, strlen(buf)); PHPWRITE(HTML_MARKUP_CSS, sizeof(HTML_MARKUP_CSS) - 1); PHPWRITE(HTML_MARKUP_SCRIPT, sizeof(HTML_MARKUP_SCRIPT) - 1); - snprintf(buf, sizeof(buf), HTML_MARKUP_TITLE, ce->name); + snprintf(buf, sizeof(buf), HTML_MARKUP_TITLE, ce->name->val); PHPWRITE(buf, strlen(buf)); - zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)php_yar_print_info, (void *)(ce) TSRMLS_CC); + zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)php_yar_print_info, (void *)(ce)); PHPWRITE(HTML_MARKUP_FOOTER, sizeof(HTML_MARKUP_FOOTER) - 1); } @@ -649,11 +562,11 @@ static void php_yar_server_info(zval *obj TSRMLS_DC) /* {{{ */ { PHP_METHOD(yar_server, __construct) { zval *obj; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) { return; } - zend_update_property(yar_server_ce, getThis(), "_executor", sizeof("_executor")-1, obj TSRMLS_CC); + zend_update_property(yar_server_ce, getThis(), "_executor", sizeof("_executor")-1, obj); } /* }}} */ @@ -662,30 +575,30 @@ PHP_METHOD(yar_server, __construct) { PHP_METHOD(yar_server, handle) { if (SG(headers_sent)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "headers already has been sent"); + php_error_docref(NULL, E_WARNING, "headers already has been sent"); RETURN_FALSE; } else { const char *method; - zval *executor = NULL; + zval *executor = NULL, rv; - executor = zend_read_property(yar_server_ce, getThis(), ZEND_STRL("_executor"), 0 TSRMLS_CC); + executor = zend_read_property(yar_server_ce, getThis(), ZEND_STRL("_executor"), 0, &rv); if (!executor || IS_OBJECT != Z_TYPE_P(executor)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "executor is not a valid object"); + php_error_docref(NULL, E_WARNING, "executor is not a valid object"); RETURN_FALSE; } method = SG(request_info).request_method; if (!method || strncasecmp(method, "POST", 4)) { if (YAR_G(expose_info)) { - php_yar_server_info(executor TSRMLS_CC); + php_yar_server_info(executor); RETURN_TRUE; } else { - zend_throw_exception(yar_server_exception_ce, "server info is not allowed to access", YAR_ERR_FORBIDDEN TSRMLS_CC); + zend_throw_exception(yar_server_exception_ce, "server info is not allowed to access", YAR_ERR_FORBIDDEN); return; } } - php_yar_server_handle(executor TSRMLS_CC); + php_yar_server_handle(executor); } RETURN_TRUE; @@ -704,8 +617,8 @@ YAR_STARTUP_FUNCTION(service) /* {{{ */ { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Yar_Server", yar_server_methods); - yar_server_ce = zend_register_internal_class(&ce TSRMLS_CC); - zend_declare_property_null(yar_server_ce, ZEND_STRL("_executor"), ZEND_ACC_PROTECTED TSRMLS_CC); + yar_server_ce = zend_register_internal_class(&ce); + zend_declare_property_null(yar_server_ce, ZEND_STRL("_executor"), ZEND_ACC_PROTECTED); return SUCCESS; } diff --git a/yar_transport.c b/yar_transport.c index 01b1cc8..90a05f9 100644 --- a/yar_transport.c +++ b/yar_transport.c @@ -40,14 +40,14 @@ struct _yar_transports_list { extern yar_transport_t yar_transport_curl; extern yar_transport_t yar_transport_socket; -static void php_yar_plink_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ { +static void php_yar_plink_dtor(zend_resource *rsrc) /* {{{ */ { yar_persistent_le_t *le = (yar_persistent_le_t *)rsrc->ptr; - le->dtor(le->ptr TSRMLS_CC); + le->dtor(le->ptr); free(le); } /* }}} */ -static void php_yar_calldata_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ { +static void php_yar_calldata_dtor(zend_resource *rsrc) /* {{{ */ { yar_call_data_t *entry = (yar_call_data_t *)rsrc->ptr; if (entry->uri) { @@ -58,23 +58,19 @@ static void php_yar_calldata_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ * efree(entry->method); } - if (entry->callback) { - zval_ptr_dtor(&entry->callback); - } - if (entry->parameters) { - zval_ptr_dtor(&entry->parameters); + zval_ptr_dtor(entry->parameters); } if (entry->options) { - zval_ptr_dtor(&entry->options); + zval_ptr_dtor(entry->options); } efree(entry); } /* }}} */ -PHP_YAR_API yar_transport_t * php_yar_transport_get(char *name, int nlen TSRMLS_DC) /* {{{ */ { +PHP_YAR_API yar_transport_t * php_yar_transport_get(char *name, int nlen) /* {{{ */ { int i = 0; for (;iname, name, nlen) == 0) { @@ -85,7 +81,7 @@ PHP_YAR_API yar_transport_t * php_yar_transport_get(char *name, int nlen TSRMLS_ return NULL; } /* }}} */ -PHP_YAR_API int php_yar_transport_register(yar_transport_t *transport TSRMLS_DC) /* {{{ */ { +PHP_YAR_API int php_yar_transport_register(yar_transport_t *transport) /* {{{ */ { if (!yar_transports_list.size) { yar_transports_list.size = 5; @@ -100,8 +96,8 @@ PHP_YAR_API int php_yar_transport_register(yar_transport_t *transport TSRMLS_DC) } /* }}} */ YAR_STARTUP_FUNCTION(transport) /* {{{ */ { - php_yar_transport_register(&yar_transport_curl TSRMLS_CC); - php_yar_transport_register(&yar_transport_socket TSRMLS_CC); + php_yar_transport_register(&yar_transport_curl); + php_yar_transport_register(&yar_transport_socket); le_calldata = zend_register_list_destructors_ex(php_yar_calldata_dtor, NULL, "Yar Call Data", module_number); le_plink = zend_register_list_destructors_ex(NULL, php_yar_plink_dtor, "Yar Persistent Link", module_number); diff --git a/yar_transport.h b/yar_transport.h index cf7b2b4..fb117e4 100644 --- a/yar_transport.h +++ b/yar_transport.h @@ -40,44 +40,44 @@ typedef struct _yar_call_data { typedef struct _yar_persistent_le { void *ptr; - void (*dtor)(void *ptr TSRMLS_DC); + void (*dtor)(void *ptr); } yar_persistent_le_t; -typedef int yar_concurrent_client_callback(yar_call_data_t *calldata, int status, struct _yar_response *response TSRMLS_DC); +typedef int yar_concurrent_client_callback(yar_call_data_t *calldata, int status, struct _yar_response *response); typedef struct _yar_transport_interface { void *data; - int (*open)(struct _yar_transport_interface *self, char *address, uint len, long options, char **msg TSRMLS_DC); - int (*send)(struct _yar_transport_interface *self, struct _yar_request *request, char **msg TSRMLS_DC); - struct _yar_response * (*exec)(struct _yar_transport_interface *self, struct _yar_request *request TSRMLS_DC); - int (*setopt)(struct _yar_transport_interface *self, long type, void *value, void *addition TSRMLS_DC); - int (*calldata)(struct _yar_transport_interface *self, yar_call_data_t *calldata TSRMLS_DC); - void (*close)(struct _yar_transport_interface *self TSRMLS_DC); + int (*open)(struct _yar_transport_interface *self, char *address, uint len, long options, char **msg); + int (*send)(struct _yar_transport_interface *self, struct _yar_request *request, char **msg); + struct _yar_response * (*exec)(struct _yar_transport_interface *self, struct _yar_request *request, zval *zerr); + int (*setopt)(struct _yar_transport_interface *self, long type, void *value, void *addition); + int (*calldata)(struct _yar_transport_interface *self, yar_call_data_t *calldata); + void (*close)(struct _yar_transport_interface *self); } yar_transport_interface_t; typedef struct _yar_transport_multi_interface { void *data; - int (*add)(struct _yar_transport_multi_interface *self, yar_transport_interface_t *cp TSRMLS_DC); - int (*exec)(struct _yar_transport_multi_interface *self, yar_concurrent_client_callback *callback TSRMLS_DC); - void (*close)(struct _yar_transport_multi_interface *self TSRMLS_DC); + int (*add)(struct _yar_transport_multi_interface *self, yar_transport_interface_t *cp); + int (*exec)(struct _yar_transport_multi_interface *self, yar_concurrent_client_callback *callback); + void (*close)(struct _yar_transport_multi_interface *self); } yar_transport_multi_interface_t; typedef struct _yar_transport_multi { - struct _yar_transport_multi_interface * (*init)(TSRMLS_D); + struct _yar_transport_multi_interface * (*init)(); } yar_transport_multi_t; typedef struct _yar_transport { const char *name; - struct _yar_transport_interface * (*init)(TSRMLS_D); - void (*destroy)(yar_transport_interface_t *self TSRMLS_DC); + struct _yar_transport_interface * (*init)(); + void (*destroy)(yar_transport_interface_t *self); yar_transport_multi_t *multi; } yar_transport_t; extern int le_calldata; extern int le_plink; -PHP_YAR_API yar_transport_t * php_yar_transport_get(char *name, int nlen TSRMLS_DC); -PHP_YAR_API int php_yar_transport_register(yar_transport_t *transport TSRMLS_DC); +PHP_YAR_API yar_transport_t * php_yar_transport_get(char *name, int nlen); +PHP_YAR_API int php_yar_transport_register(yar_transport_t *transport); YAR_STARTUP_FUNCTION(transport); YAR_SHUTDOWN_FUNCTION(transport); diff --git a/yar_transports.h b/yar_transports.h index 879947d..5e52abd 100644 --- a/yar_transports.h +++ b/yar_transports.h @@ -24,12 +24,12 @@ typedef struct _yar_protocol { const char *name; - int (*request) (struct _yar_protocol *self, struct _yar_request *request, struct _yar_response *response TSRMLS_DC); - int (*async) (zval *callstack TSRMLS_DC); + int (*request) (struct _yar_protocol *self, struct _yar_request *request, struct _yar_response *response); + int (*async) (zval *callstack); } yar_protocol_t; -PHP_YAR_API int php_yar_protocol_register(yar_protocol_t *protocol TSRMLS_DC); -PHP_YAR_API yar_protocol_t * php_yar_protocol_get(char *name, int nlen TSRMLS_DC); +PHP_YAR_API int php_yar_protocol_register(yar_protocol_t *protocol); +PHP_YAR_API yar_protocol_t * php_yar_protocol_get(char *name, int nlen); YAR_STARTUP_FUNCTION(protocol);