Skip to content

Commit 048e4b2

Browse files
getLastError method
1 parent dc36368 commit 048e4b2

File tree

5 files changed

+84
-4
lines changed

5 files changed

+84
-4
lines changed

common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ typedef struct {
184184

185185
request_item *pipeline_head;
186186
request_item *pipeline_current;
187+
188+
char *err;
189+
int err_len;
187190
} RedisSock;
188191
/* }}} */
189192

library.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,9 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por
818818
redis_sock->pipeline_head = NULL;
819819
redis_sock->pipeline_current = NULL;
820820

821+
redis_sock->err = NULL;
822+
redis_sock->err_len = 0;
823+
821824
return redis_sock;
822825
}
823826

@@ -972,6 +975,37 @@ PHPAPI void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_so
972975
RETURN_FALSE;
973976
}
974977

978+
/**
979+
* redis_sock_set_err
980+
*/
981+
PHPAPI int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len) {
982+
// Allocate/Reallocate our last error member
983+
if(msg != NULL && msg_len > 0) {
984+
if(redis_sock->err == NULL) {
985+
redis_sock->err = emalloc(msg_len + 1);
986+
} else if(msg_len > redis_sock->err_len) {
987+
redis_sock->err = erealloc(redis_sock->err, msg_len +1);
988+
}
989+
990+
// Copy in our new error message, set new length, and null terminate
991+
memcpy(redis_sock->err, msg, msg_len);
992+
redis_sock->err[msg_len] = '\0';
993+
redis_sock->err_len = msg_len;
994+
} else {
995+
// Free our last error
996+
if(redis_sock->err != NULL) {
997+
efree(redis_sock->err);
998+
}
999+
1000+
// Set to null, with zero length
1001+
redis_sock->err = NULL;
1002+
redis_sock->err_len = 0;
1003+
}
1004+
1005+
// Success
1006+
return 0;
1007+
}
1008+
9751009
/**
9761010
* redis_sock_read_multibulk_reply
9771011
*/
@@ -1170,6 +1204,9 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
11701204
if(redis_sock->prefix) {
11711205
efree(redis_sock->prefix);
11721206
}
1207+
if(redis_sock->err) {
1208+
efree(redis_sock->err);
1209+
}
11731210
efree(redis_sock->host);
11741211
efree(redis_sock);
11751212
}
@@ -1310,7 +1347,7 @@ redis_key_prefix(RedisSock *redis_sock, char **key, int *key_len TSRMLS_DC) {
13101347
*/
13111348

13121349
PHPAPI int
1313-
redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, int *line_size) {
1350+
redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, size_t *line_size) {
13141351
// Handle EOF
13151352
if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
13161353
return -1;
@@ -1328,6 +1365,11 @@ redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, int *line_size)
13281365
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
13291366
}
13301367

1368+
// We don't need \r\n
1369+
*line_size-=2;
1370+
buf[*line_size]='\0';
1371+
1372+
13311373
// Success!
13321374
return 0;
13331375
}
@@ -1370,7 +1412,7 @@ PHPAPI int
13701412
redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval **z_ret) {
13711413
// Buffer to read our single line reply
13721414
char inbuf[1024];
1373-
int line_size;
1415+
size_t line_size;
13741416

13751417
// Attempt to read our single line reply
13761418
if(redis_sock_gets(redis_sock, inbuf, sizeof(inbuf), &line_size) < 0) {
@@ -1383,6 +1425,9 @@ redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval
13831425
zend_throw_exception(redis_exception_ce, "SYNC with master in progress", 0 TSRMLS_CC);
13841426
}
13851427

1428+
// Set our last error
1429+
redis_sock_set_err(redis_sock, inbuf, line_size);
1430+
13861431
// Set our response to FALSE
13871432
ZVAL_FALSE(*z_ret);
13881433
} else {

library.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC);
3737
//PHPAPI int redis_sock_get(zval *id, RedisSock **redis_sock TSRMLS_DC);
3838
PHPAPI void redis_free_socket(RedisSock *redis_sock);
3939
PHPAPI void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock);
40+
PHPAPI int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len);
4041

4142
PHPAPI int
4243
redis_serialize(RedisSock *redis_sock, zval *z, char **val, int *val_len TSRMLS_DC);

php_redis.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ PHP_METHOD(Redis, script);
133133
PHP_METHOD(Redis, dump);
134134
PHP_METHOD(Redis, restore);
135135

136+
PHP_METHOD(Redis, getLastError);
137+
136138
PHP_METHOD(Redis, _prefix);
137139
PHP_METHOD(Redis, _unserialize);
138140

redis.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ static zend_function_entry redis_functions[] = {
161161
PHP_ME(Redis, dump, NULL, ZEND_ACC_PUBLIC)
162162
PHP_ME(Redis, restore, NULL, ZEND_ACC_PUBLIC)
163163

164+
PHP_ME(Redis, getLastError, NULL, ZEND_ACC_PUBLIC)
165+
164166
PHP_ME(Redis, _prefix, NULL, ZEND_ACC_PUBLIC)
165167
PHP_ME(Redis, _unserialize, NULL, ZEND_ACC_PUBLIC)
166168

@@ -5607,7 +5609,7 @@ redis_build_eval_cmd(RedisSock *redis_sock, char **ret, char *keyword, char *val
56075609
zval **elem;
56085610
HashTable *args_hash;
56095611
HashPosition hash_pos;
5610-
int cmd_len, args_count;
5612+
int cmd_len, args_count = 0;
56115613
int eval_cmd_count = 2;
56125614

56135615
// If we've been provided arguments, we'll want to include those in our eval command
@@ -5946,15 +5948,42 @@ PHP_METHOD(Redis, _unserialize) {
59465948

59475949
// We only need to attempt unserialization if we have a serializer running
59485950
if(redis_sock->serializer != REDIS_SERIALIZER_NONE) {
5949-
if(redis_unserialize(redis_sock, value, value_len, &return_value TSRMLS_CC) == 0) {
5951+
zval *z_ret = NULL;
5952+
if(redis_unserialize(redis_sock, value, value_len, &z_ret TSRMLS_CC) == 0) {
59505953
zend_throw_exception(redis_exception_ce, "Invalid serialized data, or unserialization error", 0 TSRMLS_CC);
59515954
RETURN_FALSE;
59525955
}
5956+
RETURN_ZVAL(z_ret, 0, 0);
59535957
} else {
59545958
// Just return the value that was passed to us
59555959
RETURN_STRINGL(value, value_len, 1);
59565960
}
59575961
}
59585962

5963+
/*
5964+
* {{{ proto Redis::getLastError()
5965+
*/
5966+
PHP_METHOD(Redis, getLastError) {
5967+
zval *object;
5968+
RedisSock *redis_sock;
5969+
5970+
// Grab our object
5971+
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, redis_ce) == FAILURE) {
5972+
RETURN_FALSE;
5973+
}
5974+
// Grab socket
5975+
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
5976+
RETURN_FALSE;
5977+
}
5978+
5979+
// Return our last error or NULL if we don't have one
5980+
if(redis_sock->err != NULL && redis_sock->err_len > 0) {
5981+
RETURN_STRING(redis_sock->err, 1);
5982+
//RETURN_STRING(redis_sock->err); // , redis_sock->err_len-1, 1);
5983+
} else {
5984+
RETURN_NULL();
5985+
}
5986+
}
5987+
59595988
/* vim: set tabstop=4 softtabstop=4 noexpandtab shiftwidth=4: */
59605989

0 commit comments

Comments
 (0)