X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fstats.cc;h=ab00d4b8051363f891a6853f743d10db61c15619;hb=e2688497603c56929e6dd2b4e6139dd85edcb0e0;hp=eb2904438e746223ff399d5dbde01dcfce6e7555;hpb=a6c3e3a3d04f379b1480c8c88a8eae17e54b1449;p=m6w6%2Flibmemcached diff --git a/libmemcached/stats.cc b/libmemcached/stats.cc index eb290443..ab00d4b8 100644 --- a/libmemcached/stats.cc +++ b/libmemcached/stats.cc @@ -1,7 +1,40 @@ -/* -*/ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Libmemcached library + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ -#include "common.h" +#include static const char *memcached_stat_keys[] = { "pid", @@ -34,18 +67,21 @@ struct local_context memcached_stat_fn func; void *context; const char *args; + const size_t args_length; local_context(memcached_stat_fn func_arg, - void *context_arg, - const char *args_arg) : + void *context_arg, + const char *args_arg, + const size_t args_length_arg) : func(func_arg), context(context_arg), - args(args_arg) + args(args_arg), + args_length(args_length_arg) { } }; -static memcached_return_t set_data(memcached_stat_st *memc_stat, char *key, char *value) +static memcached_return_t set_data(memcached_stat_st *memc_stat, const char *key, const char *value) { if (strlen(key) < 1) @@ -53,121 +89,135 @@ static memcached_return_t set_data(memcached_stat_st *memc_stat, char *key, char WATCHPOINT_STRING(key); return MEMCACHED_UNKNOWN_STAT_KEY; } - else if (!strcmp("pid", key)) + else if (strcmp("pid", key) == 0) { - memc_stat->pid= (uint32_t) strtol(value, (char **)NULL, 10); + int64_t temp= strtoll(value, (char **)NULL, 10); + + if (temp <= INT32_MAX and ( sizeof(pid_t) == sizeof(int32_t) )) + { + memc_stat->pid= temp; + } + else if (temp > -1) + { + memc_stat->pid= temp; + } + else + { + // If we got a value less then -1 then something went wrong in the + // protocol + } } - else if (!strcmp("uptime", key)) + else if (not strcmp("uptime", key)) { - memc_stat->uptime= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->uptime= strtoul(value, (char **)NULL, 10); } - else if (!strcmp("time", key)) + else if (not strcmp("time", key)) { - memc_stat->time= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->time= strtoul(value, (char **)NULL, 10); } - else if (!strcmp("version", key)) + else if (not strcmp("version", key)) { memcpy(memc_stat->version, value, strlen(value)); memc_stat->version[strlen(value)]= 0; } - else if (!strcmp("pointer_size", key)) + else if (not strcmp("pointer_size", key)) { - memc_stat->pointer_size= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->pointer_size= strtoul(value, (char **)NULL, 10); } - else if (!strcmp("rusage_user", key)) + else if (not strcmp("rusage_user", key)) { char *walk_ptr; - for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++) {}; + for (walk_ptr= (char*)value; (!ispunct(*walk_ptr)); walk_ptr++) {}; *walk_ptr= 0; walk_ptr++; - memc_stat->rusage_user_seconds= (uint32_t) strtol(value, (char **)NULL, 10); - memc_stat->rusage_user_microseconds= (uint32_t) strtol(walk_ptr, (char **)NULL, 10); + memc_stat->rusage_user_seconds= strtoul(value, (char **)NULL, 10); + memc_stat->rusage_user_microseconds= strtoul(walk_ptr, (char **)NULL, 10); } - else if (!strcmp("rusage_system", key)) + else if (not strcmp("rusage_system", key)) { char *walk_ptr; - for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++) {}; + for (walk_ptr= (char*)value; (!ispunct(*walk_ptr)); walk_ptr++) {}; *walk_ptr= 0; walk_ptr++; - memc_stat->rusage_system_seconds= (uint32_t) strtol(value, (char **)NULL, 10); - memc_stat->rusage_system_microseconds= (uint32_t) strtol(walk_ptr, (char **)NULL, 10); + memc_stat->rusage_system_seconds= strtoul(value, (char **)NULL, 10); + memc_stat->rusage_system_microseconds= strtoul(walk_ptr, (char **)NULL, 10); } - else if (!strcmp("curr_items", key)) + else if (not strcmp("curr_items", key)) { - memc_stat->curr_items= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->curr_items= strtoul(value, (char **)NULL, 10); } - else if (!strcmp("total_items", key)) + else if (not strcmp("total_items", key)) { - memc_stat->total_items= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->total_items= strtoul(value, (char **)NULL, 10); } - else if (!strcmp("bytes_read", key)) + else if (not strcmp("bytes_read", key)) { - memc_stat->bytes_read= (uint32_t) strtoll(value, (char **)NULL, 10); + memc_stat->bytes_read= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("bytes_written", key)) + else if (not strcmp("bytes_written", key)) { - memc_stat->bytes_written= (uint32_t) strtoll(value, (char **)NULL, 10); + memc_stat->bytes_written= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("bytes", key)) + else if (not strcmp("bytes", key)) { - memc_stat->bytes= (uint32_t) strtoll(value, (char **)NULL, 10); + memc_stat->bytes= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("curr_connections", key)) + else if (not strcmp("curr_connections", key)) { - memc_stat->curr_connections= (uint32_t) strtoll(value, (char **)NULL, 10); + memc_stat->curr_connections= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("total_connections", key)) + else if (not strcmp("total_connections", key)) { - memc_stat->total_connections= (uint32_t) strtoll(value, (char **)NULL, 10); + memc_stat->total_connections= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("connection_structures", key)) + else if (not strcmp("connection_structures", key)) { - memc_stat->connection_structures= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->connection_structures= strtoul(value, (char **)NULL, 10); } - else if (!strcmp("cmd_get", key)) + else if (not strcmp("cmd_get", key)) { - memc_stat->cmd_get= (uint64_t) strtoll(value, (char **)NULL, 10); + memc_stat->cmd_get= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("cmd_set", key)) + else if (not strcmp("cmd_set", key)) { - memc_stat->cmd_set= (uint64_t) strtoll(value, (char **)NULL, 10); + memc_stat->cmd_set= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("get_hits", key)) + else if (not strcmp("get_hits", key)) { - memc_stat->get_hits= (uint64_t) strtoll(value, (char **)NULL, 10); + memc_stat->get_hits= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("get_misses", key)) + else if (not strcmp("get_misses", key)) { - memc_stat->get_misses= (uint64_t)strtoll(value, (char **)NULL, 10); + memc_stat->get_misses= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("evictions", key)) + else if (not strcmp("evictions", key)) { - memc_stat->evictions= (uint64_t)strtoll(value, (char **)NULL, 10); + memc_stat->evictions= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("limit_maxbytes", key)) + else if (not strcmp("limit_maxbytes", key)) { - memc_stat->limit_maxbytes= (uint64_t) strtoll(value, (char **)NULL, 10); + memc_stat->limit_maxbytes= strtoull(value, (char **)NULL, 10); } - else if (!strcmp("threads", key)) + else if (not strcmp("threads", key)) { - memc_stat->threads= (uint32_t) strtol(value, (char **)NULL, 10); + memc_stat->threads= strtoul(value, (char **)NULL, 10); } - else if (!(strcmp("delete_misses", key) == 0 ||/* New stats in the 1.3 beta */ - strcmp("delete_hits", key) == 0 ||/* Just swallow them for now.. */ - strcmp("incr_misses", key) == 0 || - strcmp("incr_hits", key) == 0 || - strcmp("decr_misses", key) == 0 || - strcmp("decr_hits", key) == 0 || - strcmp("cas_misses", key) == 0 || - strcmp("cas_hits", key) == 0 || - strcmp("cas_badval", key) == 0 || - strcmp("cmd_flush", key) == 0 || - strcmp("accepting_conns", key) == 0 || - strcmp("listen_disabled_num", key) == 0 || - strcmp("conn_yields", key) == 0 || - strcmp("auth_cmds", key) == 0 || - strcmp("auth_errors", key) == 0 || - strcmp("reclaimed", key) == 0)) + else if (not (strcmp("delete_misses", key) == 0 or /* New stats in the 1.3 beta */ + strcmp("delete_hits", key) == 0 or /* Just swallow them for now.. */ + strcmp("incr_misses", key) == 0 or + strcmp("incr_hits", key) == 0 or + strcmp("decr_misses", key) == 0 or + strcmp("decr_hits", key) == 0 or + strcmp("cas_misses", key) == 0 or + strcmp("cas_hits", key) == 0 or + strcmp("cas_badval", key) == 0 or + strcmp("cmd_flush", key) == 0 or + strcmp("accepting_conns", key) == 0 or + strcmp("listen_disabled_num", key) == 0 or + strcmp("conn_yields", key) == 0 or + strcmp("auth_cmds", key) == 0 or + strcmp("auth_errors", key) == 0 or + strcmp("reclaimed", key) == 0)) { WATCHPOINT_STRING(key); /* return MEMCACHED_UNKNOWN_STAT_KEY; */ @@ -186,50 +236,94 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_ *error= MEMCACHED_SUCCESS; - if (!memcmp("pid", key, sizeof("pid") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->pid); - else if (!memcmp("uptime", key, sizeof("uptime") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->uptime); - else if (!memcmp("time", key, sizeof("time") -1)) + if (memcmp("pid", key, sizeof("pid") -1) == 0) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lld", (signed long long)memc_stat->pid); + } + else if (not memcmp("uptime", key, sizeof("uptime") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->uptime); + } + else if (not memcmp("time", key, sizeof("time") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->time); - else if (!memcmp("version", key, sizeof("version") -1)) + } + else if (not memcmp("version", key, sizeof("version") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%s", memc_stat->version); - else if (!memcmp("pointer_size", key, sizeof("pointer_size") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->pointer_size); - else if (!memcmp("rusage_user", key, sizeof("rusage_user") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u.%u", memc_stat->rusage_user_seconds, memc_stat->rusage_user_microseconds); - else if (!memcmp("rusage_system", key, sizeof("rusage_system") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u.%u", memc_stat->rusage_system_seconds, memc_stat->rusage_system_microseconds); - else if (!memcmp("curr_items", key, sizeof("curr_items") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->curr_items); - else if (!memcmp("total_items", key, sizeof("total_items") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->total_items); - else if (!memcmp("curr_connections", key, sizeof("curr_connections") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->curr_connections); - else if (!memcmp("total_connections", key, sizeof("total_connections") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->total_connections); - else if (!memcmp("connection_structures", key, sizeof("connection_structures") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->connection_structures); - else if (!memcmp("cmd_get", key, sizeof("cmd_get") -1)) + } + else if (not memcmp("pointer_size", key, sizeof("pointer_size") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->pointer_size); + } + else if (not memcmp("rusage_user", key, sizeof("rusage_user") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu.%lu", memc_stat->rusage_user_seconds, memc_stat->rusage_user_microseconds); + } + else if (not memcmp("rusage_system", key, sizeof("rusage_system") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu.%lu", memc_stat->rusage_system_seconds, memc_stat->rusage_system_microseconds); + } + else if (not memcmp("curr_items", key, sizeof("curr_items") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->curr_items); + } + else if (not memcmp("total_items", key, sizeof("total_items") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->total_items); + } + else if (not memcmp("curr_connections", key, sizeof("curr_connections") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->curr_connections); + } + else if (not memcmp("total_connections", key, sizeof("total_connections") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->total_connections); + } + else if (not memcmp("connection_structures", key, sizeof("connection_structures") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->connection_structures); + } + else if (not memcmp("cmd_get", key, sizeof("cmd_get") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->cmd_get); - else if (!memcmp("cmd_set", key, sizeof("cmd_set") -1)) + } + else if (not memcmp("cmd_set", key, sizeof("cmd_set") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->cmd_set); - else if (!memcmp("get_hits", key, sizeof("get_hits") -1)) + } + else if (not memcmp("get_hits", key, sizeof("get_hits") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->get_hits); - else if (!memcmp("get_misses", key, sizeof("get_misses") -1)) + } + else if (not memcmp("get_misses", key, sizeof("get_misses") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->get_misses); - else if (!memcmp("evictions", key, sizeof("evictions") -1)) + } + else if (not memcmp("evictions", key, sizeof("evictions") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->evictions); - else if (!memcmp("bytes_read", key, sizeof("bytes_read") -1)) + } + else if (not memcmp("bytes_read", key, sizeof("bytes_read") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes_read); - else if (!memcmp("bytes_written", key, sizeof("bytes_written") -1)) + } + else if (not memcmp("bytes_written", key, sizeof("bytes_written") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes_written); - else if (!memcmp("bytes", key, sizeof("bytes") -1)) + } + else if (not memcmp("bytes", key, sizeof("bytes") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes); - else if (!memcmp("limit_maxbytes", key, sizeof("limit_maxbytes") -1)) + } + else if (not memcmp("limit_maxbytes", key, sizeof("limit_maxbytes") -1)) + { length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->limit_maxbytes); - else if (! memcmp("threads", key, sizeof("threads") -1)) - length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->threads); + } + else if (not memcmp("threads", key, sizeof("threads") -1)) + { + length= snprintf(buffer, SMALL_STRING_LEN,"%lu", memc_stat->threads); + } else { *error= MEMCACHED_NOTFOUND; @@ -251,32 +345,27 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, const char *args, - memcached_server_write_instance_st instance, + const size_t args_length, + org::libmemcached::Instance* instance, struct local_context *check) { - memcached_return_t rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; protocol_binary_request_stats request= {}; // = {.bytes= {0}}; - request.message.header.request.magic= PROTOCOL_BINARY_REQ; + + initialize_binary_request(instance, request.message.header); + request.message.header.request.opcode= PROTOCOL_BINARY_CMD_STAT; request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES; - if (args != NULL) + if (args_length) { - size_t len= strlen(args); - - rc= memcached_validate_key_length(len, true); - unlikely (rc != MEMCACHED_SUCCESS) - return rc; + request.message.header.request.keylen= htons(uint16_t(args_length)); + request.message.header.request.bodylen= htonl(uint32_t( args_length)); - request.message.header.request.keylen= htons((uint16_t)len); - request.message.header.request.bodylen= htonl((uint32_t) len); - - struct libmemcached_io_vector_st vector[]= + libmemcached_io_vector_st vector[]= { - { sizeof(request.bytes), request.bytes }, - { len, args } + { request.bytes, sizeof(request.bytes) }, + { args, args_length } }; if (memcached_vdo(instance, vector, 2, true) != MEMCACHED_SUCCESS) @@ -287,8 +376,12 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, } else { - if (memcached_do(instance, request.bytes, - sizeof(request.bytes), true) != MEMCACHED_SUCCESS) + libmemcached_io_vector_st vector[]= + { + { request.bytes, sizeof(request.bytes) } + }; + + if (memcached_vdo(instance, vector, 1, true) != MEMCACHED_SUCCESS) { memcached_io_reset(instance); return MEMCACHED_WRITE_FAILURE; @@ -298,26 +391,19 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, memcached_server_response_decrement(instance); do { - rc= memcached_response(instance, buffer, sizeof(buffer), NULL); + memcached_return_t rc= memcached_response(instance, buffer, sizeof(buffer), NULL); if (rc == MEMCACHED_END) + { break; + } - unlikely (rc != MEMCACHED_SUCCESS) + if (rc != MEMCACHED_SUCCESS) { memcached_io_reset(instance); return rc; } - if (memc_stat) - { - unlikely((set_data(memc_stat, buffer, buffer + strlen(buffer) + 1)) == MEMCACHED_UNKNOWN_STAT_KEY) - { - WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); - WATCHPOINT_ASSERT(0); - } - } - if (check && check->func) { size_t key_length= strlen(buffer); @@ -327,119 +413,133 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, buffer+key_length+1, strlen(buffer+key_length+1), check->context); } + + if (memc_stat) + { + if ((set_data(memc_stat, buffer, buffer + strlen(buffer) + 1)) == MEMCACHED_UNKNOWN_STAT_KEY) + { + WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); + WATCHPOINT_ASSERT(0); + } + } } while (1); - /* shit... memcached_response will decrement the counter, so I need to - ** reset it.. todo: look at this and try to find a better solution. - */ - instance->cursor_active= 0; + /* + * memcached_response will decrement the counter, so I need to reset it.. + * todo: look at this and try to find a better solution. + * */ + instance->cursor_active_= 0; return MEMCACHED_SUCCESS; } static memcached_return_t ascii_stats_fetch(memcached_stat_st *memc_stat, const char *args, - memcached_server_write_instance_st instance, + const size_t args_length, + org::libmemcached::Instance* instance, struct local_context *check) { - memcached_return_t rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - int send_length; - - if (args) - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "stats %s\r\n", args); - else - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "stats\r\n"); - - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) - return MEMCACHED_WRITE_FAILURE; - - rc= memcached_do(instance, buffer, (size_t)send_length, true); - if (rc != MEMCACHED_SUCCESS) - goto error; - - while (1) + libmemcached_io_vector_st vector[]= { - rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); + { memcached_literal_param("stats ") }, + { args, args_length }, + { memcached_literal_param("\r\n") } + }; - if (rc == MEMCACHED_STAT) + memcached_return_t rc= memcached_vdo(instance, vector, 3, true); + if (memcached_success(rc)) + { + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + while ((rc= memcached_response(instance, buffer, sizeof(buffer), NULL)) == MEMCACHED_STAT) { - char *string_ptr, *end_ptr; - char *key, *value; - - string_ptr= buffer; + char *string_ptr= buffer; string_ptr+= 5; /* Move past STAT */ + + char *end_ptr; for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++) {}; - key= string_ptr; - key[(size_t)(end_ptr-string_ptr)]= 0; + char *key= string_ptr; + key[size_t(end_ptr-string_ptr)]= 0; string_ptr= end_ptr + 1; for (end_ptr= string_ptr; !(isspace(*end_ptr)); end_ptr++) {}; - value= string_ptr; - value[(size_t)(end_ptr-string_ptr)]= 0; - string_ptr= end_ptr + 2; + char *value= string_ptr; + value[(size_t)(end_ptr -string_ptr)]= 0; +#if 0 + bool check_bool= bool(check); + bool check_func_bool= bool(check) ? bool(check->func) : false; + fprintf(stderr, "%s:%d %s %s %d:%d\n", __FILE__, __LINE__, key, value, check_bool, check_func_bool); +#endif + + if (check and check->func) + { + check->func(instance, + key, strlen(key), + value, strlen(value), + check->context); + } + if (memc_stat) { - unlikely((set_data(memc_stat, key, value)) == MEMCACHED_UNKNOWN_STAT_KEY) + if((set_data(memc_stat, key, value)) == MEMCACHED_UNKNOWN_STAT_KEY) { WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); WATCHPOINT_ASSERT(0); } } - - if (check && check->func) - { - check->func(instance, - key, strlen(key), - value, strlen(value), - check->context); - } - } - else - { - break; } } -error: + if (rc == MEMCACHED_ERROR) + { + return MEMCACHED_INVALID_ARGUMENTS; + } + if (rc == MEMCACHED_END) + { return MEMCACHED_SUCCESS; - else - return rc; + } + + return rc; } memcached_stat_st *memcached_stat(memcached_st *self, char *args, memcached_return_t *error) { - memcached_return_t rc; - memcached_stat_st *stats; - - if ((rc= initialize_query(self)) != MEMCACHED_SUCCESS) + memcached_return_t unused; + if (error == NULL) { - if (error) - *error= rc; + error= &unused; + } + if (memcached_failed(*error= initialize_query(self, true))) + { return NULL; } - WATCHPOINT_ASSERT(error); - - unlikely (self->flags.use_udp) + if (memcached_is_udp(self)) { - if (error) - *error= MEMCACHED_NOT_SUPPORTED; - + *error= memcached_set_error(*self, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT); return NULL; } - stats= static_cast(libmemcached_calloc(self, memcached_server_count(self), sizeof(memcached_stat_st))); - - if (! stats) + memcached_return_t rc; + size_t args_length= 0; + if (args) { - if (error) - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + args_length= strlen(args); + rc= memcached_validate_key_length(args_length, self->flags.binary_protocol); + if (memcached_failed(rc)) + { + *error= memcached_set_error(*self, rc, MEMCACHED_AT); + return NULL; + } + } + + WATCHPOINT_ASSERT(error); + memcached_stat_st *stats= libmemcached_xcalloc(self, memcached_server_count(self), memcached_stat_st); + if (stats == NULL) + { + *error= memcached_set_error(*self, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT); return NULL; } @@ -447,31 +547,37 @@ memcached_stat_st *memcached_stat(memcached_st *self, char *args, memcached_retu rc= MEMCACHED_SUCCESS; for (uint32_t x= 0; x < memcached_server_count(self); x++) { - memcached_return_t temp_return; - memcached_server_write_instance_st instance; - memcached_stat_st *stat_instance; - - stat_instance= stats + x; + memcached_stat_st* stat_instance= stats +x; + stat_instance->pid= -1; stat_instance->root= self; - instance= memcached_server_instance_fetch(self, x); + org::libmemcached::Instance* instance= memcached_instance_fetch(self, x); - if (self->flags.binary_protocol) + memcached_return_t temp_return; + if (memcached_is_binary(self)) { - temp_return= binary_stats_fetch(stat_instance, args, instance, NULL); + temp_return= binary_stats_fetch(stat_instance, args, args_length, instance, NULL); } else { - temp_return= ascii_stats_fetch(stat_instance, args, instance, NULL); + temp_return= ascii_stats_fetch(stat_instance, args, args_length, instance, NULL); + } + + // Special case where "args" is invalid + if (temp_return == MEMCACHED_INVALID_ARGUMENTS) + { + rc= MEMCACHED_INVALID_ARGUMENTS; + break; } - if (temp_return != MEMCACHED_SUCCESS) + if (memcached_failed(temp_return)) + { rc= MEMCACHED_SOME_ERRORS; + } } - if (error) - *error= rc; + *error= rc; return stats; } @@ -480,32 +586,43 @@ memcached_return_t memcached_stat_servername(memcached_stat_st *memc_stat, char const char *hostname, in_port_t port) { memcached_st memc; - memcached_st *memc_ptr; - memcached_server_write_instance_st instance; memset(memc_stat, 0, sizeof(memcached_stat_st)); - memc_ptr= memcached_create(&memc); - if (! memc_ptr) + memcached_st *memc_ptr= memcached_create(&memc); + if (memc_ptr == NULL) + { return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - - memcached_server_add(&memc, hostname, port); + } memcached_return_t rc; - if ((rc= initialize_query(memc_ptr)) != MEMCACHED_SUCCESS) + if (memcached_failed(rc= memcached_server_add(&memc, hostname, port))) { + memcached_free(&memc); return rc; } - instance= memcached_server_instance_fetch(memc_ptr, 0); - - if (memc.flags.binary_protocol) + if (memcached_success(rc= initialize_query(memc_ptr, true))) { - rc= binary_stats_fetch(memc_stat, args, instance, NULL); - } - else - { - rc= ascii_stats_fetch(memc_stat, args, instance, NULL); + size_t args_length= 0; + if (args) + { + args_length= strlen(args); + rc= memcached_validate_key_length(args_length, memc.flags.binary_protocol); + } + + if (memcached_success(rc)) + { + org::libmemcached::Instance* instance= memcached_instance_fetch(memc_ptr, 0); + if (memc.flags.binary_protocol) + { + rc= binary_stats_fetch(memc_stat, args, args_length, instance, NULL); + } + else + { + rc= ascii_stats_fetch(memc_stat, args, args_length, instance, NULL); + } + } } memcached_free(&memc); @@ -517,20 +634,19 @@ memcached_return_t memcached_stat_servername(memcached_stat_st *memc_stat, char We make a copy of the keys since at some point in the not so distant future we will add support for "found" keys. */ -char ** memcached_stat_get_keys(const memcached_st *ptr, - memcached_stat_st *memc_stat, +char ** memcached_stat_get_keys(memcached_st *ptr, + memcached_stat_st *, memcached_return_t *error) { - char **list; - size_t length= sizeof(memcached_stat_keys); - - (void)memc_stat; - - list= static_cast(libmemcached_malloc(ptr, length)); + if (ptr == NULL) + { + return NULL; + } + char **list= static_cast(libmemcached_malloc(ptr, sizeof(memcached_stat_keys))); if (not list) { - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + *error= memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT); return NULL; } @@ -541,11 +657,11 @@ char ** memcached_stat_get_keys(const memcached_st *ptr, return list; } -void memcached_stat_free(const memcached_st *ptr, memcached_stat_st *memc_stat) +void memcached_stat_free(const memcached_st *, memcached_stat_st *memc_stat) { + WATCHPOINT_ASSERT(memc_stat); // Be polite, but when debugging catch this as an error if (memc_stat == NULL) { - WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */ return; } @@ -555,23 +671,23 @@ void memcached_stat_free(const memcached_st *ptr, memcached_stat_st *memc_stat) return; } - libmemcached_free(ptr, memc_stat); + libmemcached_free(NULL, memc_stat); } static memcached_return_t call_stat_fn(memcached_st *ptr, - memcached_server_write_instance_st instance, + org::libmemcached::Instance* instance, void *context) { memcached_return_t rc; - struct local_context *check= (struct local_context *)context; + local_context *check= (struct local_context *)context; - if (ptr->flags.binary_protocol) + if (memcached_is_binary(ptr)) { - rc= binary_stats_fetch(NULL, check->args, instance, check); + rc= binary_stats_fetch(NULL, check->args, check->args_length, instance, check); } else { - rc= ascii_stats_fetch(NULL, check->args, instance, check); + rc= ascii_stats_fetch(NULL, check->args, check->args_length, instance, check); } return rc; @@ -581,7 +697,7 @@ memcached_return_t memcached_stat_execute(memcached_st *memc, const char *args, { memcached_version(memc); - struct local_context check(func, context, args); + local_context check(func, context, args, args ? strlen(args) : 0); return memcached_server_execute(memc, call_stat_fn, (void *)&check); }