X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fversion.c;h=82de87d362240666b2134ee50b802c56b7e99952;hb=3dee67d04099cc5e2986ed94aa612f429f54d6fb;hp=7ab488809b6b083504db0192b65e5c91973e4155;hpb=ba24508f51eed2af4f0192589801db2f945eac7b;p=m6w6%2Flibmemcached diff --git a/libmemcached/version.c b/libmemcached/version.c index 7ab48880..82de87d3 100644 --- a/libmemcached/version.c +++ b/libmemcached/version.c @@ -13,10 +13,14 @@ memcached_return_t memcached_version(memcached_st *ptr) if (ptr->flags.use_udp) return MEMCACHED_NOT_SUPPORTED; + memcached_return_t rc; + if (ptr->flags.binary_protocol) - return memcached_version_binary(ptr); + rc= memcached_version_binary(ptr); else - return memcached_version_textual(ptr); + rc= memcached_version_textual(ptr); + + return rc; } static inline memcached_return_t memcached_version_textual(memcached_st *ptr) @@ -27,7 +31,7 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) char *response_ptr; const char *command= "version\r\n"; - send_length= strlen(command); + send_length= sizeof("version\r\n") -1; rc= MEMCACHED_SUCCESS; for (uint32_t x= 0; x < memcached_server_count(ptr); x++) @@ -36,9 +40,14 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); + // Optimization, we only fetch version once. + if (instance->major_version != UINT8_MAX) + continue; + rrc= memcached_do(instance, command, send_length, true); if (rrc != MEMCACHED_SUCCESS) { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; rc= MEMCACHED_SOME_ERRORS; continue; } @@ -46,6 +55,7 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) rrc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); if (rrc != MEMCACHED_SUCCESS) { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; rc= MEMCACHED_SOME_ERRORS; continue; } @@ -55,12 +65,33 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) response_ptr++; instance->major_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); + if (errno == ERANGE) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + rc= MEMCACHED_SOME_ERRORS; + continue; + } + response_ptr= index(response_ptr, '.'); response_ptr++; + instance->minor_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); + if (errno == ERANGE) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + rc= MEMCACHED_SOME_ERRORS; + continue; + } + response_ptr= index(response_ptr, '.'); response_ptr++; instance->micro_version= (uint8_t)strtol(response_ptr, (char **)NULL, 10); + if (errno == ERANGE) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + rc= MEMCACHED_SOME_ERRORS; + continue; + } } return rc; @@ -69,20 +100,22 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr) static inline memcached_return_t memcached_version_binary(memcached_st *ptr) { memcached_return_t rc; - unsigned int x; protocol_binary_request_version request= { .bytes= {0}}; request.message.header.request.magic= PROTOCOL_BINARY_REQ; request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION; request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES; rc= MEMCACHED_SUCCESS; - for (x= 0; x < memcached_server_count(ptr); x++) + for (uint32_t x= 0; x < memcached_server_count(ptr); x++) { memcached_return_t rrc; memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); + if (instance->major_version != UINT8_MAX) + continue; + rrc= memcached_do(instance, request.bytes, sizeof(request.bytes), true); if (rrc != MEMCACHED_SUCCESS) { @@ -92,11 +125,14 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) } } - for (x= 0; x < memcached_server_count(ptr); x++) + for (uint32_t x= 0; x < memcached_server_count(ptr); x++) { memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); + if (instance->major_version != UINT8_MAX) + continue; + if (memcached_server_response_count(instance) > 0) { memcached_return_t rrc; @@ -112,8 +148,29 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) } instance->major_version= (uint8_t)strtol(buffer, &p, 10); + if (errno == ERANGE) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + rc= MEMCACHED_SOME_ERRORS; + continue; + } + instance->minor_version= (uint8_t)strtol(p + 1, &p, 10); + if (errno == ERANGE) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + rc= MEMCACHED_SOME_ERRORS; + continue; + } + instance->micro_version= (uint8_t)strtol(p + 1, NULL, 10); + if (errno == ERANGE) + { + instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; + rc= MEMCACHED_SOME_ERRORS; + continue; + } + } }