From: Brian Aker Date: Tue, 22 Feb 2011 02:02:11 +0000 (-0800) Subject: Merge in ability for memcapable to handle ascii/binary as flags to the X-Git-Tag: 0.51~35 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=3c11b74c0aa013a6afd492d46a8e9c911e12b350;hp=a68e25b801d5b5e5f905534b4269dfafc18df2c1;p=awesomized%2Flibmemcached Merge in ability for memcapable to handle ascii/binary as flags to the command. --- diff --git a/.bzrignore b/.bzrignore index f428ca67..0ccaac97 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,3 +1,4 @@ +*.exe *.lo *.pop */*.l[oa] @@ -71,6 +72,7 @@ libmemcached-0.37-1.x86_64.rpm libmemcached-?.??/ libmemcached.pop libmemcached/configure.h +libmemcached/dtrace_probes.h libmemcached/memcached_configure.h libmemcached_examples.pop libmemcachedutil.pop @@ -183,3 +185,4 @@ tests/testhashkit tests/testplus tests/testudp unittests/unittests +config/top.h diff --git a/.quickly b/.quickly index b7c3fe31..398e2ab6 100644 --- a/.quickly +++ b/.quickly @@ -2,4 +2,4 @@ project = libmemcached version = 0.4.2 template = pandora-build project-type = library -pandora-version = 0.134 +pandora-version = 0.171 diff --git a/ChangeLog b/ChangeLog index 913e9a0a..589f002a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +0.46 Mon Feb 14 10:28:01 PST 2011 + * Fixes a number of corner case bugs. + * Fixes related to OpenBSD. + * Better testing for protocol version. + * Removes special case infinite wait on blocking setup. + +0.45 Tue Feb 8 16:02:06 PST 2011 + * Add support for systemtap + +0.44 Wed Sep 22 21:57:57 PDT 2010 + * Windows bug fixes. + * Hudson port support in test harness. + * Improved portability of test hanrness. + * SASL fixes. + 0.43 Wed Jul 28 16:29:47 PDT 2010 * Added --args to memstat so that a greater range of values can be returned. * Prelimanary support for Windows. diff --git a/Makefile.am b/Makefile.am index 079f9482..df606e61 100644 --- a/Makefile.am +++ b/Makefile.am @@ -93,5 +93,6 @@ lcov-clean: clean find . -name '*.gcno' | xargs rm -f find . -name '*.gcda' | xargs rm -f +CLEANFILES+= config/top.h diff --git a/clients/memcapable.c b/clients/memcapable.c index 7f5d51ee..fdbc35c8 100644 --- a/clients/memcapable.c +++ b/clients/memcapable.c @@ -303,6 +303,7 @@ static enum test_return retry_read(void *buf, size_t len) ssize_t nr= timeout_io_op(sock, POLLIN, ((char*) buf) + offset, len - offset); switch (nr) { case -1 : + fprintf(stderr, "Errno: %d %s\n", get_socket_errno(), strerror(errno)); verify(get_socket_errno() == EINTR || get_socket_errno() == EAGAIN); break; case 0: @@ -321,7 +322,7 @@ static enum test_return retry_read(void *buf, size_t len) */ static enum test_return recv_packet(response *rsp) { - execute(retry_read(rsp, sizeof (protocol_binary_response_no_extras))); + execute(retry_read(rsp, sizeof(protocol_binary_response_no_extras))); /* Fix the byte order in the packet header */ rsp->plain.message.header.response.keylen= @@ -693,10 +694,12 @@ static enum test_return test_binary_set_impl(const char* key, uint8_t cc) cmd.plain.message.header.request.cas= htonll(rsp.plain.message.header.response.cas - 1); execute(resend_packet(&cmd)); + execute(send_binary_noop()); execute(recv_packet(&rsp)); verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS)); + execute(receive_binary_noop()); - return test_binary_noop(); + return TEST_PASS; } static enum test_return test_binary_set(void) @@ -733,7 +736,9 @@ static enum test_return test_binary_add_impl(const char* key, uint8_t cc) else expected_result= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS; + execute(send_binary_noop()); execute(recv_packet(&rsp)); + execute(receive_binary_noop()); verify(validate_response_header(&rsp, cc, expected_result)); } else @@ -790,7 +795,9 @@ static enum test_return test_binary_replace_impl(const char* key, uint8_t cc) else expected_result=PROTOCOL_BINARY_RESPONSE_SUCCESS; + execute(send_binary_noop()); execute(recv_packet(&rsp)); + execute(receive_binary_noop()); verify(validate_response_header(&rsp, cc, expected_result)); if (ii == 0) @@ -817,7 +824,9 @@ static enum test_return test_binary_replace_impl(const char* key, uint8_t cc) cmd.plain.message.header.request.cas= htonll(rsp.plain.message.header.response.cas - 1); execute(resend_packet(&cmd)); + execute(send_binary_noop()); execute(recv_packet(&rsp)); + execute(receive_binary_noop()); verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS)); return TEST_PASS; @@ -841,8 +850,10 @@ static enum test_return test_binary_delete_impl(const char *key, uint8_t cc) /* The delete shouldn't work the first time, because the item isn't there */ execute(send_packet(&cmd)); + execute(send_binary_noop()); execute(recv_packet(&rsp)); verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT)); + execute(receive_binary_noop()); execute(binary_set_item(key, key)); /* The item should be present now, resend*/ @@ -1256,8 +1267,7 @@ static enum test_return test_ascii_set_impl(const char* key, bool noreply) { /* @todo add tests for bogus format! */ char buffer[1024]; - sprintf(buffer, "set %s 0 0 5%s\r\nvalue\r\n", key, - noreply ? " noreply" : ""); + snprintf(buffer, sizeof(buffer), "set %s 0 0 5%s\r\nvalue\r\n", key, noreply ? " noreply" : ""); execute(send_string(buffer)); if (!noreply) @@ -1280,8 +1290,7 @@ static enum test_return test_ascii_add_impl(const char* key, bool noreply) { /* @todo add tests for bogus format! */ char buffer[1024]; - sprintf(buffer, "add %s 0 0 5%s\r\nvalue\r\n", key, - noreply ? " noreply" : ""); + snprintf(buffer, sizeof(buffer), "add %s 0 0 5%s\r\nvalue\r\n", key, noreply ? " noreply" : ""); execute(send_string(buffer)); if (!noreply) @@ -1305,6 +1314,41 @@ static enum test_return test_ascii_add_noreply(void) return test_ascii_add_impl("test_ascii_add_noreply", true); } +static enum test_return ascii_get_unknown_value(char **key, char **value, ssize_t *ndata) +{ + char buffer[1024]; + + execute(receive_line(buffer, sizeof(buffer))); + verify(strncmp(buffer, "VALUE ", 6) == 0); + char *end= strchr(buffer + 6, ' '); + verify(end != NULL); + *end= '\0'; + *key= strdup(buffer + 6); + verify(*key != NULL); + char *ptr= end + 1; + + unsigned long val= strtoul(ptr, &end, 10); /* flags */ + verify(ptr != end); + verify(val == 0); + verify(end != NULL); + *ndata = (ssize_t)strtoul(end, &end, 10); /* size */ + verify(ptr != end); + verify(end != NULL); + while (*end != '\n' && isspace(*end)) + ++end; + verify(*end == '\n'); + + *value= malloc((size_t)*ndata); + verify(*value != NULL); + + execute(retry_read(*value, (size_t)*ndata)); + + execute(retry_read(buffer, 2)); + verify(memcmp(buffer, "\r\n", 2) == 0); + + return TEST_PASS; +} + static enum test_return ascii_get_value(const char *key, const char *value) { @@ -1348,7 +1392,7 @@ static enum test_return ascii_get_item(const char *key, const char *value, datasize= strlen(value); verify(datasize < sizeof(buffer)); - sprintf(buffer, "get %s\r\n", key); + snprintf(buffer, sizeof(buffer), "get %s\r\n", key); execute(send_string(buffer)); if (exist) @@ -1409,7 +1453,7 @@ static enum test_return ascii_gets_item(const char *key, const char *value, datasize= strlen(value); verify(datasize < sizeof(buffer)); - sprintf(buffer, "gets %s\r\n", key); + snprintf(buffer, sizeof(buffer), "gets %s\r\n", key); execute(send_string(buffer)); if (exist) @@ -1425,7 +1469,7 @@ static enum test_return ascii_set_item(const char *key, const char *value) { char buffer[300]; size_t len= strlen(value); - sprintf(buffer, "set %s 0 0 %u\r\n", key, (unsigned int)len); + snprintf(buffer, sizeof(buffer), "set %s 0 0 %u\r\n", key, (unsigned int)len); execute(send_string(buffer)); execute(retry_write(value, len)); execute(send_string("\r\n")); @@ -1436,8 +1480,7 @@ static enum test_return ascii_set_item(const char *key, const char *value) static enum test_return test_ascii_replace_impl(const char* key, bool noreply) { char buffer[1024]; - sprintf(buffer, "replace %s 0 0 5%s\r\nvalue\r\n", key, - noreply ? " noreply" : ""); + snprintf(buffer, sizeof(buffer), "replace %s 0 0 5%s\r\nvalue\r\n", key, noreply ? " noreply" : ""); execute(send_string(buffer)); if (noreply) @@ -1477,8 +1520,7 @@ static enum test_return test_ascii_cas_impl(const char* key, bool noreply) execute(ascii_set_item(key, "value")); execute(ascii_gets_item(key, "value", true, &cas)); - sprintf(buffer, "cas %s 0 0 6 %lu%s\r\nvalue2\r\n", key, cas, - noreply ? " noreply" : ""); + snprintf(buffer, sizeof(buffer), "cas %s 0 0 6 %lu%s\r\nvalue2\r\n", key, cas, noreply ? " noreply" : ""); execute(send_string(buffer)); if (noreply) @@ -1518,7 +1560,7 @@ static enum test_return test_ascii_delete_impl(const char *key, bool noreply) execute(receive_error_response()); char buffer[1024]; - sprintf(buffer, "delete %s%s\r\n", key, noreply ? " noreply" : ""); + snprintf(buffer, sizeof(buffer), "delete %s%s\r\n", key, noreply ? " noreply" : ""); execute(send_string(buffer)); if (noreply) @@ -1573,31 +1615,65 @@ static enum test_return test_ascii_gets(void) static enum test_return test_ascii_mget(void) { - execute(ascii_set_item("test_ascii_mget1", "value")); - execute(ascii_set_item("test_ascii_mget2", "value")); - execute(ascii_set_item("test_ascii_mget3", "value")); - execute(ascii_set_item("test_ascii_mget4", "value")); - execute(ascii_set_item("test_ascii_mget5", "value")); + const uint32_t nkeys= 5; + const char * const keys[]= { + "test_ascii_mget1", + "test_ascii_mget2", + /* test_ascii_mget_3 does not exist :) */ + "test_ascii_mget4", + "test_ascii_mget5", + "test_ascii_mget6" + }; + + for (uint32_t x= 0; x < nkeys; ++x) + execute(ascii_set_item(keys[x], "value")); + /* Ask for a key that doesn't exist as well */ execute(send_string("get test_ascii_mget1 test_ascii_mget2 test_ascii_mget3 " "test_ascii_mget4 test_ascii_mget5 " "test_ascii_mget6\r\n")); - execute(ascii_get_value("test_ascii_mget1", "value")); - execute(ascii_get_value("test_ascii_mget2", "value")); - execute(ascii_get_value("test_ascii_mget3", "value")); - execute(ascii_get_value("test_ascii_mget4", "value")); - execute(ascii_get_value("test_ascii_mget5", "value")); + + char *returned[nkeys]; + + for (uint32_t x= 0; x < nkeys; ++x) + { + ssize_t nbytes = 0; + char *v= NULL; + execute(ascii_get_unknown_value(&returned[x], &v, &nbytes)); + verify(nbytes == 5); + verify(memcmp(v, "value", 5) == 0); + free(v); + } char buffer[5]; execute(retry_read(buffer, 5)); verify(memcmp(buffer, "END\r\n", 5) == 0); - return TEST_PASS; + + /* verify that we got all the keys we expected */ + for (uint32_t x= 0; x < nkeys; ++x) + { + bool found= false; + for (uint32_t y= 0; y < nkeys; ++y) + { + if (strcmp(keys[x], returned[y]) == 0) + { + found = true; + break; + } + } + verify(found); + } + + for (uint32_t x= 0; x < nkeys; ++x) + free(returned[x]); + + return TEST_PASS; } static enum test_return test_ascii_incr_impl(const char* key, bool noreply) { char cmd[300]; - sprintf(cmd, "incr %s 1%s\r\n", key, noreply ? " noreply" : ""); + snprintf(cmd, sizeof(cmd), "incr %s 1%s\r\n", key, noreply ? " noreply" : ""); execute(ascii_set_item(key, "0")); for (int x= 1; x < 11; ++x) @@ -1633,7 +1709,7 @@ static enum test_return test_ascii_incr_noreply(void) static enum test_return test_ascii_decr_impl(const char* key, bool noreply) { char cmd[300]; - sprintf(cmd, "decr %s 1%s\r\n", key, noreply ? " noreply" : ""); + snprintf(cmd, sizeof(cmd), "decr %s 1%s\r\n", key, noreply ? " noreply" : ""); execute(ascii_set_item(key, "9")); for (int x= 8; x > -1; --x) @@ -1735,10 +1811,10 @@ static enum test_return test_ascii_concat_impl(const char *key, value="hello"; char cmd[400]; - sprintf(cmd, "%s %s 0 0 %u%s\r\n%s\r\n", - append ? "append" : "prepend", - key, (unsigned int)strlen(value), noreply ? " noreply" : "", - value); + snprintf(cmd, sizeof(cmd), "%s %s 0 0 %u%s\r\n%s\r\n", + append ? "append" : "prepend", + key, (unsigned int)strlen(value), noreply ? " noreply" : "", + value); execute(send_string(cmd)); if (noreply) @@ -1748,10 +1824,10 @@ static enum test_return test_ascii_concat_impl(const char *key, execute(ascii_get_item(key, "hello world", true)); - sprintf(cmd, "%s %s_notfound 0 0 %u%s\r\n%s\r\n", - append ? "append" : "prepend", - key, (unsigned int)strlen(value), noreply ? " noreply" : "", - value); + snprintf(cmd, sizeof(cmd), "%s %s_notfound 0 0 %u%s\r\n%s\r\n", + append ? "append" : "prepend", + key, (unsigned int)strlen(value), noreply ? " noreply" : "", + value); execute(send_string(cmd)); if (noreply) @@ -1864,25 +1940,36 @@ struct testcase testcases[]= { const int ascii_tests = 1; const int binary_tests = 2; +struct test_type_st +{ + bool ascii; + bool binary; +}; + int main(int argc, char **argv) { static const char * const status_msg[]= {"[skip]", "[pass]", "[pass]", "[FAIL]"}; + struct test_type_st tests= { true, true }; int total= 0; int failed= 0; const char *hostname= "localhost"; const char *port= "11211"; int cmd; - int tests = ascii_tests | binary_tests; + bool prompt= false; + const char *testname= NULL; + - while ((cmd= getopt(argc, argv, "t:vch:p:?ab")) != EOF) + while ((cmd= getopt(argc, argv, "t:vch:p:PT:?ab")) != EOF) { switch (cmd) { case 'a': - tests = ascii_tests; + tests.ascii= true; + tests.binary= false; break; case 'b': - tests = binary_tests; + tests.ascii= false; + tests.binary= true; break; case 't': timeout= atoi(optarg); @@ -1900,11 +1987,20 @@ int main(int argc, char **argv) break; case 'p': port= optarg; break; + case 'P': prompt= true; + break; + case 'T': testname= optarg; + break; default: - fprintf(stderr, "Usage: %s [-h hostname] [-p port] [-c] [-v] [-t n] [-a] [-b]\n" + fprintf(stderr, "Usage: %s [-h hostname] [-p port] [-c] [-v] [-t n] [-P] [-T testname]'\n" "\t-c\tGenerate coredump if a test fails\n" "\t-v\tVerbose test output (print out the assertion)\n" "\t-t n\tSet the timeout for io-operations to n seconds\n" + "\t-P\tPrompt the user before starting a test.\n" + "\t\t\t\"skip\" will skip the test\n" + "\t\t\t\"quit\" will terminate memcapable\n" + "\t\t\tEverything else will start the test\n" + "\t-T n\tJust run the test named n\n" "\t-a\tOnly test the ascii protocol\n" "\t-b\tOnly test the binary protocol\n", argv[0]); @@ -1923,8 +2019,11 @@ int main(int argc, char **argv) for (int ii= 0; testcases[ii].description != NULL; ++ii) { - if ((testcases[ii].description[0] == 'a' && (tests & ascii_tests) == 0) || - (testcases[ii].description[0] == 'b' && (tests & binary_tests) == 0)) + if (testname != NULL && strcmp(testcases[ii].description, testname) != 0) + continue; + + if ((testcases[ii].description[0] == 'a' && (tests.ascii) == 0) || + (testcases[ii].description[0] == 'b' && (tests.binary) == 0)) { continue; } @@ -1932,6 +2031,26 @@ int main(int argc, char **argv) fprintf(stdout, "%-40s", testcases[ii].description); fflush(stdout); + if (prompt) + { + fprintf(stdout, "\nPress when you are ready? "); + char buffer[80] = {0}; + if (fgets(buffer, sizeof(buffer), stdin) != NULL) { + if (strncmp(buffer, "skip", 4) == 0) + { + fprintf(stdout, "%-40s%s\n", testcases[ii].description, + status_msg[TEST_SKIP]); + fflush(stdout); + continue; + } + if (strncmp(buffer, "quit", 4) == 0) + exit(0); + } + + fprintf(stdout, "%-40s", testcases[ii].description); + fflush(stdout); + } + bool reconnect= false; enum test_return ret= testcases[ii].function(); if (ret == TEST_FAIL) diff --git a/clients/memslap.c b/clients/memslap.c index 38343b86..94048802 100644 --- a/clients/memslap.c +++ b/clients/memslap.c @@ -706,45 +706,69 @@ static void ms_print_memslap_stats(struct timeval *start_time, char buf[1024]; char *pos= buf; - pos+= sprintf(pos, "cmd_get: %zu\n", - ms_stats.cmd_get); - pos+= sprintf(pos, "cmd_set: %zu\n", - ms_stats.cmd_set); - pos+= sprintf(pos, "get_misses: %zu\n", - ms_stats.get_misses); + pos+= snprintf(pos, + sizeof(buf), "cmd_get: %lu\n", + (unsigned long) ms_stats.cmd_get); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "cmd_set: %lu\n", + (unsigned long) ms_stats.cmd_set); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "get_misses: %lu\n", + (unsigned long) ms_stats.get_misses); if (ms_setting.verify_percent > 0) { - pos+= sprintf(pos, "verify_misses: %zu\n", - ms_stats.vef_miss); - pos+= sprintf(pos, "verify_failed: %zu\n", - ms_stats.vef_failed); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "verify_misses: %lu\n", + (unsigned long) ms_stats.vef_miss); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "verify_failed: %lu\n", + (unsigned long) ms_stats.vef_failed); } if (ms_setting.exp_ver_per > 0) { - pos+= sprintf(pos, "expired_get: %zu\n", - ms_stats.exp_get); - pos+= sprintf(pos, "unexpired_unget: %zu\n", - ms_stats.unexp_unget); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "expired_get: %lu\n", + (unsigned long) ms_stats.exp_get); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "unexpired_unget: %lu\n", + (unsigned long) ms_stats.unexp_unget); } - pos+= sprintf(pos, - "written_bytes: %zu\n", - ms_stats.bytes_written); - pos+= sprintf(pos, "read_bytes: %zu\n", - ms_stats.bytes_read); - pos+= sprintf(pos, "object_bytes: %zu\n", - ms_stats.obj_bytes); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "written_bytes: %lu\n", + (unsigned long) ms_stats.bytes_written); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "read_bytes: %lu\n", + (unsigned long) ms_stats.bytes_read); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "object_bytes: %lu\n", + (unsigned long) ms_stats.obj_bytes); if (ms_setting.udp || ms_setting.facebook_test) { - pos+= sprintf(pos, "packet_disorder: %zu\n", - ms_stats.pkt_disorder); - pos+= sprintf(pos, "packet_drop: %zu\n", - ms_stats.pkt_drop); - pos+= sprintf(pos, "udp_timeout: %zu\n", - ms_stats.udp_timeout); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "packet_disorder: %lu\n", + (unsigned long) ms_stats.pkt_disorder); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "packet_drop: %lu\n", + (unsigned long)ms_stats.pkt_drop); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "udp_timeout: %lu\n", + (unsigned long)ms_stats.udp_timeout); } if (ms_setting.stat_freq > 0) @@ -755,17 +779,18 @@ static void ms_print_memslap_stats(struct timeval *start_time, } int64_t time_diff= ms_time_diff(start_time, end_time); - pos+= sprintf( - pos, - "\nRun time: %.1fs Ops: %llu TPS: %.0Lf Net_rate: %.1fM/s\n", - (double)time_diff / 1000000, - (unsigned long long)(ms_stats.cmd_get + ms_stats.cmd_set), - (ms_stats.cmd_get - + ms_stats.cmd_set) / ((long double)time_diff / 1000000), - (double)( - ms_stats.bytes_written - + ms_stats.bytes_read) / 1024 / 1024 - / ((double)time_diff / 1000000)); + pos+= snprintf(pos, + sizeof(buf) - (size_t)(pos -buf), + "\nRun time: %.1fs Ops: %llu TPS: %.0Lf Net_rate: %.1fM/s\n", + (double)time_diff / 1000000, + (unsigned long long)(ms_stats.cmd_get + ms_stats.cmd_set), + (ms_stats.cmd_get + + ms_stats.cmd_set) / ((long double)time_diff / 1000000), + (double)( + ms_stats.bytes_written + + ms_stats.bytes_read) / 1024 / 1024 + / ((double)time_diff / 1000000)); + assert(pos <= buf); fprintf(stdout, "%s", buf); fflush(stdout); diff --git a/clients/ms_atomic.h b/clients/ms_atomic.h index 18606636..0b05bcec 100644 --- a/clients/ms_atomic.h +++ b/clients/ms_atomic.h @@ -27,7 +27,7 @@ # define atomic_dec_size_nv(X, Y) atomic_add_32((X), (Y)) # endif # undef _KERNEL -#else +#elif HAVE_GCC_ATOMIC_BUILTINS # define atomic_add_8(X, Y) __sync_fetch_and_add((X), (Y)) # define atomic_add_16(X, Y) __sync_fetch_and_add((X), (Y)) # define atomic_add_32(X, Y) __sync_fetch_and_add((X), (Y)) @@ -45,6 +45,25 @@ # define atomic_dec_16_nv(X) __sync_fetch_and_sub((X), 1) # define atomic_dec_32_nv(X) __sync_fetch_and_sub((X), 1) # define atomic_dec_size_nv(X) __sync_fetch_and_sub((X), 1) +#else +#warning "Atomic operators not found so memslap will not work correctly" +# define atomic_add_8(X, Y) +# define atomic_add_16(X, Y) +# define atomic_add_32(X, Y) +# define atomic_add_size(X, Y) +# define atomic_dec_8(X) +# define atomic_dec_16(X) +# define atomic_dec_32(X) +# define atomic_dec_size(X) +/* The same as above, but these return the new value instead of void */ +# define atomic_add_8_nv(X, Y) +# define atomic_add_16_nv(X, Y) +# define atomic_add_32_nv(X, Y) +# define atomic_add_size_nv(X, Y) +# define atomic_dec_8_nv(X) +# define atomic_dec_16_nv(X) +# define atomic_dec_32_nv(X) +# define atomic_dec_size_nv(X) #endif /* defined(__SUNPRO_C) */ #endif /* CLIENTS_MS_ATOMIC_H */ diff --git a/clients/ms_conn.c b/clients/ms_conn.c index 82016e1f..ae3145f5 100644 --- a/clients/ms_conn.c +++ b/clients/ms_conn.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #if TIME_WITH_SYS_TIME # include @@ -2886,13 +2887,14 @@ static int ms_build_ascii_write_buf_set(ms_conn_t *c, ms_task_item_t *item) int write_len; char *buffer= c->wbuf; - write_len= sprintf(buffer, - " %u %d %d\r\n", - 0, - item->exp_time, - item->value_size); + write_len= snprintf(buffer, + c->wsize, + " %u %d %d\r\n", + 0, + item->exp_time, + item->value_size); - if (write_len > c->wsize) + if (write_len > c->wsize || write_len < 0) { /* ought to be always enough. just fail for simplicity */ fprintf(stderr, "output command line too long.\n"); diff --git a/clients/ms_setting.c b/clients/ms_setting.c index ac76853f..d7099709 100644 --- a/clients/ms_setting.c +++ b/clients/ms_setting.c @@ -19,7 +19,6 @@ #include #include #include -#include #include diff --git a/config/autorun.sh b/config/autorun.sh index 511b6bba..ae57443a 100755 --- a/config/autorun.sh +++ b/config/autorun.sh @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2006 Jan Kneschke -# Copyright (c) 2009 Sun Microsystems +# Copyright (C) 2006 Jan Kneschke +# Copyright (C) 2009 Sun Microsystems, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/config/lcov.am b/config/lcov.am new file mode 100644 index 00000000..7509df10 --- /dev/null +++ b/config/lcov.am @@ -0,0 +1,42 @@ +# Copyright (C) 2010 Hartmut Holzgraefe +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +LCOV = lcov +LCOV_GENHTML = genhtml + +lcov: lcov-html + +lcov-test: lcov-clean-data test + +drizzle_lcov.info: lcov-test + @echo "Generating $@" + $(LCOV) --directory . --capture --base-directory . --output-file $@ + $(LCOV) --remove $@ '/usr/include/*' --output-file $@ + $(LCOV) --remove $@ '/usr/local/include/*' --output-file $@ + @echo + +lcov-html: drizzle_lcov.info + @echo "Generating lcov HTML" + @$(LCOV_GENHTML) --legend --output-directory lcov_html/ --title "Drizzle Code Coverage" $< + +lcov-clean: + rm -f drizzle_lcov.info + rm -rf lcov_data/ + rm -rf lcov_html/ + +lcov-clean-data: + @find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f + + diff --git a/config/pandora-plugin b/config/pandora-plugin index 3ffcaaff..91302914 100755 --- a/config/pandora-plugin +++ b/config/pandora-plugin @@ -1,6 +1,6 @@ #!/usr/bin/python -# Copyright (C) 2009 Sun Microsystems +# Copyright (C) 2009 Sun Microsystems, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,6 +25,7 @@ import subprocess plugin_am_file=None plugin_ac_file=None +plugin_doc_index=None class ChangeProtectedFile(object): @@ -130,9 +131,16 @@ VERSION=$(PANDORA_RELEASE_VERSION) pkgplugindir=%(pkgplugindir)s EXTRA_DIST = plugin.ini +noinst_HEADERS= +nobase_include_HEADERS= +check_PROGRAMS= +noinst_LTLIBRARIES= +bin_PROGRAMS= + + """ % plugin) if plugin['headers'] != "": - plugin_file.write("noinst_HEADERS = %(headers)s\n" % plugin) + plugin_file.write("noinst_HEADERS += %(headers)s\n" % plugin) if plugin['install_headers'] != "": plugin_file.write("nobase_include_HEADERS += %(install_headers)s\n" % plugin) if plugin['testsuite']: @@ -191,8 +199,16 @@ def write_plugin(plugin, plugin_ini_list): write_plugin_ac(plugin, plugin_ac_file) write_plugin_am(plugin, plugin_am_file) + write_plugin_docs(plugin, plugin_doc_index) plugin['writing_status'] = 'done' +def write_plugin_docs(plugin, doc_index): + if plugin['docs'] is not None and os.path.isdir("docs/plugins"): + if not os.path.exists(os.path.join("docs/plugins",plugin["name"])): + os.symlink(os.path.abspath(plugin["docs"]), os.path.join("docs/plugins",plugin["name"])) + doc_index.write(""" + %(name)s/index""" % plugin) + def write_plugin_ac(plugin, plugin_ac): # # Write plugin config instructions into plugin.ac file. @@ -229,8 +245,8 @@ AS_HELP_STRING([--without-%(name_with_dashes)s-plugin],[Disable building %(title ]) AC_ARG_ENABLE([%(name_with_dashes)s-plugin],[ dnl indented wierd to make the help output correct -AS_HELP_STRING([--enable-%(name_with_dashes)s-plugin],[Build %(title)s. @<:@default=%(default_yesno)s@:>@]) -AS_HELP_STRING([--disable-%(name_with_dashes)s-plugin],[Disable building %(title)s]) +AS_HELP_STRING([--enable-%(name_with_dashes)s-plugin],[Enable loading %(title)s by default. @<:@default=%(default_yesno)s@:>@]) +AS_HELP_STRING([--disable-%(name_with_dashes)s-plugin],[Disable loading %(title)s by default.]) ], [enable_%(name)s_plugin="$enableval"], [enable_%(name)s_plugin=%(default_yesno)s]) @@ -271,11 +287,13 @@ AS_IF([test "x$with_%(name)s_plugin" = "xyes"], if plugin['static']: plugin_ac.write(""" AS_IF([test "x$enable_%(name)s_plugin" = "xyes"],[ - pandora_builtin_list="%(module_name)s,${pandora_builtin_list}" - pandora_builtin_symbols_list="_drizzled_%(module_name)s_plugin_,${pandora_builtin_symbols_list}" - pandora_plugin_libs="${pandora_plugin_libs} \${top_builddir}/%(root_plugin_dir)s/%(libname)s.la" + pandora_builtin_load_list="%(module_name)s,${pandora_builtin_load_list}" + pandora_builtin_load_symbols_list="_drizzled_%(module_name)s_plugin_,${pandora_builtin_load_symbols_list}" PANDORA_PLUGIN_DEP_LIBS="${PANDORA_PLUGIN_DEP_LIBS} %(plugin_dep_libs)s" ]) + pandora_builtin_list="%(module_name)s,${pandora_builtin_list}" + pandora_builtin_symbols_list="_drizzled_%(module_name)s_plugin_,${pandora_builtin_symbols_list}" + pandora_plugin_libs="${pandora_plugin_libs} \${top_builddir}/%(root_plugin_dir)s/%(libname)s.la" """ % plugin) else: @@ -320,11 +338,14 @@ def expand_plugin_ini(plugin): plugin['tests']= fix_file_paths(plugin, plugin['tests']) # Make a yes/no version for autoconf help messages - if plugin['load_by_default'] or plugin['static']: + if plugin['load_by_default']: plugin['default_yesno']="yes" else: plugin['default_yesno']="no" + if plugin.has_key('extra_dist'): + plugin['extra_dist']=" ".join([os.path.join(plugin['rel_path'],f) for f in plugin['extra_dist'].split()]) + plugin['build_conditional_tag']= "BUILD_%s_PLUGIN" % plugin['name'].upper() plugin['name_with_dashes']= plugin['name'].replace('_','-') @@ -348,18 +369,24 @@ def find_testsuite(plugin_dir): return "" return None +def find_docs(plugin_dir): + if os.path.isfile(os.path.join(plugin_dir, "docs", "index.rst")): + return os.path.join(plugin_dir, "docs") + def read_plugin_ini(plugin_dir): + sources_default="" if plugin_dir == ".": plugin_name="**OUT-OF-TREE**" + module_name="**OUT-OF-TREE**" else: - short_name=os.path.basename(plugin_dir) + sources_default="%s.cc" % os.path.basename(plugin_dir) plugin_name = plugin_dir[plugin_dir.index(config['root_plugin_dir']) + len(config['root_plugin_dir']) + 1:] module_name = plugin_name.replace("/", config['module_name_separator']).replace("\\", config['module_name_separator']) plugin_name = plugin_name.replace("/", config['plugin_name_separator']).replace("\\", config['plugin_name_separator']) plugin_file= os.path.join(plugin_dir,config['plugin_ini_fname']) - plugin_defaults= dict(sources="%s.cc" % short_name, + plugin_defaults= dict(sources=sources_default, headers="", install_headers="", cflags="", @@ -394,7 +421,6 @@ def read_plugin_ini(plugin_dir): sys.exit(1) if not plugin.has_key('version'): plugin['version'] = config['default_plugin_version'] - if plugin.has_key('load_by_default'): plugin['load_by_default']=parser.getboolean('plugin','load_by_default') if plugin.has_key('disabled'): @@ -404,12 +430,19 @@ def read_plugin_ini(plugin_dir): else: plugin['enabled']="yes" if plugin.has_key('static'): - plugin['static']= parser.getboolean('plugin','static') + try: + plugin['static']= parser.getboolean('plugin','static') + except: + if plugin['static'][:5] == os.sys.platform[:5]: + plugin['static']= True + else: + plugin['static']= False if plugin.has_key('install'): plugin['install']= parser.getboolean('plugin','install') if plugin.has_key('testsuite'): if plugin['testsuite'] == 'disable': plugin['testsuite']= False + plugin['dist_testsuite']= find_testsuite(plugin_dir) else: plugin_testsuite= find_testsuite(plugin_dir) plugin['testsuitedir']=plugin_testsuite @@ -417,6 +450,7 @@ def read_plugin_ini(plugin_dir): plugin['testsuite']=True else: plugin['testsuite']=False + plugin['docs']= find_docs(plugin_dir) plugin['cflags']+= ' ' + config['extra_cflags'] plugin['cppflags']+= ' ' + config['extra_cppflags'] @@ -471,6 +505,8 @@ EXTRA_DIST += %(rel_path)s/plugin.ini %(rel_path)s/plugin.ini: """ % plugin) + if plugin.has_key('extra_dist') and plugin['extra_dist'] != "": + plugin_am.write("EXTRA_DIST += %(extra_dist)s\n" % plugin) if plugin['headers'] != "": plugin_am.write("noinst_HEADERS += %(headers)s\n" % plugin) if plugin['install_headers'] != "": @@ -478,6 +514,10 @@ EXTRA_DIST += %(rel_path)s/plugin.ini if plugin['testsuite']: if plugin.has_key('testsuitedir') and plugin['testsuitedir'] != "": plugin_am.write("EXTRA_DIST += %(rel_path)s/%(testsuitedir)s\n" % plugin) + if plugin.has_key('dist_testsuite') and plugin['dist_testsuite'] != "": + plugin_am.write("EXTRA_DIST += %(rel_path)s/%(dist_testsuite)s\n" % plugin) + if plugin['docs'] is not None: + plugin_am.write("EXTRA_DIST += ${top_srcdir}/%(rel_path)s/docs/*.rst\n" % plugin) if plugin['static']: plugin_am.write(""" %(root_plugin_dir)s_%(plugin_prefix)s%(name)s_dir=${top_srcdir}/%(rel_path)s @@ -593,7 +633,6 @@ os.path.walk(os.path.join(config['top_srcdir'], accumulate_plugins, plugin_list) - if not os.path.exists("config/pandora-plugin.am") or "write" in actions: plugin_am_file = ChangeProtectedFile(os.path.join('config', 'pandora-plugin.am')) plugin_am_file.write(""" @@ -624,6 +663,17 @@ if not os.path.exists("config/pandora-plugin.ac") or "write" in actions: plugin_ac_file = ChangeProtectedFile(os.path.join('config', 'pandora-plugin.ac')) plugin_ac_file.write("dnl Generated file, run make to rebuild\n") +if os.path.exists("docs/plugins"): + if not os.path.exists("docs/plugins/list.rst") or "write" in actions: + plugin_doc_index = ChangeProtectedFile("docs/plugins/list.rst") + plugin_doc_index.write(""" +Plugin Documentation +==================== + +.. toctree:: + :maxdepth: 2 +""") + if os.path.exists('plugin.ini'): # Are we in a plugin dir which wants to have a self-sufficient build system? @@ -665,3 +715,5 @@ if plugin_am_file is not None: plugin_am_file.close() if plugin_ac_file is not None: plugin_ac_file.close() +if plugin_doc_index is not None: + plugin_doc_index.close() diff --git a/configure.ac b/configure.ac index 0a2df059..716cb6b7 100644 --- a/configure.ac +++ b/configure.ac @@ -7,16 +7,16 @@ # the COPYING file in this directory for full text. AC_PREREQ(2.59) -AC_INIT([libmemcached],[0.43],[http://libmemcached.org/]) +AC_INIT([libmemcached],[0.46],[http://libmemcached.org/]) AC_CONFIG_SRCDIR([libmemcached/memcached.c]) AC_CONFIG_AUX_DIR(config) -PANDORA_CANONICAL_TARGET +PANDORA_CANONICAL_TARGET(no-vc-changelog) #shared library versioning MEMCACHED_UTIL_LIBRARY_VERSION=1:0:0 MEMCACHED_PROTOCAL_LIBRARY_VERSION=0:0:0 -MEMCACHED_LIBRARY_VERSION=5:2:0 +MEMCACHED_LIBRARY_VERSION=6:0:0 # | | | # +------+ | +---+ # | | | @@ -101,6 +101,7 @@ DETECT_BYTEORDER ENABLE_UTILLIB SETSOCKOPT_SANITY ENABLE_HSIEH_HASH +ENABLE_MURMUR_HASH PROTOCOL_BINARY_TEST WITH_MEMCACHED ENABLE_DEPRECATED @@ -139,26 +140,11 @@ AC_CHECK_HEADERS_ONCE(winsock2.h poll.h sys/wait.h fnmatch.h) AM_CONDITIONAL(BUILD_POLL, test "x$ac_cv_header_poll_h" = "xno") AM_CONDITIONAL(BUILD_WIN32_WRAPPERS, test "x$ac_cv_header_winsock2_h" = "xyes") AS_IF(test "x$ac_cv_header_winsock2_h" = "xyes", - AM_LDFLAGS="$AM_LDFLAGS -lws2_32") - -# -# Some platforms define EWOULDBLOCK == EAGAIN, causing our switch for error -# codes to be illegal (POSIX.1-2001 allows both return codes from recv, so -# we need to test both if they differ...) -# -AC_MSG_CHECKING([if EWOULDBLOCK == EAGAIN]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([ -#include - ], [dnl - return EAGAIN == EWOULDBLOCK ? 0 : 1; - ]) - ],[ - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - AC_DEFINE([USE_EAGAIN], [1], [Define to true if you need to test for eagain]) - ]) + [AM_LDFLAGS="$AM_LDFLAGS -lws2_32" + AM_CFLAGS="$AM_CFLAGS $NO_WERROR" + AM_CXXFLAGS="$AM_CXXFLAGS $NO_WERROR" + ]) +DETECT_EAGAIN AC_CONFIG_FILES([ Makefile diff --git a/docs/memcached_behavior.pod b/docs/memcached_behavior.pod index eea90891..02ab0de4 100644 --- a/docs/memcached_behavior.pod +++ b/docs/memcached_behavior.pod @@ -239,13 +239,13 @@ Specify time, in seconds, to mark a connection as idle. This is only available a Find the current size of SO_SNDBUF. A value of 0 means either an error occured or no hosts were available. It is safe to assume system default -if this occurs. +if this occurs. If an error occurs you can checked the last cached errno statement to find the specific error. =item MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE Find the current size of SO_RCVBUF. A value of 0 means either an error occured or no hosts were available. It is safe to assume system default -if this occurs. +if this occurs. If an error occurs you can checked the last cached errno statement to find the specific error. =item MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT @@ -262,6 +262,11 @@ in combination with MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT. When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior. +=item MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY + +When enabled the prefix key will be added to the key when determining +server by hash. + =back =head1 RETURN diff --git a/libhashkit/algorithm.c b/libhashkit/algorithm.c index e8f859e8..0f0f9f01 100644 --- a/libhashkit/algorithm.c +++ b/libhashkit/algorithm.c @@ -45,10 +45,12 @@ uint32_t libhashkit_hsieh(const char *key, size_t key_length) } #endif +#ifdef HAVE_MURMUR_HASH uint32_t libhashkit_murmur(const char *key, size_t key_length) { return hashkit_murmur(key, key_length, NULL); } +#endif uint32_t libhashkit_jenkins(const char *key, size_t key_length) { diff --git a/libhashkit/algorithm.h b/libhashkit/algorithm.h index 40ab98ae..052575c9 100644 --- a/libhashkit/algorithm.h +++ b/libhashkit/algorithm.h @@ -41,8 +41,10 @@ HASHKIT_API uint32_t libhashkit_hsieh(const char *key, size_t key_length); #endif +#ifdef HAVE_MURMUR_HASH HASHKIT_API uint32_t libhashkit_murmur(const char *key, size_t key_length); +#endif HASHKIT_API uint32_t libhashkit_jenkins(const char *key, size_t key_length); @@ -73,8 +75,10 @@ HASHKIT_LOCAL uint32_t hashkit_hsieh(const char *key, size_t key_length, void *context); #endif +#ifdef HAVE_MURMUR_HASH HASHKIT_LOCAL uint32_t hashkit_murmur(const char *key, size_t key_length, void *context); +#endif HASHKIT_LOCAL uint32_t hashkit_jenkins(const char *key, size_t key_length, void *context); diff --git a/libhashkit/common.h b/libhashkit/common.h index b2aaf0e2..dff3ab0b 100644 --- a/libhashkit/common.h +++ b/libhashkit/common.h @@ -9,10 +9,6 @@ #ifndef HASHKIT_COMMON_H #define HASHKIT_COMMON_H -#ifdef __cplusplus -extern "C" { -#endif - #include "config.h" #include @@ -23,6 +19,10 @@ extern "C" { #include "hashkit.h" +#ifdef __cplusplus +extern "C" { +#endif + HASHKIT_LOCAL void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result); diff --git a/libhashkit/digest.c b/libhashkit/digest.c index bca6b5b5..4ff6de29 100644 --- a/libhashkit/digest.c +++ b/libhashkit/digest.c @@ -38,7 +38,11 @@ uint32_t libhashkit_digest(const char *key, size_t key_length, hashkit_hash_algo return 1; #endif case HASHKIT_HASH_MURMUR: +#ifdef HAVE_MURMUR_HASH return libhashkit_murmur(key, key_length); +#else + return 1; +#endif case HASHKIT_HASH_JENKINS: return libhashkit_jenkins(key, key_length); case HASHKIT_HASH_CUSTOM: diff --git a/libhashkit/function.c b/libhashkit/function.c index 25c929bd..2e68b583 100644 --- a/libhashkit/function.c +++ b/libhashkit/function.c @@ -41,8 +41,12 @@ static hashkit_return_t _set_function(struct hashkit_function_st *self, hashkit_ return HASHKIT_FAILURE; #endif case HASHKIT_HASH_MURMUR: +#ifdef HAVE_MURMUR_HASH self->function= hashkit_murmur; break; +#else + return HASHKIT_FAILURE; +#endif case HASHKIT_HASH_JENKINS: self->function= hashkit_jenkins; break; @@ -126,10 +130,12 @@ static hashkit_hash_algorithm_t get_function_type(const hashkit_hash_fn function return HASHKIT_HASH_HSIEH; } #endif +#ifdef HAVE_MURMUR_HASH else if (function == hashkit_murmur) { return HASHKIT_HASH_MURMUR; } +#endif else if (function == hashkit_jenkins) { return HASHKIT_HASH_JENKINS; diff --git a/libhashkit/include.am b/libhashkit/include.am index e800d798..f0adcdc9 100644 --- a/libhashkit/include.am +++ b/libhashkit/include.am @@ -40,7 +40,6 @@ libhashkit_libhashkit_la_SOURCES= \ libhashkit/jenkins.c \ libhashkit/ketama.c \ libhashkit/md5.c \ - libhashkit/murmur.c \ libhashkit/one_at_a_time.c \ libhashkit/strerror.c @@ -48,6 +47,10 @@ if INCLUDE_HSIEH_SRC libhashkit_libhashkit_la_SOURCES+= libhashkit/hsieh.c endif +if INCLUDE_MURMUR_SRC +libhashkit_libhashkit_la_SOURCES+= libhashkit/murmur.c +endif + libhashkit_libhashkit_la_CFLAGS= \ ${AM_CFLAGS} \ -DBUILDING_HASHKIT diff --git a/libmemcached/auto.c b/libmemcached/auto.c index b73425f0..a221144f 100644 --- a/libmemcached/auto.c +++ b/libmemcached/auto.c @@ -18,7 +18,6 @@ static memcached_return_t text_incr_decr(memcached_st *ptr, uint64_t offset, uint64_t *value) { - size_t send_length; memcached_return_t rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; uint32_t server_key; @@ -34,16 +33,17 @@ static memcached_return_t text_incr_decr(memcached_st *ptr, server_key= memcached_generate_hash_with_redistribution(ptr, master_key, master_key_length); instance= memcached_server_instance_fetch(ptr, server_key); - send_length= (size_t)snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s%.*s %" PRIu64 "%s\r\n", verb, - (int)ptr->prefix_key_length, - ptr->prefix_key, - (int)key_length, key, - offset, no_reply ? " noreply" : ""); - unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + int send_length; + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "%s %.*s%.*s %" PRIu64 "%s\r\n", verb, + (int)ptr->prefix_key_length, + ptr->prefix_key, + (int)key_length, key, + offset, no_reply ? " noreply" : ""); + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) return MEMCACHED_WRITE_FAILURE; - rc= memcached_do(instance, buffer, send_length, true); + rc= memcached_do(instance, buffer, (size_t)send_length, true); if (no_reply || rc != MEMCACHED_SUCCESS) return rc; @@ -60,7 +60,7 @@ static memcached_return_t text_incr_decr(memcached_st *ptr, { *value= 0; rc= MEMCACHED_PROTOCOL_ERROR; - } + } else if (! strncmp(buffer, "CLIENT_ERROR\r\n", 14)) { *value= 0; @@ -116,12 +116,12 @@ static memcached_return_t binary_incr_decr(memcached_st *ptr, uint8_t cmd, request.message.body.initial= htonll(initial); request.message.body.expiration= htonl((uint32_t) expiration); - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= sizeof(request.bytes), .buffer= request.bytes }, { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, { .length= key_length, .buffer= key } - }; + }; memcached_return_t rc; if ((rc= memcached_vdo(instance, vector, 3, true)) != MEMCACHED_SUCCESS) diff --git a/libmemcached/behavior.c b/libmemcached/behavior.c index b84e770a..2b6ccdf9 100644 --- a/libmemcached/behavior.c +++ b/libmemcached/behavior.c @@ -313,11 +313,20 @@ uint64_t memcached_behavior_get(memcached_st *ptr, /* REFACTOR */ /* We just try the first host, and if it is down we return zero */ if ((memcached_connect(instance)) != MEMCACHED_SUCCESS) + { + return 0; + } + + if (memcached_io_wait_for_write(instance) != MEMCACHED_SUCCESS) + { return 0; + } - if (getsockopt(instance->fd, SOL_SOCKET, - SO_SNDBUF, &sock_size, &sock_length)) + if (getsockopt(instance->fd, SOL_SOCKET, SO_SNDBUF, &sock_size, &sock_length) < 0) + { + ptr->cached_errno= errno; return 0; /* Zero means error */ + } } return (uint64_t) sock_size; @@ -340,11 +349,20 @@ uint64_t memcached_behavior_get(memcached_st *ptr, { /* We just try the first host, and if it is down we return zero */ if ((memcached_connect(instance)) != MEMCACHED_SUCCESS) + { + return 0; + } + + if (memcached_io_wait_for_write(instance) != MEMCACHED_SUCCESS) + { return 0; + } - if (getsockopt(instance->fd, SOL_SOCKET, - SO_RCVBUF, &sock_size, &sock_length)) + if (getsockopt(instance->fd, SOL_SOCKET, SO_RCVBUF, &sock_size, &sock_length) < 0) + { + ptr->cached_errno= errno; return 0; /* Zero means error */ + } } diff --git a/libmemcached/byteorder.c b/libmemcached/byteorder.c index 96a39bf8..97d14f2b 100644 --- a/libmemcached/byteorder.c +++ b/libmemcached/byteorder.c @@ -32,12 +32,12 @@ static inline uint64_t swap64(uint64_t in) } #endif -uint64_t ntohll(uint64_t value) +uint64_t memcached_ntohll(uint64_t value) { return swap64(value); } -uint64_t htonll(uint64_t value) +uint64_t memcached_htonll(uint64_t value) { return swap64(value); } diff --git a/libmemcached/byteorder.h b/libmemcached/byteorder.h index f43dbc43..90a71ee4 100644 --- a/libmemcached/byteorder.h +++ b/libmemcached/byteorder.h @@ -27,10 +27,13 @@ #include "libmemcached/memcached.h" #ifndef HAVE_HTONLL +#define ntohll(a) memcached_ntohll(a) +#define htonll(a) memcached_htonll(a) + LIBMEMCACHED_LOCAL -uint64_t ntohll(uint64_t); +uint64_t memcached_ntohll(uint64_t); LIBMEMCACHED_LOCAL -uint64_t htonll(uint64_t); +uint64_t memcached_htonll(uint64_t); #endif #ifdef linux diff --git a/libmemcached/connect.c b/libmemcached/connect.c index 7b38def9..3afef7d3 100644 --- a/libmemcached/connect.c +++ b/libmemcached/connect.c @@ -19,16 +19,12 @@ static memcached_return_t connect_poll(memcached_server_st *ptr) fds[0].fd = ptr->fd; fds[0].events = POLLOUT; - int timeout= ptr->root->connect_timeout; - if (ptr->root->flags.no_block == true) - timeout= -1; - int error; size_t loop_max= 5; while (--loop_max) // Should only loop on cases of ERESTART or EINTR { - error= poll(fds, 1, timeout); + error= poll(fds, 1, ptr->root->connect_timeout); switch (error) { @@ -80,7 +76,6 @@ static memcached_return_t connect_poll(memcached_server_st *ptr) return MEMCACHED_ERRNO; } } - WATCHPOINT_ASSERT(0); // Programming error } // This should only be possible from ERESTART or EINTR; @@ -96,7 +91,9 @@ static memcached_return_t set_hostinfo(memcached_server_st *server) char str_port[NI_MAXSERV]; uint32_t counter= 5; - snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port); + int length= snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port); + if (length >= NI_MAXSERV || length < 0) + return MEMCACHED_FAILURE; memset(&hints, 0, sizeof(hints)); @@ -537,7 +534,7 @@ memcached_return_t memcached_connect(memcached_server_write_instance_st ptr) case MEMCACHED_CONNECTION_TCP: rc= network_connect(ptr); #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT - if (ptr->fd != INVALID_SOCKET && ptr->root->sasl && ptr->root->sasl->callbacks) + if (ptr->fd != INVALID_SOCKET && ptr->root->sasl.callbacks) { rc= memcached_sasl_authenticate_connection(ptr); if (rc != MEMCACHED_SUCCESS) diff --git a/libmemcached/delete.c b/libmemcached/delete.c index 70553d94..ef1fa6da 100644 --- a/libmemcached/delete.c +++ b/libmemcached/delete.c @@ -20,7 +20,6 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr, time_t expiration) { bool to_write; - size_t send_length; memcached_return_t rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; uint32_t server_key; @@ -56,6 +55,8 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr, } else { + int send_length; + unlikely (expiration) { if ((instance->major_version == 1 && @@ -89,25 +90,25 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr, no_reply= false; } } - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "delete %.*s%.*s %u%s\r\n", - (int)ptr->prefix_key_length, - ptr->prefix_key, - (int) key_length, key, - (uint32_t)expiration, - no_reply ? " noreply" :"" ); + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "delete %.*s%.*s %u%s\r\n", + (int)ptr->prefix_key_length, + ptr->prefix_key, + (int) key_length, key, + (uint32_t)expiration, + no_reply ? " noreply" :"" ); } } else { - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "delete %.*s%.*s%s\r\n", - (int)ptr->prefix_key_length, - ptr->prefix_key, - (int)key_length, key, no_reply ? " noreply" :""); + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "delete %.*s%.*s%s\r\n", + (int)ptr->prefix_key_length, + ptr->prefix_key, + (int)key_length, key, no_reply ? " noreply" :""); } - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) { rc= MEMCACHED_WRITE_FAILURE; goto error; @@ -121,7 +122,7 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr, memcached_io_write(instance, NULL, 0, true); } - rc= memcached_do(instance, buffer, send_length, to_write); + rc= memcached_do(instance, buffer, (size_t)send_length, to_write); } if (rc != MEMCACHED_SUCCESS) @@ -175,12 +176,12 @@ static inline memcached_return_t binary_delete(memcached_st *ptr, memcached_io_write(instance, NULL, 0, true); } - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= sizeof(request.bytes), .buffer= request.bytes}, { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, { .length= key_length, .buffer= key }, - }; + }; memcached_return_t rc= MEMCACHED_SUCCESS; diff --git a/libmemcached/do.c b/libmemcached/do.c index 1a274cd3..14824a64 100644 --- a/libmemcached/do.c +++ b/libmemcached/do.c @@ -5,13 +5,13 @@ * Use and distribution licensed under the BSD license. See * the COPYING file in the parent directory for full text. * - * Summary: + * Summary: * */ #include "common.h" -memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *command, +memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *command, size_t command_length, bool with_flush) { memcached_return_t rc; @@ -51,7 +51,7 @@ memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const vo } memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr, - const struct __write_vector_st *vector, size_t count, + const struct libmemcached_io_vector_st *vector, size_t count, bool with_flush) { memcached_return_t rc; diff --git a/libmemcached/do.h b/libmemcached/do.h index d6d018d9..2506ddf2 100644 --- a/libmemcached/do.h +++ b/libmemcached/do.h @@ -17,14 +17,14 @@ extern "C" { #endif LIBMEMCACHED_LOCAL -memcached_return_t memcached_do(memcached_server_write_instance_st ptr, +memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *commmand, size_t command_length, bool with_flush); LIBMEMCACHED_LOCAL memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr, - const struct __write_vector_st *vector, size_t count, + const struct libmemcached_io_vector_st *vector, size_t count, bool with_flush); #ifdef __cplusplus diff --git a/libmemcached/dump.c b/libmemcached/dump.c index a0d62df0..9ec2dab5 100644 --- a/libmemcached/dump.c +++ b/libmemcached/dump.c @@ -11,7 +11,6 @@ static memcached_return_t ascii_dump(memcached_st *ptr, memcached_dump_fn *callb { memcached_return_t rc= MEMCACHED_SUCCESS; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - size_t send_length; uint32_t server_key; uint32_t x; @@ -26,10 +25,16 @@ static memcached_return_t ascii_dump(memcached_st *ptr, memcached_dump_fn *callb /* 256 I BELIEVE is the upper limit of slabs */ for (x= 0; x < 256; x++) { - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "stats cachedump %u 0 0\r\n", x); + int send_length; + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "stats cachedump %u 0 0\r\n", x); - rc= memcached_do(instance, buffer, send_length, true); + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) + { + return MEMCACHED_FAILURE; + } + + rc= memcached_do(instance, buffer, (size_t)send_length, true); unlikely (rc != MEMCACHED_SUCCESS) goto error; diff --git a/libmemcached/flush.c b/libmemcached/flush.c index 425d4576..5aaffa56 100644 --- a/libmemcached/flush.c +++ b/libmemcached/flush.c @@ -21,29 +21,37 @@ memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration) static memcached_return_t memcached_flush_textual(memcached_st *ptr, time_t expiration) { - unsigned int x; - size_t send_length; - memcached_return_t rc; - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - unlikely (memcached_server_count(ptr) == 0) return MEMCACHED_NO_SERVERS; - for (x= 0; x < memcached_server_count(ptr); x++) + for (unsigned int x= 0; x < memcached_server_count(ptr); x++) { + memcached_return_t rc; + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + bool no_reply= ptr->flags.no_reply; memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x); + int send_length; if (expiration) - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "flush_all %llu%s\r\n", - (unsigned long long)expiration, no_reply ? " noreply" : ""); + { + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "flush_all %llu%s\r\n", + (unsigned long long)expiration, no_reply ? " noreply" : ""); + } else - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "flush_all%s\r\n", no_reply ? " noreply" : ""); + { + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "flush_all%s\r\n", no_reply ? " noreply" : ""); + } + + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) + { + return MEMCACHED_FAILURE; + } - rc= memcached_do(instance, buffer, send_length, true); + rc= memcached_do(instance, buffer, (size_t)send_length, true); if (rc == MEMCACHED_SUCCESS && !no_reply) (void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL); diff --git a/libmemcached/flush_buffers.c b/libmemcached/flush_buffers.c index 0a902757..649db983 100644 --- a/libmemcached/flush_buffers.c +++ b/libmemcached/flush_buffers.c @@ -17,8 +17,11 @@ memcached_return_t memcached_flush_buffers(memcached_st *memc) WATCHPOINT_ERROR(ret); return ret; } + if (memcached_io_write(instance, NULL, 0, true) == -1) + { ret= MEMCACHED_SOME_ERRORS; + } } } diff --git a/libmemcached/get.c b/libmemcached/get.c index 55457f7f..aa4e6f53 100644 --- a/libmemcached/get.c +++ b/libmemcached/get.c @@ -1,5 +1,5 @@ /* LibMemcached - * Copyright (C) 2006-2009 Brian Aker + * Copyright (C) 2006-2009 Brian Aker * All rights reserved. * * Use and distribution licensed under the BSD license. See @@ -144,7 +144,7 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, size_t number_of_keys, bool mget_mode) { - memcached_return_t rc= MEMCACHED_NOTFOUND; + bool failures_occured_in_sending= false; const char *get_command= "get "; uint8_t get_command_length= 4; unsigned int master_server_key= (unsigned int)-1; /* 0 is a valid server id! */ @@ -211,6 +211,8 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, If a server fails we warn about errors and start all over with sending keys to the server. */ + memcached_return_t rc= MEMCACHED_SUCCESS; + size_t hosts_connected= 0; for (uint32_t x= 0; x < number_of_keys; x++) { memcached_server_write_instance_st instance; @@ -227,13 +229,13 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, instance= memcached_server_instance_fetch(ptr, server_key); - struct __write_vector_st vector[]= - { - { .length= get_command_length, .buffer= get_command }, - { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, - { .length= key_length[x], .buffer= keys[x] }, - { .length= 1, .buffer= " " } - }; + struct libmemcached_io_vector_st vector[]= + { + { .length= get_command_length, .buffer= get_command }, + { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, + { .length= key_length[x], .buffer= keys[x] }, + { .length= 1, .buffer= " " } + }; if (memcached_server_response_count(instance) == 0) @@ -241,11 +243,14 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, rc= memcached_connect(instance); if (rc != MEMCACHED_SUCCESS) + { continue; + } + hosts_connected++; if ((memcached_io_writev(instance, vector, 4, false)) == -1) { - rc= MEMCACHED_SOME_ERRORS; + failures_occured_in_sending= true; continue; } WATCHPOINT_ASSERT(instance->cursor_active == 0); @@ -257,15 +262,27 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, if ((memcached_io_writev(instance, (vector + 1), 3, false)) == -1) { memcached_server_response_reset(instance); - rc= MEMCACHED_SOME_ERRORS; + failures_occured_in_sending= true; continue; } } } + if (hosts_connected == 0) + { + LIBMEMCACHED_MEMCACHED_MGET_END(); + + if (rc != MEMCACHED_SUCCESS) + return rc; + + return MEMCACHED_NO_SERVERS; + } + + /* Should we muddle on if some servers are dead? */ + bool success_happened= false; for (uint32_t x= 0; x < memcached_server_count(ptr); x++) { memcached_server_write_instance_st instance= @@ -276,13 +293,24 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, /* We need to do something about non-connnected hosts in the future */ if ((memcached_io_write(instance, "\r\n", 2, true)) == -1) { - rc= MEMCACHED_SOME_ERRORS; + failures_occured_in_sending= true; + } + else + { + success_happened= true; } } } LIBMEMCACHED_MEMCACHED_MGET_END(); - return rc; + + if (failures_occured_in_sending && success_happened) + return MEMCACHED_SOME_ERRORS; + + if (success_happened) + return MEMCACHED_SUCCESS; + + return MEMCACHED_FAILURE; } memcached_return_t memcached_mget_by_key(memcached_st *ptr, @@ -399,12 +427,12 @@ static memcached_return_t simple_binary_mget(memcached_st *ptr, request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES; request.message.header.request.bodylen= htonl((uint32_t)( key_length[x] + ptr->prefix_key_length)); - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= sizeof(request.bytes), .buffer= request.bytes }, { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, { .length= key_length[x], .buffer= keys[x] } - }; + }; if (memcached_io_writev(instance, vector, 3, flush) == -1) { @@ -533,12 +561,12 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, * that we might have processed some of the responses etc. For now, * just make sure we work _correctly_ */ - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= sizeof(request.bytes), .buffer= request.bytes }, { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, { .length= key_length[x], .buffer= keys[x] } - }; + }; if (memcached_io_writev(instance, vector, 3, true) == -1) { diff --git a/libmemcached/hosts.c b/libmemcached/hosts.c index 4018a258..ec12c92f 100644 --- a/libmemcached/hosts.c +++ b/libmemcached/hosts.c @@ -206,15 +206,20 @@ static memcached_return_t update_continuum(memcached_st *ptr) pointer_index++) { char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= ""; - size_t sort_host_length; + int sort_host_length; // Spymemcached ketema key format is: hostname/ip:port-index // If hostname is not available then: /ip:port-index - sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, - "/%s:%u-%u", - list[host_index].hostname, - (uint32_t)list[host_index].port, - pointer_index); + sort_host_length= snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, + "/%s:%u-%u", + list[host_index].hostname, + (uint32_t)list[host_index].port, + pointer_index); + + if (sort_host_length >= MEMCACHED_MAX_HOST_SORT_LENGTH || sort_host_length < 0) + { + return MEMCACHED_FAILURE; + } #ifdef DEBUG printf("update_continuum: key is %s\n", sort_host); #endif @@ -225,14 +230,14 @@ static memcached_return_t update_continuum(memcached_st *ptr) { for (uint32_t x= 0; x < pointer_per_hash; x++) { - value= ketama_server_hash(sort_host, sort_host_length, x); + value= ketama_server_hash(sort_host, (size_t)sort_host_length, x); ptr->continuum[continuum_index].index= host_index; ptr->continuum[continuum_index++].value= value; } } else { - value= hashkit_digest(&ptr->distribution_hashkit, sort_host, sort_host_length); + value= hashkit_digest(&ptr->distribution_hashkit, sort_host, (size_t)sort_host_length); ptr->continuum[continuum_index].index= host_index; ptr->continuum[continuum_index++].value= value; } @@ -245,22 +250,27 @@ static memcached_return_t update_continuum(memcached_st *ptr) pointer_index++) { char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= ""; - size_t sort_host_length; + int sort_host_length; if (list[host_index].port == MEMCACHED_DEFAULT_PORT) { - sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, - "%s-%u", - list[host_index].hostname, - pointer_index - 1); + sort_host_length= snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, + "%s-%u", + list[host_index].hostname, + pointer_index - 1); } else { - sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, - "%s:%u-%u", - list[host_index].hostname, - (uint32_t)list[host_index].port, - pointer_index - 1); + sort_host_length= snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, + "%s:%u-%u", + list[host_index].hostname, + (uint32_t)list[host_index].port, + pointer_index - 1); + } + + if (sort_host_length >= MEMCACHED_MAX_HOST_SORT_LENGTH || sort_host_length < 0) + { + return MEMCACHED_FAILURE; } WATCHPOINT_ASSERT(sort_host_length); @@ -269,14 +279,14 @@ static memcached_return_t update_continuum(memcached_st *ptr) { for (uint32_t x = 0; x < pointer_per_hash; x++) { - value= ketama_server_hash(sort_host, sort_host_length, x); + value= ketama_server_hash(sort_host, (size_t)sort_host_length, x); ptr->continuum[continuum_index].index= host_index; ptr->continuum[continuum_index++].value= value; } } else { - value= hashkit_digest(&ptr->distribution_hashkit, sort_host, sort_host_length); + value= hashkit_digest(&ptr->distribution_hashkit, sort_host, (size_t)sort_host_length); ptr->continuum[continuum_index].index= host_index; ptr->continuum[continuum_index++].value= value; } diff --git a/libmemcached/include.am b/libmemcached/include.am index fccced99..e318f7ed 100644 --- a/libmemcached/include.am +++ b/libmemcached/include.am @@ -161,6 +161,7 @@ endif if DTRACE_NEEDS_OBJECTS libmemcached_libmemcached_la_SOURCES += libmemcached/libmemcached_probes.d libmemcached_libmemcached_la_DEPENDENCIES += libmemcached/libmemcached_probes.o +libmemcached_libmemcached_la_LIBADD += libmemcached/libmemcached_probes.o CLEANFILES+= libmemcached/libmemcached_probes.o endif @@ -172,5 +173,5 @@ libmemcached/dtrace_probes.h: libmemcached/libmemcached_probes.d libmemcached/libmemcached_probes.o: libmemcached/libmemcached_probes.d ${libmemcached_libmemcached_la_OBJECTS} config.h .d.o: - $(DTRACE) $(DTRACEFLAGS) -o libmemcached/libmemcached_probes.o -G -s ${top_srcdir}/libmemcached/libmemcached_probes.d `grep '^pic_object' ${top_builddir}/libmemcached/*.lo | cut -f 2 -d\' | sed "s/^/${top_builddir}\//"` + $(DTRACE) $(DTRACEFLAGS) -o $@ -G -s $< `grep '^pic_object' ${top_builddir}/libmemcached/*.lo | cut -f 2 -d\' | sed "s/^/${top_builddir}\/libmemcached\//"` diff --git a/libmemcached/io.c b/libmemcached/io.c index 9a20609b..d3c5e4b6 100644 --- a/libmemcached/io.c +++ b/libmemcached/io.c @@ -55,14 +55,10 @@ static memcached_return_t io_wait(memcached_server_write_instance_st ptr, return MEMCACHED_FAILURE; } - int timeout= ptr->root->poll_timeout; - if (ptr->root->flags.no_block == false) - timeout= -1; - size_t loop_max= 5; while (--loop_max) // While loop is for ERESTART or EINTR { - error= poll(&fds, 1, timeout); + error= poll(&fds, 1, ptr->root->poll_timeout); switch (error) { @@ -109,6 +105,11 @@ static memcached_return_t io_wait(memcached_server_write_instance_st ptr, return MEMCACHED_FAILURE; } +memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr) +{ + return io_wait(ptr, MEM_WRITE); +} + /** * Try to fill the input buffer for a server with as much * data as possible. @@ -385,7 +386,9 @@ static ssize_t _io_write(memcached_server_write_instance_st ptr, buffer_end= MAX_UDP_DATAGRAM_LENGTH; should_write= length; if (ptr->write_buffer_offset + should_write > buffer_end) + { return -1; + } } else { @@ -408,7 +411,9 @@ static ssize_t _io_write(memcached_server_write_instance_st ptr, WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET); sent_length= io_flush(ptr, &rc); if (sent_length == -1) + { return -1; + } /* If io_flush calls memcached_purge, sent_length may be 0 */ unlikely (sent_length != 0) @@ -440,7 +445,7 @@ ssize_t memcached_io_write(memcached_server_write_instance_st ptr, } ssize_t memcached_io_writev(memcached_server_write_instance_st ptr, - const struct __write_vector_st *vector, + const struct libmemcached_io_vector_st *vector, size_t number_of, bool with_flush) { ssize_t total= 0; @@ -574,7 +579,9 @@ static ssize_t io_flush(memcached_server_write_instance_st ptr, rc= memcached_purge(ptr); if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_STORED) + { return -1; + } } ssize_t sent_length; size_t return_length; @@ -587,7 +594,9 @@ static ssize_t io_flush(memcached_server_write_instance_st ptr, // UDP Sanity check, make sure that we are not sending somthing too big if (ptr->type == MEMCACHED_CONNECTION_UDP && write_length > MAX_UDP_DATAGRAM_LENGTH) + { return -1; + } if (ptr->write_buffer_offset == 0 || (ptr->type == MEMCACHED_CONNECTION_UDP && ptr->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH)) @@ -609,12 +618,19 @@ static ssize_t io_flush(memcached_server_write_instance_st ptr, if (ptr->type == MEMCACHED_CONNECTION_UDP) increment_udp_message_id(ptr); + WATCHPOINT_ASSERT(ptr->fd != -1); +#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) sent_length= send(ptr->fd, local_write_ptr, write_length, 0); +#else + sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT); +#endif if (sent_length == SOCKET_ERROR) { ptr->cached_errno= get_socket_errno(); +#if 0 // @todo I should look at why we hit this bit of code hard frequently WATCHPOINT_ERRNO(get_socket_errno()); WATCHPOINT_NUMBER(get_socket_errno()); +#endif switch (get_socket_errno()) { case ENOBUFS: @@ -643,9 +659,12 @@ static ssize_t io_flush(memcached_server_write_instance_st ptr, memcached_quit_server(ptr, true); return -1; } + case ENOTCONN: + case EPIPE: default: memcached_quit_server(ptr, true); *error= MEMCACHED_ERRNO; + WATCHPOINT_ASSERT(ptr->fd == -1); return -1; } } diff --git a/libmemcached/io.h b/libmemcached/io.h index 30145823..3662954d 100644 --- a/libmemcached/io.h +++ b/libmemcached/io.h @@ -40,15 +40,18 @@ struct udp_datagram_header_st uint16_t reserved; }; -struct __write_vector_st +struct libmemcached_io_vector_st { size_t length; const void *buffer; }; +LIBMEMCACHED_LOCAL +memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr); + LIBMEMCACHED_LOCAL ssize_t memcached_io_writev(memcached_server_write_instance_st ptr, - const struct __write_vector_st *vector, + const struct libmemcached_io_vector_st *vector, size_t number_of, bool with_flush); LIBMEMCACHED_LOCAL diff --git a/libmemcached/memcached.c b/libmemcached/memcached.c index d5411e86..81895afa 100644 --- a/libmemcached/memcached.c +++ b/libmemcached/memcached.c @@ -92,7 +92,8 @@ static inline bool _memcached_init(memcached_st *self) self->get_key_failure= NULL; self->delete_trigger= NULL; self->callbacks= NULL; - self->sasl= NULL; + self->sasl.callbacks= NULL; + self->sasl.is_allocated= false; return true; } @@ -176,7 +177,7 @@ void memcached_free(memcached_st *ptr) if (ptr->continuum) libmemcached_free(ptr, ptr->continuum); - if (ptr->sasl) + if (ptr->sasl.callbacks) { #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT memcached_destroy_sasl_auth_data(ptr); @@ -273,7 +274,7 @@ memcached_st *memcached_clone(memcached_st *clone, const memcached_st *source) } #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT - if (source->sasl && source->sasl->callbacks) + if (source->sasl.callbacks) { if (memcached_clone_sasl(new_clone, source) != MEMCACHED_SUCCESS) { diff --git a/libmemcached/memcached.h b/libmemcached/memcached.h index 58f9f673..c099d76e 100644 --- a/libmemcached/memcached.h +++ b/libmemcached/memcached.h @@ -124,7 +124,7 @@ struct memcached_st { memcached_trigger_key_fn get_key_failure; memcached_trigger_delete_key_fn delete_trigger; memcached_callback_st *callbacks; - struct memcached_sasl_st *sasl; + struct memcached_sasl_st sasl; char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE]; struct { bool is_allocated:1; diff --git a/libmemcached/platform.h b/libmemcached/platform.h index 9eafbb14..e7511cad 100644 --- a/libmemcached/platform.h +++ b/libmemcached/platform.h @@ -20,11 +20,11 @@ typedef SOCKET memcached_socket_t; #else typedef int memcached_socket_t; #include +#include #include #include #include #include -#include #endif /* WIN32 */ diff --git a/libmemcached/protocol/ascii_handler.c b/libmemcached/protocol/ascii_handler.c index 6f5102b0..465b7396 100644 --- a/libmemcached/protocol/ascii_handler.c +++ b/libmemcached/protocol/ascii_handler.c @@ -92,10 +92,10 @@ static void send_command_usage(memcached_protocol_client_st *client) */ static protocol_binary_response_status ascii_version_response_handler(const void *cookie, - const void *text, - uint32_t textlen) + const void *text, + uint32_t textlen) { - memcached_protocol_client_st *client= (void*)cookie; + memcached_protocol_client_st *client= (memcached_protocol_client_st*)cookie; spool_string(client, "VERSION "); client->root->spool(client, text, textlen); spool_string(client, "\r\n"); @@ -146,8 +146,8 @@ ascii_get_response_handler(const void *cookie, if (client->ascii_command == GETS_CMD) { - snprintf(dest, sizeof(buffer) - used, " %u %u %llu\r\n", flags, - bodylen, (unsigned long long)cas); + snprintf(dest, sizeof(buffer) - used, " %u %u %" PRIu64 "\r\n", flags, + bodylen, cas); } else { @@ -440,8 +440,7 @@ static void process_arithmetic(memcached_protocol_client_st *client, if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { char buffer[80]; - snprintf(buffer, sizeof(buffer), "%llu\r\n", - (unsigned long long)result); + snprintf(buffer, sizeof(buffer), "%"PRIu64"\r\n", result); spool_string(client, buffer); } else diff --git a/libmemcached/protocol/common.h b/libmemcached/protocol/common.h index f7fa6044..185aef0b 100644 --- a/libmemcached/protocol/common.h +++ b/libmemcached/protocol/common.h @@ -93,7 +93,7 @@ enum ascii_cmd { VERSION_CMD, QUIT_CMD, VERBOSITY_CMD, - UNKNOWN_CMD, + UNKNOWN_CMD }; struct memcached_protocol_client_st { diff --git a/libmemcached/quit.c b/libmemcached/quit.c index 18a9a316..251f578c 100644 --- a/libmemcached/quit.c +++ b/libmemcached/quit.c @@ -65,12 +65,17 @@ void memcached_quit_server(memcached_server_st *ptr, bool io_death) } ptr->fd= -1; + ptr->io_bytes_sent= 0; ptr->write_buffer_offset= (size_t) ((ptr->type == MEMCACHED_CONNECTION_UDP) ? UDP_DATAGRAM_HEADER_LENGTH : 0); ptr->read_buffer_length= 0; ptr->read_ptr= ptr->read_buffer; ptr->options.is_shutting_down= false; memcached_server_response_reset(ptr); + // We reset the version so that if we end up talking to a different server + // we don't have stale server version information. + ptr->major_version= ptr->minor_version= ptr->micro_version= UINT8_MAX; + if (io_death) { ptr->server_failure_counter++; diff --git a/libmemcached/result.c b/libmemcached/result.c index dae53bf7..c6c754f3 100644 --- a/libmemcached/result.c +++ b/libmemcached/result.c @@ -92,7 +92,14 @@ memcached_return_t memcached_result_set_value(memcached_result_st *ptr, const char *value, size_t length) { - return memcached_string_append(&ptr->value, value, length); + memcached_return_t rc= memcached_string_append(&ptr->value, value, length); + + if (rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE) + { + ((memcached_st *)ptr->root)->cached_errno= errno; + } + + return rc; } const char *memcached_result_key_value(const memcached_result_st *self) diff --git a/libmemcached/sasl.c b/libmemcached/sasl.c index 85edeb3d..0dedb52d 100644 --- a/libmemcached/sasl.c +++ b/libmemcached/sasl.c @@ -14,16 +14,13 @@ void memcached_set_sasl_callbacks(memcached_st *ptr, const sasl_callback_t *callbacks) { - ptr->sasl->callbacks= callbacks; - ptr->sasl->is_allocated= false; + ptr->sasl.callbacks= callbacks; + ptr->sasl.is_allocated= false; } const sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr) { - if (ptr->sasl) - return ptr->sasl->callbacks; - - return NULL; + return ptr->sasl.callbacks; } /** @@ -33,7 +30,7 @@ const sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr) * @param raddr remote address (out) * @return true on success false otherwise (errno contains more info) */ -static bool resolve_names(int fd, char *laddr, char *raddr) +static bool resolve_names(int fd, char *laddr, size_t laddr_length, char *raddr, size_t raddr_length) { char host[NI_MAXHOST]; char port[NI_MAXSERV]; @@ -47,7 +44,7 @@ static bool resolve_names(int fd, char *laddr, char *raddr) return false; } - (void)sprintf(laddr, "%s;%s", host, port); + (void)snprintf(laddr, laddr_length, "%s;%s", host, port); salen= sizeof(saddr); if ((getpeername(fd, (struct sockaddr *)&saddr, &salen) < 0) || @@ -57,7 +54,7 @@ static bool resolve_names(int fd, char *laddr, char *raddr) return false; } - (void)sprintf(raddr, "%s;%s", host, port); + (void)snprintf(raddr, raddr_length, "%s;%s", host, port); return true; } @@ -111,7 +108,7 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s char laddr[NI_MAXHOST + NI_MAXSERV]; char raddr[NI_MAXHOST + NI_MAXSERV]; - unlikely (!resolve_names(server->fd, laddr, raddr)) + unlikely (!resolve_names(server->fd, laddr, sizeof(laddr), raddr, sizeof(raddr))) { server->cached_errno= errno; return MEMCACHED_ERRNO; @@ -119,7 +116,7 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s sasl_conn_t *conn; int ret= sasl_client_new("memcached", server->hostname, laddr, raddr, - server->root->sasl->callbacks, 0, &conn); + server->root->sasl.callbacks, 0, &conn); if (ret != SASL_OK) { return MEMCACHED_AUTH_PROBLEM; @@ -144,12 +141,12 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s do { /* send the packet */ - struct __write_vector_st vector[]= - { - { .length= sizeof(request.bytes), .buffer= request.bytes }, - { .length= keylen, .buffer= chosenmech }, - { .length= len, .buffer= data } - }; + struct libmemcached_io_vector_st vector[]= + { + { .length= sizeof(request.bytes), .buffer= request.bytes }, + { .length= keylen, .buffer= chosenmech }, + { .length= len, .buffer= data } + }; if (memcached_io_writev(server, vector, 3, true) == -1) { @@ -221,7 +218,7 @@ memcached_return_t memcached_set_sasl_auth_data(memcached_st *ptr, const char *password) { if (ptr == NULL || username == NULL || - password == NULL || ptr->sasl->callbacks != NULL) + password == NULL || ptr->sasl.callbacks != NULL) { return MEMCACHED_FAILURE; } @@ -252,62 +249,52 @@ memcached_return_t memcached_set_sasl_auth_data(memcached_st *ptr, cb[2].context= secret; cb[3].id= SASL_CB_LIST_END; - ptr->sasl->callbacks= cb; - ptr->sasl->is_allocated= true; + ptr->sasl.callbacks= cb; + ptr->sasl.is_allocated= true; return MEMCACHED_SUCCESS; } memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *ptr) { - if (ptr == NULL || ptr->sasl->callbacks == NULL) + if (ptr == NULL || ptr->sasl.callbacks == NULL) { return MEMCACHED_FAILURE; } - if (ptr->sasl->is_allocated) + if (ptr->sasl.is_allocated) { - libmemcached_free(ptr, ptr->sasl->callbacks[0].context); - libmemcached_free(ptr, ptr->sasl->callbacks[2].context); - libmemcached_free(ptr, (void*)ptr->sasl->callbacks); - ptr->sasl->is_allocated= false; + libmemcached_free(ptr, ptr->sasl.callbacks[0].context); + libmemcached_free(ptr, ptr->sasl.callbacks[2].context); + libmemcached_free(ptr, (void*)ptr->sasl.callbacks); + ptr->sasl.is_allocated= false; } - ptr->sasl->callbacks= NULL; - libmemcached_free(ptr, ptr->sasl); - ptr->sasl= NULL; + ptr->sasl.callbacks= NULL; return MEMCACHED_SUCCESS; } memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st *source) { - if (source->sasl == NULL) + + if (source->sasl.callbacks == NULL) { return MEMCACHED_SUCCESS; } - else - { - clone->sasl= libmemcached_malloc(source, sizeof(struct memcached_sasl_st)); - - if (clone->sasl == NULL) - { - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - } - } /* Hopefully we are using our own callback mechanisms.. */ - if (source->sasl->callbacks[0].id == SASL_CB_USER && - source->sasl->callbacks[0].proc == get_username && - source->sasl->callbacks[1].id == SASL_CB_AUTHNAME && - source->sasl->callbacks[1].proc == get_username && - source->sasl->callbacks[2].id == SASL_CB_PASS && - source->sasl->callbacks[2].proc == get_password && - source->sasl->callbacks[3].id == SASL_CB_LIST_END) + if (source->sasl.callbacks[0].id == SASL_CB_USER && + source->sasl.callbacks[0].proc == get_username && + source->sasl.callbacks[1].id == SASL_CB_AUTHNAME && + source->sasl.callbacks[1].proc == get_username && + source->sasl.callbacks[2].id == SASL_CB_PASS && + source->sasl.callbacks[2].proc == get_password && + source->sasl.callbacks[3].id == SASL_CB_LIST_END) { - sasl_secret_t *secret= source->sasl->callbacks[2].context; + sasl_secret_t *secret= source->sasl.callbacks[2].context; return memcached_set_sasl_auth_data(clone, - source->sasl->callbacks[0].context, + source->sasl.callbacks[0].context, (const char*)secret->data); } @@ -318,9 +305,9 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st */ size_t total= 0; - while (source->sasl->callbacks[total].id != SASL_CB_LIST_END) + while (source->sasl.callbacks[total].id != SASL_CB_LIST_END) { - switch (source->sasl->callbacks[total].id) + switch (source->sasl.callbacks[total].id) { case SASL_CB_USER: case SASL_CB_AUTHNAME: @@ -339,38 +326,38 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st { return MEMCACHED_MEMORY_ALLOCATION_FAILURE; } - memcpy(cb, source->sasl->callbacks, (total + 1) * sizeof(sasl_callback_t)); + memcpy(cb, source->sasl.callbacks, (total + 1) * sizeof(sasl_callback_t)); /* Now update the context... */ for (size_t x= 0; x < total; ++x) { if (cb[x].id == SASL_CB_USER || cb[x].id == SASL_CB_AUTHNAME) { - cb[x].context= libmemcached_malloc(clone, strlen(source->sasl->callbacks[x].context)); + cb[x].context= libmemcached_malloc(clone, strlen(source->sasl.callbacks[x].context)); if (cb[x].context == NULL) { /* Failed to allocate memory, clean up previously allocated memory */ for (size_t y= 0; y < x; ++y) { - libmemcached_free(clone, clone->sasl->callbacks[y].context); + libmemcached_free(clone, clone->sasl.callbacks[y].context); } libmemcached_free(clone, cb); return MEMCACHED_MEMORY_ALLOCATION_FAILURE; } - strcpy(cb[x].context, source->sasl->callbacks[x].context); + strcpy(cb[x].context, source->sasl.callbacks[x].context); } else { - sasl_secret_t *src = source->sasl->callbacks[x].context; + sasl_secret_t *src = source->sasl.callbacks[x].context; sasl_secret_t *n = libmemcached_malloc(clone, src->len + 1 + sizeof(*n)); if (n == NULL) { /* Failed to allocate memory, clean up previously allocated memory */ for (size_t y= 0; y < x; ++y) { - libmemcached_free(clone, clone->sasl->callbacks[y].context); + libmemcached_free(clone, clone->sasl.callbacks[y].context); } libmemcached_free(clone, cb); @@ -381,8 +368,8 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st } } - clone->sasl->callbacks= cb; - clone->sasl->is_allocated= true; + clone->sasl.callbacks= cb; + clone->sasl.is_allocated= true; return MEMCACHED_SUCCESS; } diff --git a/libmemcached/server.c b/libmemcached/server.c index 3e5e77a5..22bd6f54 100644 --- a/libmemcached/server.c +++ b/libmemcached/server.c @@ -32,9 +32,9 @@ static inline void _server_init(memcached_server_st *self, const memcached_st *r self->state.is_dead= false; WATCHPOINT_SET(self->io_wait_count.read= 0); WATCHPOINT_SET(self->io_wait_count.write= 0); - self->major_version= 0; - self->micro_version= 0; - self->minor_version= 0; + self->major_version= UINT8_MAX; + self->micro_version= UINT8_MAX; + self->minor_version= UINT8_MAX; self->type= type; self->read_ptr= self->read_buffer; self->cached_server_error= NULL; diff --git a/libmemcached/server.h b/libmemcached/server.h index 2206c7b8..4248e143 100644 --- a/libmemcached/server.h +++ b/libmemcached/server.h @@ -36,9 +36,9 @@ struct memcached_server_st { uint32_t read; uint32_t write; } io_wait_count; - uint8_t major_version; - uint8_t micro_version; - uint8_t minor_version; + uint8_t major_version; // Default definition of UINT8_MAX means that it has not been set. + uint8_t micro_version; // ditto + uint8_t minor_version; // ditto memcached_connection_t type; char *read_ptr; char *cached_server_error; diff --git a/libmemcached/server_list.c b/libmemcached/server_list.c index 9287bc19..c20f8dbf 100644 --- a/libmemcached/server_list.c +++ b/libmemcached/server_list.c @@ -37,6 +37,7 @@ memcached_server_list_append_with_weight(memcached_server_list_st ptr, new_host_list= (memcached_server_write_instance_st)realloc(ptr, sizeof(memcached_server_st) * count); if (!new_host_list) { + ptr->cached_errno= errno; *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; return NULL; } diff --git a/libmemcached/stats.c b/libmemcached/stats.c index 731c1cc0..ab005f49 100644 --- a/libmemcached/stats.c +++ b/libmemcached/stats.c @@ -227,6 +227,12 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_ return NULL; } + if (length >= SMALL_STRING_LEN || length < 0) + { + *error= MEMCACHED_FAILURE; + return NULL; + } + ret= libmemcached_malloc(ptr, (size_t) (length + 1)); memcpy(ret, buffer, (size_t) length); ret[length]= '\0'; @@ -258,11 +264,11 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, request.message.header.request.keylen= htons((uint16_t)len); request.message.header.request.bodylen= htonl((uint32_t) len); - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= sizeof(request.bytes), .buffer= request.bytes }, { .length= len, .buffer= args } - }; + }; if (memcached_vdo(instance, vector, 2, true) != MEMCACHED_SUCCESS) { @@ -302,7 +308,7 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, WATCHPOINT_ASSERT(0); } } - + if (check && check->func) { size_t key_length= strlen(buffer); @@ -329,7 +335,7 @@ static memcached_return_t ascii_stats_fetch(memcached_stat_st *memc_stat, { memcached_return_t rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - size_t send_length; + int send_length; if (args) send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, @@ -338,10 +344,10 @@ static memcached_return_t ascii_stats_fetch(memcached_stat_st *memc_stat, send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "stats\r\n"); - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) return MEMCACHED_WRITE_FAILURE; - rc= memcached_do(instance, buffer, send_length, true); + rc= memcached_do(instance, buffer, (size_t)send_length, true); if (rc != MEMCACHED_SUCCESS) goto error; diff --git a/libmemcached/storage.c b/libmemcached/storage.c index dce5fec3..deb4aed4 100644 --- a/libmemcached/storage.c +++ b/libmemcached/storage.c @@ -104,15 +104,24 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, if (cas) { - write_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%s %.*s%.*s %u %llu %zu %llu%s\r\n", - storage_op_string(verb), - (int)ptr->prefix_key_length, - ptr->prefix_key, - (int)key_length, key, flags, - (unsigned long long)expiration, value_length, - (unsigned long long)cas, - (ptr->flags.no_reply) ? " noreply" : ""); + int check_length; + check_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + "%s %.*s%.*s %u %llu %lu %llu%s\r\n", + storage_op_string(verb), + (int)ptr->prefix_key_length, + ptr->prefix_key, + (int)key_length, key, flags, + (unsigned long long)expiration, (unsigned long)value_length, + (unsigned long long)cas, + (ptr->flags.no_reply) ? " noreply" : ""); + if (check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || check_length < 0) + { + rc= MEMCACHED_WRITE_FAILURE; + memcached_io_reset(instance); + + return rc; + } + write_length= check_length; } else { @@ -133,11 +142,22 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, buffer_ptr++; write_length= (size_t)(buffer_ptr - buffer); - write_length+= (size_t) snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE, - "%u %llu %zu%s\r\n", - flags, - (unsigned long long)expiration, value_length, - ptr->flags.no_reply ? " noreply" : ""); + int check_length; + check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer), + "%u %llu %lu%s\r\n", + flags, + (unsigned long long)expiration, (unsigned long)value_length, + ptr->flags.no_reply ? " noreply" : ""); + if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer) || check_length < 0) + { + rc= MEMCACHED_WRITE_FAILURE; + memcached_io_reset(instance); + + return rc; + } + + write_length+= (size_t)check_length; + WATCHPOINT_ASSERT(write_length < MEMCACHED_DEFAULT_COMMAND_SIZE); } if (ptr->flags.use_udp && ptr->flags.buffer_requests) @@ -155,12 +175,12 @@ static inline memcached_return_t memcached_send(memcached_st *ptr, } else { - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= write_length, .buffer= buffer }, { .length= value_length, .buffer= value }, { .length= 2, .buffer= "\r\n" } - }; + }; if (ptr->flags.buffer_requests && verb == SET_OP) { @@ -492,13 +512,13 @@ static memcached_return_t memcached_send_binary(memcached_st *ptr, } } - struct __write_vector_st vector[]= + struct libmemcached_io_vector_st vector[]= { { .length= send_length, .buffer= request.bytes }, { .length= ptr->prefix_key_length, .buffer= ptr->prefix_key }, { .length= key_length, .buffer= key }, { .length= value_length, .buffer= value } - }; + }; /* write the header */ memcached_return_t rc; diff --git a/libmemcached/string.c b/libmemcached/string.c index f708f8d4..34597067 100644 --- a/libmemcached/string.c +++ b/libmemcached/string.c @@ -32,7 +32,9 @@ inline static memcached_return_t _string_check(memcached_string_st *string, size new_value= libmemcached_realloc(string->root, string->string, new_size); if (new_value == NULL) + { return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + } string->string= new_value; string->end= string->string + current_offset; @@ -80,7 +82,12 @@ memcached_string_st *memcached_string_create(const memcached_st *memc, memcached rc= _string_check(self, initial_size); if (rc != MEMCACHED_SUCCESS) { + if (rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE) + { + ((memcached_st *)memc)->cached_errno= errno; + } libmemcached_free(memc, self); + return NULL; } @@ -99,7 +106,9 @@ memcached_return_t memcached_string_append_character(memcached_string_st *string rc= _string_check(string, 1); if (rc != MEMCACHED_SUCCESS) + { return rc; + } *string->end= character; string->end++; @@ -115,7 +124,9 @@ memcached_return_t memcached_string_append(memcached_string_st *string, rc= _string_check(string, length); if (rc != MEMCACHED_SUCCESS) + { return rc; + } WATCHPOINT_ASSERT(length <= string->current_size); WATCHPOINT_ASSERT(string->string); diff --git a/libmemcached/util/version.c b/libmemcached/util/version.c index 7c936c71..a4d5b2d4 100644 --- a/libmemcached/util/version.c +++ b/libmemcached/util/version.c @@ -29,7 +29,8 @@ static memcached_return_t check_server_version(const memcached_st *ptr __attribu /* Do Nothing */ struct local_context *check= (struct local_context *)context; - if (instance->major_version >= check->major_version && + if (instance->major_version != UINT8_MAX && + instance->major_version >= check->major_version && instance->minor_version >= check->minor_version && instance->micro_version >= check->micro_version ) { @@ -47,10 +48,12 @@ bool libmemcached_util_version_check(memcached_st *memc, uint8_t micro_version) { memcached_server_fn callbacks[1]; - memcached_version(memc); + memcached_return_t rc= memcached_version(memc); + + if (rc != MEMCACHED_SUCCESS) + return false; struct local_context check= { .major_version= major_version, .minor_version= minor_version, .micro_version= micro_version, .truth= true }; - memcached_version(memc); callbacks[0]= check_server_version; memcached_server_cursor(memc, callbacks, (void *)&check, 1); diff --git a/libmemcached/verbosity.c b/libmemcached/verbosity.c index fba00144..d0903514 100644 --- a/libmemcached/verbosity.c +++ b/libmemcached/verbosity.c @@ -41,17 +41,17 @@ static memcached_return_t _set_verbosity(const memcached_st *ptr __attribute__(( memcached_return_t memcached_verbosity(memcached_st *ptr, uint32_t verbosity) { - size_t send_length; + int send_length; memcached_server_fn callbacks[1]; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, + send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "verbosity %u\r\n", verbosity); - unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) return MEMCACHED_WRITE_FAILURE; - struct context_st context = { .length= send_length, .buffer= buffer }; + struct context_st context = { .length= (size_t)send_length, .buffer= buffer }; callbacks[0]= _set_verbosity; diff --git a/libmemcached/version.c b/libmemcached/version.c index 54545cb9..cb8fa0e0 100644 --- a/libmemcached/version.c +++ b/libmemcached/version.c @@ -13,18 +13,13 @@ memcached_return_t memcached_version(memcached_st *ptr) if (ptr->flags.use_udp) return MEMCACHED_NOT_SUPPORTED; - bool was_blocking= ptr->flags.no_block; memcached_return_t rc; - ptr->flags.no_block= false; - if (ptr->flags.binary_protocol) rc= memcached_version_binary(ptr); else rc= memcached_version_textual(ptr); - ptr->flags.no_block= was_blocking; - return rc; } @@ -45,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; } @@ -55,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; } @@ -64,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; @@ -91,6 +113,9 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) 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) { @@ -105,6 +130,9 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr) 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; @@ -120,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; + } + } } diff --git a/libmemcached/watchpoint.h b/libmemcached/watchpoint.h index 31d0a12b..341f4fe2 100644 --- a/libmemcached/watchpoint.h +++ b/libmemcached/watchpoint.h @@ -16,7 +16,7 @@ #if defined(DEBUG) #ifdef TARGET_OS_LINUX -static inline void __stack_dump(void) +static inline void libmemcached_stack_dump(void) { void *array[10]; int size; @@ -35,12 +35,21 @@ static inline void __stack_dump(void) fflush(stderr); } +#elif defined(__sun) +#include + +static inline void libmemcached_stack_dump(void) +{ + fflush(stderr); + printstack(fileno(stderr)); +} + #else -static inline void __stack_dump(void) +static inline void libmemcached_stack_dump(void) { } -#endif // __stack_dump() +#endif // libmemcached_stack_dump() #include @@ -49,13 +58,13 @@ static inline void __stack_dump(void) #define WATCHPOINT_IFERROR(A) do { if(A != MEMCACHED_SUCCESS)fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); } while (0) #define WATCHPOINT_STRING(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__,A);fflush(stdout); } while (0) #define WATCHPOINT_STRING_LENGTH(A,B) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %.*s\n", __FILE__, __LINE__,__func__,(int)B,A);fflush(stdout); } while (0) -#define WATCHPOINT_NUMBER(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %zu\n", __FILE__, __LINE__,__func__,(size_t)(A));fflush(stdout); } while (0) -#define WATCHPOINT_LABELED_NUMBER(A,B) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s:%zu\n", __FILE__, __LINE__,__func__,(A),(size_t)(B));fflush(stdout); } while (0) -#define WATCHPOINT_IF_LABELED_NUMBER(A,B,C) do { if(A) {fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s:%zu\n", __FILE__, __LINE__,__func__,(B),(size_t)(C));fflush(stdout);} } while (0) +#define WATCHPOINT_NUMBER(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %lu\n", __FILE__, __LINE__,__func__,(unsigned long)(A));fflush(stdout); } while (0) +#define WATCHPOINT_LABELED_NUMBER(A,B) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s:%lu\n", __FILE__, __LINE__,__func__,(A),(unsigned long)(B));fflush(stdout); } while (0) +#define WATCHPOINT_IF_LABELED_NUMBER(A,B,C) do { if(A) {fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s:%lu\n", __FILE__, __LINE__,__func__,(B),(unsigned long)(C));fflush(stdout);} } while (0) #define WATCHPOINT_ERRNO(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__, strerror(A));fflush(stdout); } while (0) -#define WATCHPOINT_ASSERT_PRINT(A,B,C) do { if(!(A)){fprintf(stderr, "\nWATCHPOINT ASSERT %s:%d (%s) ", __FILE__, __LINE__,__func__);fprintf(stderr, (B),(C));fprintf(stderr,"\n");fflush(stdout); __stack_dump(); } assert((A)); } while (0) -#define WATCHPOINT_ASSERT(A) do { if (! (A)) {__stack_dump();} assert((A)); } while (0) -#define WATCHPOINT_ASSERT_INITIALIZED(A) do { if (! (A)) { __stack_dump(); } assert(memcached_is_initialized((A))); } while (0); +#define WATCHPOINT_ASSERT_PRINT(A,B,C) do { if(!(A)){fprintf(stderr, "\nWATCHPOINT ASSERT %s:%d (%s) ", __FILE__, __LINE__,__func__);fprintf(stderr, (B),(C));fprintf(stderr,"\n");fflush(stdout); libmemcached_stack_dump(); } assert((A)); } while (0) +#define WATCHPOINT_ASSERT(A) do { if (! (A)) {libmemcached_stack_dump();} assert((A)); } while (0) +#define WATCHPOINT_ASSERT_INITIALIZED(A) do { if (! (A)) { libmemcached_stack_dump(); } assert(memcached_is_initialized((A))); } while (0); #define WATCHPOINT_SET(A) do { A; } while(0); #else diff --git a/m4/byteorder.m4 b/m4/byteorder.m4 index 4692bbd2..32431798 100644 --- a/m4/byteorder.m4 +++ b/m4/byteorder.m4 @@ -1,25 +1,19 @@ AC_DEFUN([DETECT_BYTEORDER], [ AC_REQUIRE([AC_C_BIGENDIAN]) - AC_CACHE_CHECK([for htonll],[av_cv_have_htonll],[ - - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[ + AC_CACHE_CHECK([for htonll], [ac_cv_have_htonll], + [AC_TRY_LINK([ #include #include #include - ]],[[ - return htonll(0); - ]]) - ], [ - ac_cv_have_htonll=yes - ],[ - ac_cv_have_htonll=no - ])]) - + ], [ +return htonll(0); + ], + [ ac_cv_have_htonll=yes ], + [ ac_cv_have_htonll=no ]) + ]) AS_IF([test "x$ac_cv_have_htonll" = "xyes"],[ - AC_DEFINE([HAVE_HTONLL], [1], [Have ntohll])]) + AC_DEFINE([HAVE_HTONLL], [1], [Have ntohll])]) AM_CONDITIONAL([BUILD_BYTEORDER],[test "x$ac_cv_have_htonll" = "xno"]) ]) - diff --git a/m4/eagain.m4 b/m4/eagain.m4 new file mode 100644 index 00000000..3ba8c23f --- /dev/null +++ b/m4/eagain.m4 @@ -0,0 +1,28 @@ +# +# Some platforms define EWOULDBLOCK == EAGAIN, causing our switch for error +# codes to be illegal (POSIX.1-2001 allows both return codes from recv, so +# we need to test both if they differ...) +# +AC_DEFUN([DETECT_EAGAIN], +[ + AC_CACHE_CHECK([if EWOULDBLOCK == EAGAIN],[av_cv_eagain_ewouldblock], + [AC_TRY_COMPILE([ +#include + ], [ +int error = EAGAIN; +switch (error) +{ + case EAGAIN: + case EWOULDBLOCK: + error = 1; + break; + default: + error = 0; +} + ], + [ av_cv_eagain_ewouldblock=no ], + [ av_cv_eagain_ewouldblock=yes ]) + ]) + AS_IF([test "x$ac_cv_eagain_ewouldblock" = "xyes"],[ + AC_DEFINE([USE_EAGAIN], [1], [Define to true if you need to test for eagain])]) +]) diff --git a/m4/hsieh.m4 b/m4/hsieh.m4 index b057bfdc..c4f3df04 100644 --- a/m4/hsieh.m4 +++ b/m4/hsieh.m4 @@ -4,7 +4,7 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([ENABLE_HSIEH_HASH], [AC_ARG_ENABLE([hsieh_hash], [AS_HELP_STRING([--enable-hsieh_hash], - [build with support for hsieh hashing. @<:default=off@:>@])], + [build with support for hsieh hashing. @<:@default=off@:>@])], [ac_cv_enable_hsieh_hash=yes], [ac_cv_enable_hsieh_hash=no]) diff --git a/m4/iconv.m4 b/m4/iconv.m4 index 66bc76f4..e2041b9b 100644 --- a/m4/iconv.m4 +++ b/m4/iconv.m4 @@ -1,5 +1,5 @@ -# iconv.m4 serial AM6 (gettext-0.17) -dnl Copyright (C) 2000-2002, 2007 Free Software Foundation, Inc. +# iconv.m4 serial 11 (gettext-0.18.1) +dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -34,7 +34,7 @@ AC_DEFUN([AM_ICONV_LINK], am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - AC_CACHE_CHECK([for iconv], am_cv_func_iconv, [ + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include @@ -42,7 +42,7 @@ AC_DEFUN([AM_ICONV_LINK], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], - am_cv_func_iconv=yes) + [am_cv_func_iconv=yes]) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" @@ -51,14 +51,14 @@ AC_DEFUN([AM_ICONV_LINK], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], - am_cv_lib_iconv=yes - am_cv_func_iconv=yes) + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then - AC_CACHE_CHECK([for working iconv], am_cv_func_iconv_works, [ - dnl This tests against bugs in AIX 5.1 and HP-UX 11.11. + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10. am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" @@ -87,6 +87,25 @@ int main () return 1; } } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\263"; + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { @@ -134,7 +153,7 @@ int main () am_func_iconv=no am_cv_lib_iconv=no fi if test "$am_func_iconv" = yes; then - AC_DEFINE(HAVE_ICONV, 1, + AC_DEFINE([HAVE_ICONV], [1], [Define if you have the iconv() function and it works.]) fi if test "$am_cv_lib_iconv" = yes; then @@ -147,16 +166,31 @@ int main () LIBICONV= LTLIBICONV= fi - AC_SUBST(LIBICONV) - AC_SUBST(LTLIBICONV) + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) ]) -AC_DEFUN([AM_ICONV], +dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to +dnl avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +dnl This is tricky because of the way 'aclocal' is implemented: +dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. +dnl Otherwise aclocal's initial scan pass would miss the macro definition. +dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. +dnl Otherwise aclocal would emit many "Use of uninitialized value $1" +dnl warnings. +m4_define([gl_iconv_AC_DEFUN], + m4_version_prereq([2.64], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [[AC_DEFUN( + [$1], [$2])]])) +gl_iconv_AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_CACHE_VAL([am_cv_proto_iconv], [ AC_TRY_COMPILE([ #include #include @@ -169,12 +203,12 @@ size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, si #else size_t iconv(); #endif -], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") +], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([$]{ac_t:- - }[$]am_cv_proto_iconv) - AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], [Define as const if the declaration of iconv() needs const.]) fi ]) diff --git a/m4/murmur.m4 b/m4/murmur.m4 new file mode 100644 index 00000000..ecdcf3a5 --- /dev/null +++ b/m4/murmur.m4 @@ -0,0 +1,18 @@ +dnl --------------------------------------------------------------------------- +dnl Macro: ENABLE_MURMUR_HASH +dnl --------------------------------------------------------------------------- +AC_DEFUN([ENABLE_MURMUR_HASH], + [AC_ARG_ENABLE([murmur_hash], + [AS_HELP_STRING([--disable-murmur_hash], + [build with support for murmur hashing. @<:@default=on@:>@])], + [ac_cv_enable_murmur_hash=no], + [ac_cv_enable_murmur_hash=yes]) + + AS_IF([test "$ac_cv_enable_murmur_hash" = "yes"], + [AC_DEFINE([HAVE_MURMUR_HASH], [1], [Enables murmur hashing support])]) + + AM_CONDITIONAL([INCLUDE_MURMUR_SRC], [test "$ac_cv_enable_murmur_hash" = "yes"]) +]) +dnl --------------------------------------------------------------------------- +dnl End Macro: ENABLE_MURMUR_HASH +dnl --------------------------------------------------------------------------- diff --git a/m4/pandora_64bit.m4 b/m4/pandora_64bit.m4 index ed123d2b..e026fd92 100644 --- a/m4/pandora_64bit.m4 +++ b/m4/pandora_64bit.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_bison.m4 b/m4/pandora_bison.m4 new file mode 100644 index 00000000..c95896c7 --- /dev/null +++ b/m4/pandora_bison.m4 @@ -0,0 +1,33 @@ +dnl Copyright (C) 2010 Monty Taylor +dnl Copyright (C) 2010 Hartmut Holzgraefe +dnl This file is free software; Monty Taylor and Hartmut Holzgraefe +dnl give unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_BISON],[ + + dnl -------------------------------------------------------------------- + dnl Check for bison + dnl -------------------------------------------------------------------- + + AC_CHECK_PROGS([YACC], ['bison -y'], [:]) + AS_IF([test "x$YACC" = "x:"],[ + pandora_have_bison=no + YACC='if test -f "$@"; then echo "WARNING: no proper bison binary found, ignoring changes to $<"; exit 0; else echo "ERROR: no proper bison binary found"; exit 1; fi;' + ],[ + pandora_have_bison=yes + ]) + + AM_CONDITIONAL(HAVE_BISON, [test "x${pandora_have_bison}" = "xyes"]) +]) + +AC_DEFUN([PANDORA_HAVE_BISON],[ + AC_REQUIRE([_PANDORA_SEARCH_BISON]) +]) + +AC_DEFUN([PANDORA_REQUIRE_BISON],[ + AC_REQUIRE([PANDORA_HAVE_BISON]) + AS_IF([test "x${pandora_have_bison}" = "xno" -a "$pandora_building_from_bzr" = "yes"], + AC_MSG_ERROR(["bison is required for ${PACKAGE} to build from a bzr branch"]) + ) +]) diff --git a/m4/pandora_canonical.m4 b/m4/pandora_canonical.m4 index 8443bf80..002f2fd3 100644 --- a/m4/pandora_canonical.m4 +++ b/m4/pandora_canonical.m4 @@ -1,10 +1,10 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Which version of the canonical setup we're using -AC_DEFUN([PANDORA_CANONICAL_VERSION],[0.134]) +AC_DEFUN([PANDORA_CANONICAL_VERSION],[0.171]) AC_DEFUN([PANDORA_FORCE_DEPEND_TRACKING],[ AC_ARG_ENABLE([fat-binaries], @@ -23,6 +23,12 @@ AC_DEFUN([PANDORA_FORCE_DEPEND_TRACKING],[ ]) ]) +AC_DEFUN([PANDORA_BLOCK_BAD_OPTIONS],[ + AS_IF([test "x${prefix}" = "x"],[ + AC_MSG_ERROR([--prefix requires an argument]) + ]) +]) + dnl The standard setup for how we build Pandora projects AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AC_REQUIRE([PANDORA_FORCE_DEPEND_TRACKING]) @@ -32,6 +38,7 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ m4_define([PCT_REQUIRE_CXX],[no]) m4_define([PCT_FORCE_GCC42],[no]) m4_define([PCT_DONT_SUPPRESS_INCLUDE],[no]) + m4_define([PCT_NO_VC_CHANGELOG],[no]) m4_define([PCT_VERSION_FROM_VC],[no]) m4_define([PCT_USE_VISIBILITY],[yes]) m4_foreach([pct_arg],[$*],[ @@ -52,6 +59,10 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ m4_undefine([PCT_DONT_SUPPRESS_INCLUDE]) m4_define([PCT_DONT_SUPPRESS_INCLUDE],[yes]) ], + [no-vc-changelog], [ + m4_undefine([PCT_NO_VC_CHANGELOG]) + m4_define([PCT_NO_VC_CHANGELOG],[yes]) + ], [version-from-vc], [ m4_undefine([PCT_VERSION_FROM_VC]) m4_define([PCT_VERSION_FROM_VC],[yes]) @@ -66,6 +77,8 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AC_CONFIG_HEADERS([config.h]) ]) + PANDORA_BLOCK_BAD_OPTIONS + # We need to prevent canonical target # from injecting -O2 into CFLAGS - but we won't modify anything if we have # set CFLAGS on the command line, since that should take ultimate precedence @@ -77,15 +90,17 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AC_CANONICAL_TARGET m4_if(PCT_DONT_SUPRESS_INCLUDE,yes,[ - AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability subdir-objects foreign) + AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability subdir-objects foreign tar-ustar) ],[ - AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability nostdinc subdir-objects foreign) + AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability nostdinc subdir-objects foreign tar-ustar) ]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) m4_if(m4_substr(m4_esyscmd(test -d gnulib && echo 0),0,1),0,[ gl_EARLY + ],[ + PANDORA_EXTENSIONS ]) AC_REQUIRE([AC_PROG_CC]) @@ -94,10 +109,27 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ ]) AC_REQUIRE([PANDORA_64BIT]) + m4_if(PCT_NO_VC_CHANGELOG,yes,[ + vc_changelog=no + ],[ + vc_changelog=yes + ]) m4_if(PCT_VERSION_FROM_VC,yes,[ PANDORA_VC_VERSION ],[ PANDORA_TEST_VC_DIR + + changequote(<<, >>)dnl + PANDORA_RELEASE_ID=`echo $VERSION | sed 's/[^0-9]//g'` + changequote([, ])dnl + + PANDORA_RELEASE_COMMENT="" + AC_DEFINE_UNQUOTED([PANDORA_RELEASE_VERSION],["$VERSION"], + [Version of the software]) + + AC_SUBST(PANDORA_RELEASE_COMMENT) + AC_SUBST(PANDORA_RELEASE_VERSION) + AC_SUBST(PANDORA_RELEASE_ID) ]) PANDORA_VERSION @@ -121,8 +153,9 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AS_IF([test "$ac_cv_cxx_stdcxx_98" = "no"],[ AC_MSG_ERROR([No working C++ Compiler has been found. ${PACKAGE} requires a C++ compiler that can handle C++98]) ]) - ]) + PANDORA_CXX_CSTDINT + PANDORA_CXX_CINTTYPES m4_if(m4_substr(m4_esyscmd(test -d gnulib && echo 0),0,1),0,[ gl_INIT @@ -144,6 +177,8 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AC_SYS_LARGEFILE PANDORA_CLOCK_GETTIME + AC_CHECK_HEADERS(sys/socket.h) + # off_t is not a builtin type AC_CHECK_SIZEOF(off_t, 4) AS_IF([test "$ac_cv_sizeof_off_t" -eq 0],[ @@ -176,6 +211,25 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AC_DEFINE([TIME_T_UNSIGNED], 1, [Define to 1 if time_t is unsigned]) ]) + AC_CACHE_CHECK([if system defines RUSAGE_THREAD], [ac_cv_rusage_thread],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include +#include + ]],[[ + int x= RUSAGE_THREAD; + ]]) + ],[ + ac_cv_rusage_thread=yes + ],[ + ac_cv_rusage_thread=no + ]) + ]) + AS_IF([test "$ac_cv_rusage_thread" = "no"],[ + AC_DEFINE([RUSAGE_THREAD], [RUSAGE_SELF], + [Define if system doesn't define]) + ]) + AC_CHECK_LIBM dnl Bug on FreeBSD - LIBM check doesn't set the damn variable AC_SUBST([LIBM]) @@ -201,11 +255,9 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ PANDORA_HAVE_GCC_ATOMICS m4_if(PCT_USE_VISIBILITY,[yes],[ - dnl We need to inject error into the cflags to test if visibility works or not - save_CFLAGS="${CFLAGS}" - CFLAGS="${CFLAGS} -Werror" - PANDORA_VISIBILITY - CFLAGS="${save_CFLAGS}" + PANDORA_ENABLE_VISIBILITY + ],[ + PANDORA_CHECK_VISIBILITY ]) PANDORA_HEADER_ASSERT @@ -220,10 +272,37 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ AC_CHECK_PROGS([DOXYGEN], [doxygen]) AC_CHECK_PROGS([PERL], [perl]) AC_CHECK_PROGS([DPKG_GENSYMBOLS], [dpkg-gensymbols], [:]) + AC_CHECK_PROGS([LCOV], [lcov], [echo lcov not found]) + AC_CHECK_PROGS([LCOV_GENHTML], [genhtml], [echo genhtml not found]) + + AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build], [:]) + AS_IF([test "x${SPHINXBUILD}" != "x:"],[ + AC_CACHE_CHECK([if sphinx is new enough],[ac_cv_recent_sphinx],[ + + ${SPHINXBUILD} -Q -C -b man -d conftest.d . . >/dev/null 2>&1 + AS_IF([test $? -eq 0],[ac_cv_recent_sphinx=yes], + [ac_cv_recent_sphinx=no]) + rm -rf conftest.d + ]) + ]) AM_CONDITIONAL(HAVE_DPKG_GENSYMBOLS,[test "x${DPKG_GENSYMBOLS}" != "x:"]) - - PANDORA_WITH_GETTEXT + AM_CONDITIONAL(HAVE_SPHINX,[test "x${SPHINXBUILD}" != "x:"]) + AM_CONDITIONAL(HAVE_RECENT_SPHINX,[test "x${ac_cv_recent_sphinx}" = "xyes"]) + + m4_if(m4_substr(m4_esyscmd(test -d po && echo 0),0,1),0, [ + AM_PO_SUBDIRS + IT_PROG_INTLTOOL([0.35],[no-xml]) + + GETTEXT_PACKAGE=$PACKAGE + AC_CHECK_LIB(intl, libintl_gettext) + AC_SUBST([GETTEXT_PACKAGE]) + AS_IF([test "x${USE_NLS}" = "xyes" -a "x${pandora_have_intltool}" = "xyes"], + [AC_DEFINE([ENABLE_NLS],[1],[Turn on language support]) + AC_CONFIG_FILES([po/Makefile.in]) + ]) + ]) + AM_CONDITIONAL(BUILD_PO,[test "x${USE_NLS}" = "xyes" -a "x${pandora_have_intltool}" = "xyes"]) AS_IF([test "x${gl_LIBOBJS}" != "x"],[ AS_IF([test "$GCC" = "yes"],[ @@ -240,6 +319,91 @@ AC_DEFUN([PANDORA_CANONICAL_TARGET],[ PANDORA_USE_PIPE + AH_TOP([ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +/* _SYS_FEATURE_TESTS_H is Solaris, _FEATURES_H is GCC */ +#if defined( _SYS_FEATURE_TESTS_H) || defined(_FEATURES_H) +#error "You should include config.h as your first include file" +#endif + +]) + mkdir -p config + cat > config/top.h.stamp </dev/null 2>&1 || mv config/top.h.stamp config/top.h + rm -f config/top.h.stamp + + AH_BOTTOM([ +#if defined(__cplusplus) +# include CSTDINT_H +# include CINTTYPES_H +#else +# include +# include +#endif + +#if !defined(HAVE_ULONG) && !defined(__USE_MISC) +# define HAVE_ULONG 1 +typedef unsigned long int ulong; +#endif + +/* To hide the platform differences between MS Windows and Unix, I am + * going to use the Microsoft way and #define the Microsoft-specific + * functions to the unix way. Microsoft use a separate subsystem for sockets, + * but Unix normally just use a filedescriptor on the same functions. It is + * a lot easier to map back to the unix way with macros than going the other + * way without side effect ;-) + */ +#ifdef TARGET_OS_WINDOWS +#define random() rand() +#define srandom(a) srand(a) +#define get_socket_errno() WSAGetLastError() +#else +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define closesocket(a) close(a) +#define get_socket_errno() errno +#endif + +#if defined(__cplusplus) +# if defined(DEBUG) +# include +# include +# endif +template +inline To implicit_cast(From const &f) { + return f; +} +template // use like this: down_cast(foo); +inline To down_cast(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + implicit_cast(0); + } + +#if defined(DEBUG) + assert(f == NULL || dynamic_cast(f) != NULL); // RTTI: debug mode only! +#endif + return static_cast(f); +} +#endif /* defined(__cplusplus) */ + +#endif /* __CONFIG_H__ */ + ]) AM_CFLAGS="${AM_CFLAGS} ${CC_WARNINGS} ${CC_PROFILING} ${CC_COVERAGE}" AM_CXXFLAGS="${AM_CXXFLAGS} ${CXX_WARNINGS} ${CC_PROFILING} ${CC_COVERAGE}" diff --git a/m4/pandora_check_compiler_version.m4 b/m4/pandora_check_compiler_version.m4 index ab7c6718..f39174ed 100644 --- a/m4/pandora_check_compiler_version.m4 +++ b/m4/pandora_check_compiler_version.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_check_cxx_standard.m4 b/m4/pandora_check_cxx_standard.m4 index 6a88a31f..a5f0cca3 100644 --- a/m4/pandora_check_cxx_standard.m4 +++ b/m4/pandora_check_cxx_standard.m4 @@ -1,10 +1,10 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([PANDORA_CHECK_CXX_STANDARD],[ - AC_REQUIRE([AC_CXX_COMPILE_STDCXX_0X]) + dnl AC_REQUIRE([AC_CXX_COMPILE_STDCXX_0X]) AS_IF([test "$GCC" = "yes"], [AS_IF([test "$ac_cv_cxx_compile_cxx0x_native" = "yes"],[], [AS_IF([test "$ac_cv_cxx_compile_cxx0x_gxx" = "yes"], diff --git a/m4/pandora_compile_stdcxx_0x.m4 b/m4/pandora_compile_stdcxx_0x.m4 new file mode 100644 index 00000000..4445779a --- /dev/null +++ b/m4/pandora_compile_stdcxx_0x.m4 @@ -0,0 +1,103 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ac_cxx_compile_stdcxx_0x.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_CXX_COMPILE_STDCXX_0X +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++0x +# standard. +# +# LICENSE +# +# Copyright (C) 2008 Benjamin Kosnik +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AC_CXX_COMPILE_STDCXX_0X], [ + AC_CACHE_CHECK(if g++ supports C++0x features without additional flags, + ac_cv_cxx_compile_cxx0x_native, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([ + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check check_type; + check_type c; + check_type&& cr = c;],, + ac_cv_cxx_compile_cxx0x_native=yes, ac_cv_cxx_compile_cxx0x_native=no) + AC_LANG_RESTORE + ]) + + AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x, + ac_cv_cxx_compile_cxx0x_cxx, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -std=c++0x" + AC_TRY_COMPILE([ + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check check_type; + check_type c; + check_type&& cr = c;],, + ac_cv_cxx_compile_cxx0x_cxx=yes, ac_cv_cxx_compile_cxx0x_cxx=no) + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE + ]) + + AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x, + ac_cv_cxx_compile_cxx0x_gxx, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -std=gnu++0x" + AC_TRY_COMPILE([ + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check check_type; + check_type c; + check_type&& cr = c;],, + ac_cv_cxx_compile_cxx0x_gxx=yes, ac_cv_cxx_compile_cxx0x_gxx=no) + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE + ]) + + if test "$ac_cv_cxx_compile_cxx0x_native" = yes || + test "$ac_cv_cxx_compile_cxx0x_cxx" = yes || + test "$ac_cv_cxx_compile_cxx0x_gxx" = yes; then + AC_DEFINE(HAVE_STDCXX_0X,,[Define if g++ supports C++0x features. ]) + fi +]) diff --git a/m4/pandora_cxx_demangle.m4 b/m4/pandora_cxx_demangle.m4 index d2d9ddd5..5ae66877 100644 --- a/m4/pandora_cxx_demangle.m4 +++ b/m4/pandora_cxx_demangle.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_drizzle_build.m4 b/m4/pandora_drizzle_build.m4 index 2c7a321d..54f946f1 100644 --- a/m4/pandora_drizzle_build.m4 +++ b/m4/pandora_drizzle_build.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -9,11 +9,6 @@ dnl are set. AC_DEFUN([PANDORA_DRIZZLE_BUILD],[ - PANDORA_HAVE_CXX_UNORDERED - - PANDORA_CXX_CSTDINT - PANDORA_CXX_CINTTYPES - AC_STRUCT_TM AC_FUNC_ALLOCA @@ -38,7 +33,7 @@ AC_DEFUN([PANDORA_DRIZZLE_BUILD],[ AC_CHECK_HEADERS(sys/types.h sys/fpu.h fpu_control.h ieeefp.h) AC_CHECK_HEADERS(select.h sys/select.h) AC_CHECK_HEADERS(utime.h sys/utime.h ) - AC_CHECK_HEADERS(synch.h sys/mman.h sys/socket.h) + AC_CHECK_HEADERS(synch.h sys/mman.h) AC_CHECK_HEADERS(sched.h) AC_CHECK_HEADERS(sys/prctl.h) AC_CHECK_HEADERS(execinfo.h) @@ -68,45 +63,15 @@ AC_DEFUN([PANDORA_DRIZZLE_BUILD],[ ]]) AC_CHECK_TYPES([uint, ulong]) + PANDORA_REQUIRE_BISON + PANDORA_CXX_DEMANGLE PANDORA_REQUIRE_BOOST([1.38]) PANDORA_REQUIRE_BOOST_PROGRAM_OPTIONS + PANDORA_REQUIRE_BOOST_THREAD + PANDORA_REQUIRE_BOOST_REGEX + PANDORA_REQUIRE_BOOST_DATE_TIME + PANDORA_REQUIRE_BOOST_FILESYSTEM + PANDORA_REQUIRE_BOOST_IOSTREAMS - - AH_TOP([ -#ifndef __CONFIG_H__ -#define __CONFIG_H__ - -#include "config/top.h" -]) - mkdir -p config - cat > config/top.h.stamp </dev/null 2>&1 || mv config/top.h.stamp config/top.h - rm -f config/top.h.stamp - - - AH_BOTTOM([ -#if defined(__cplusplus) -# include CSTDINT_H -# include CINTTYPES_H -#else -# include -# include -#endif - -#if !defined(HAVE_ULONG) && !defined(__USE_MISC) -typedef unsigned long int ulong; -#endif - -#endif /* __CONFIG_H__ */ - ]) ]) diff --git a/m4/pandora_enable_dtrace.m4 b/m4/pandora_enable_dtrace.m4 index 627fd3d0..390efc57 100644 --- a/m4/pandora_enable_dtrace.m4 +++ b/m4/pandora_enable_dtrace.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -15,7 +15,9 @@ AC_DEFUN([PANDORA_ENABLE_DTRACE],[ AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[ AC_CHECK_PROGS([DTRACE], [dtrace]) - AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[ + AC_CHECK_HEADERS(sys/sdt.h) + + AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace" -a "x${ac_cv_header_sys_sdt_h}" = "xyes"],[ AC_CACHE_CHECK([if dtrace works],[ac_cv_dtrace_works],[ cat >conftest.d <<_ACEOF diff --git a/m4/pandora_ensure_gcc_version.m4 b/m4/pandora_ensure_gcc_version.m4 index 588fa442..9d2f65d3 100644 --- a/m4/pandora_ensure_gcc_version.m4 +++ b/m4/pandora_ensure_gcc_version.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_extensions.m4 b/m4/pandora_extensions.m4 index ee73b804..b2720eff 100644 --- a/m4/pandora_extensions.m4 +++ b/m4/pandora_extensions.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_fdatasync.m4 b/m4/pandora_fdatasync.m4 index 3a17c18d..e8bba25c 100644 --- a/m4/pandora_fdatasync.m4 +++ b/m4/pandora_fdatasync.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_flex.m4 b/m4/pandora_flex.m4 new file mode 100644 index 00000000..0fb2f81c --- /dev/null +++ b/m4/pandora_flex.m4 @@ -0,0 +1,33 @@ +dnl Copyright (C) 2010 Monty Taylor +dnl Copyright (C) 2010 Hartmut Holzgraefe +dnl This file is free software; Monty Taylor and Hartmut Holzgraefe +dnl give unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_FLEX],[ + + dnl -------------------------------------------------------------------- + dnl Check for flex + dnl -------------------------------------------------------------------- + + AC_CHECK_PROGS([LEX], ['flex'], [:]) + AS_IF([test "x$LEX" = "x:"],[ + pandora_have_flex=no + LEX='if test -f "$@"; then echo "WARNING: no proper flex binary found, ignoring changes to $<"; exit 0; else echo "ERROR: no proper flex binary found"; exit 1; fi;' + ],[ + pandora_have_flex=yes + ]) + + AM_CONDITIONAL(HAVE_FLEX, [test "x${pandora_have_flex}" = "xyes"]) +]) + +AC_DEFUN([PANDORA_HAVE_FLEX],[ + AC_REQUIRE([_PANDORA_SEARCH_FLEX]) +]) + +AC_DEFUN([PANDORA_REQUIRE_FLEX],[ + AC_REQUIRE([PANDORA_HAVE_FLEX]) + AS_IF([test "x${pandora_have_flex}" = "xno" -a "$pandora_building_from_bzr" = "yes"], + AC_MSG_ERROR(["flex is required for ${PACKAGE} to build from a bzr branch"]) + ) +]) diff --git a/m4/pandora_have_better_malloc.m4 b/m4/pandora_have_better_malloc.m4 index 6f46ee9a..c984cbaf 100644 --- a/m4/pandora_have_better_malloc.m4 +++ b/m4/pandora_have_better_malloc.m4 @@ -1,11 +1,9 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([PANDORA_HAVE_BETTER_MALLOC],[ - AC_REQUIRE([AC_FUNC_MALLOC]) - AC_REQUIRE([AC_FUNC_REALLOC]) AC_REQUIRE([AC_LIB_PREFIX]) AC_ARG_ENABLE([umem], diff --git a/m4/pandora_have_boost.m4 b/m4/pandora_have_boost.m4 index 67ee1b0b..2a571dbb 100644 --- a/m4/pandora_have_boost.m4 +++ b/m4/pandora_have_boost.m4 @@ -19,11 +19,10 @@ AC_DEFUN([_PANDORA_SEARCH_BOOST],[ AS_IF([test "x$ac_enable_boost" = "xyes"],[ dnl link against libc because we're just looking for headers here AC_LANG_PUSH(C++) - AC_LIB_HAVE_LINKFLAGS(c,,[ - #include - ],[ - boost::pool<> test_pool(1); - ]) + AC_LIB_HAVE_LINKFLAGS(c,, + [#include ], + [boost::pool<> test_pool(1);], + [system]) AC_LANG_POP() ],[ ac_cv_boost="no" @@ -55,7 +54,28 @@ AC_DEFUN([_PANDORA_SEARCH_BOOST],[ ac_cv_boost=no ]) ]) - + + AS_IF([test "x${ac_gcc_profile_mode}" = "xyes"],[ + AC_CACHE_CHECK([if boost is recent enough for GCC Profile Mode], + [pandora_cv_boost_profile],[ + pandora_need_boost_version=104300 + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + +#if BOOST_VERSION < ${pandora_need_boost_version} +# error boost too old! +#endif + ]],[[]]) + ],[ + pandora_cv_boost_profile=yes + ],[ + pandora_cv_boost_profile=no + ]) + ]) + AS_IF([test "x${pandora_cv_boost_profile}" = "xyes"],[ + AC_DEFINE([BOOST_DETAIL_NO_CONTAINER_FWD],[1],[Disable forward decl of stl in boost]) + ]) + ]) AM_CONDITIONAL(HAVE_BOOST, [test "x${ac_cv_boost}" = "xyes"]) diff --git a/m4/pandora_have_gcc_atomics.m4 b/m4/pandora_have_gcc_atomics.m4 index 47257d6a..a106895f 100644 --- a/m4/pandora_have_gcc_atomics.m4 +++ b/m4/pandora_have_gcc_atomics.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libavahi.m4 b/m4/pandora_have_libavahi.m4 index 72c274f7..b32432dc 100644 --- a/m4/pandora_have_libavahi.m4 +++ b/m4/pandora_have_libavahi.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libbdb.m4 b/m4/pandora_have_libbdb.m4 index 3e2d1446..443d3cc2 100644 --- a/m4/pandora_have_libbdb.m4 +++ b/m4/pandora_have_libbdb.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libboost_date_time.m4 b/m4/pandora_have_libboost_date_time.m4 new file mode 100644 index 00000000..71c3efe3 --- /dev/null +++ b/m4/pandora_have_libboost_date_time.m4 @@ -0,0 +1,46 @@ +dnl Copyright (C) 2010 Monty Taylor +dnl This file is free software; Monty Taylor +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_BOOST_DATE_TIME],[ + AC_REQUIRE([AC_LIB_PREFIX]) + AC_REQUIRE([ACX_PTHREAD]) + + dnl -------------------------------------------------------------------- + dnl Check for Boost.Date_Time + dnl -------------------------------------------------------------------- + + AC_LANG_PUSH(C++) + AC_LIB_HAVE_LINKFLAGS(boost_date_time-mt,,[ + #include + ],[ + boost::gregorian::date weekstart(2002,2,1); + ]) + AS_IF([test "x${ac_cv_libboost_date_time_mt}" = "xno"],[ + AC_LIB_HAVE_LINKFLAGS(boost_date_time,,[ + #include + ],[ + boost::gregorian::date weekstart(2002,2,1); + ]) + ]) + AC_LANG_POP() + + AM_CONDITIONAL(HAVE_BOOST_DATE_TIME, + [test "x${ac_cv_libboost_date_time}" = "xyes" -o "x${ac_cv_libboost_date_time_mt}" = "xyes"]) + BOOST_LIBS="${BOOST_LIBS} ${LTLIBBOOST_DATE_TIME_MT} ${LTLIBBOOST_DATE_TIME}" + AC_SUBST(BOOST_LIBS) +]) + +AC_DEFUN([PANDORA_HAVE_BOOST_DATE_TIME],[ + PANDORA_HAVE_BOOST($1) + _PANDORA_SEARCH_BOOST_DATE_TIME($1) +]) + +AC_DEFUN([PANDORA_REQUIRE_BOOST_DATE_TIME],[ + PANDORA_REQUIRE_BOOST($1) + _PANDORA_SEARCH_BOOST_DATE_TIME($1) + AS_IF([test "x${ac_cv_libboost_date_time}" = "xno" -a "x${ac_cv_libboost_date_time_mt}" = "xno"], + AC_MSG_ERROR([Boost.Date_Time is required for ${PACKAGE}])) +]) + diff --git a/m4/pandora_have_libboost_filesystem.m4 b/m4/pandora_have_libboost_filesystem.m4 new file mode 100644 index 00000000..6b9ecba5 --- /dev/null +++ b/m4/pandora_have_libboost_filesystem.m4 @@ -0,0 +1,45 @@ +dnl Copyright (C) 2010 Monty Taylor +dnl This file is free software; Monty Taylor +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_BOOST_FILESYSTEM],[ + AC_REQUIRE([AC_LIB_PREFIX]) + + dnl -------------------------------------------------------------------- + dnl Check for Boost.Filesystem + dnl -------------------------------------------------------------------- + + AC_LANG_PUSH(C++) + AC_LIB_HAVE_LINKFLAGS(boost_filesystem-mt,boost_system-mt,[ + #include + ],[ + boost::filesystem::path my_path("some_dir/file.txt"); + ]) + AS_IF([test "x${ac_cv_libboost_filesystem_mt}" = "xno"],[ + AC_LIB_HAVE_LINKFLAGS(boost_filesystem,boost_system,[ + #include + ],[ + boost::filesystem::path my_path("some_dir/file.txt"); + ]) + ]) + AC_LANG_POP() + + AM_CONDITIONAL(HAVE_BOOST_FILESYSTEM, + [test "x${ac_cv_libboost_filesystem}" = "xyes" -o "x${ac_cv_libboost_filesystem_mt}" = "xyes"]) + BOOST_LIBS="${BOOST_LIBS} ${LTLIBBOOST_FILESYSTEM_MT} ${LTLIBBOOST_FILESYSTEM}" + AC_SUBST(BOOST_LIBS) +]) + +AC_DEFUN([PANDORA_HAVE_BOOST_FILESYSTEM],[ + PANDORA_HAVE_BOOST($1) + _PANDORA_SEARCH_BOOST_FILESYSTEM($1) +]) + +AC_DEFUN([PANDORA_REQUIRE_BOOST_FILESYSTEM],[ + PANDORA_REQUIRE_BOOST($1) + _PANDORA_SEARCH_BOOST_FILESYSTEM($1) + AS_IF([test "x${ac_cv_libboost_filesystem}" = "xno" -a "x${ac_cv_libboost_filesystem_mt}" = "xno"], + AC_MSG_ERROR([Boost.Filesystem is required for ${PACKAGE}])) +]) + diff --git a/m4/pandora_have_libboost_iostreams.m4 b/m4/pandora_have_libboost_iostreams.m4 new file mode 100644 index 00000000..e9ac7b6e --- /dev/null +++ b/m4/pandora_have_libboost_iostreams.m4 @@ -0,0 +1,49 @@ +dnl Copyright (C) 2010 Andrew Hutchings +dnl This file is free software; Andrew Hutchings +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_BOOST_IOSTREAMS],[ + AC_REQUIRE([AC_LIB_PREFIX]) + + dnl -------------------------------------------------------------------- + dnl Check for Boost.Iostreams + dnl -------------------------------------------------------------------- + + AC_LANG_PUSH(C++) + AC_LIB_HAVE_LINKFLAGS(boost_iostreams-mt,,[ + #include + #include + ],[ + const char* input= "hello world"; + boost::iostreams::stream in(input, strlen(input)); + ]) + AS_IF([test "x${ac_cv_libboost_iostreams_mt}" = "xno"],[ + AC_LIB_HAVE_LINKFLAGS(boost_iostreams,,[ + #include + #include + ],[ + const char* input= "hello world"; + boost::iostreams::stream in(input, strlen(input)); + ]) + ]) + AC_LANG_POP() + + AM_CONDITIONAL(HAVE_BOOST_IOSTREAMS, + [test "x${ac_cv_libboost_iostreams}" = "xyes" -o "x${ac_cv_libboost_iostreams_mt}" = "xyes"]) + BOOST_LIBS="${BOOST_LIBS} ${LTLIBBOOST_IOSTREAMS_MT} ${LTLIBBOOST_IOSTREAMS}" + AC_SUBST(BOOST_LIBS) +]) + +AC_DEFUN([PANDORA_HAVE_BOOST_IOSTREAMS],[ + PANDORA_HAVE_BOOST($1) + _PANDORA_SEARCH_BOOST_IOSTREAMS($1) +]) + +AC_DEFUN([PANDORA_REQUIRE_BOOST_IOSTREAMS],[ + PANDORA_REQUIRE_BOOST($1) + _PANDORA_SEARCH_BOOST_IOSTREAMS($1) + AS_IF([test "x${ac_cv_libboost_iostreams}" = "xno" -a "x${ac_cv_libboost_iostreams_mt}" = "xno"], + AC_MSG_ERROR([Boost.Iostreams is required for ${PACKAGE}])) +]) + diff --git a/m4/pandora_have_libboost_regex.m4 b/m4/pandora_have_libboost_regex.m4 new file mode 100644 index 00000000..50a496ac --- /dev/null +++ b/m4/pandora_have_libboost_regex.m4 @@ -0,0 +1,54 @@ +dnl Copyright (C) 2010 Andrew Hutchings +dnl This file is free software; Andrew Hutchings +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_BOOST_REGEX],[ + AC_REQUIRE([AC_LIB_PREFIX]) + AC_REQUIRE([ACX_PTHREAD]) + + dnl -------------------------------------------------------------------- + dnl Check for boost::regex + dnl -------------------------------------------------------------------- + + save_CFLAGS="${CFLAGS}" + save_CXXFLAGS="${CXXFLAGS}" + CFLAGS="${PTHREAD_CFLAGS} ${CFLAGS}" + CXXFLAGS="${PTHREAD_CFLAGS} ${CXXFLAGS}" + + AC_LANG_PUSH(C++) + AC_LIB_HAVE_LINKFLAGS(boost_regex-mt,,[ + #include + ],[ + boost::regex test_regex("drizzle"); + ]) + AS_IF([test "x${ac_cv_libboost_regex_mt}" = "xno"],[ + AC_LIB_HAVE_LINKFLAGS(boost_regex,,[ + #include + ],[ + boost::regex test_regex("drizzle"); + ]) + ]) + AC_LANG_POP() + CFLAGS="${save_CFLAGS}" + CXXFLAGS="${save_CXXFLAGS}" + + + AM_CONDITIONAL(HAVE_BOOST_REGEX, + [test "x${ac_cv_libboost_regex}" = "xyes" -o "x${ac_cv_libboost_regex_mt}" = "xyes"]) + BOOST_LIBS="${BOOST_LIBS} ${LTLIBBOOST_REGEX_MT} ${LTLIBBOOST_REGEX}" + AC_SUBST(BOOST_LIBS) +]) + +AC_DEFUN([PANDORA_HAVE_BOOST_REGEX],[ + PANDORA_HAVE_BOOST($1) + _PANDORA_SEARCH_BOOST_REGEX($1) +]) + +AC_DEFUN([PANDORA_REQUIRE_BOOST_REGEX],[ + PANDORA_REQUIRE_BOOST($1) + _PANDORA_SEARCH_BOOST_REGEX($1) + AS_IF([test "x${ac_cv_libboost_regex}" = "xno" -a "x${ac_cv_libboost_regex_mt}" = "xno"], + AC_MSG_ERROR([boost::regex is required for ${PACKAGE}])) +]) + diff --git a/m4/pandora_have_libboost_thread.m4 b/m4/pandora_have_libboost_thread.m4 new file mode 100644 index 00000000..e3359fb3 --- /dev/null +++ b/m4/pandora_have_libboost_thread.m4 @@ -0,0 +1,54 @@ +dnl Copyright (C) 2010 Monty Taylor +dnl This file is free software; Monty Taylor +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_BOOST_THREAD],[ + AC_REQUIRE([AC_LIB_PREFIX]) + AC_REQUIRE([ACX_PTHREAD]) + + dnl -------------------------------------------------------------------- + dnl Check for boost::thread + dnl -------------------------------------------------------------------- + + save_CFLAGS="${CFLAGS}" + save_CXXFLAGS="${CXXFLAGS}" + CFLAGS="${PTHREAD_CFLAGS} ${CFLAGS}" + CXXFLAGS="${PTHREAD_CFLAGS} ${CXXFLAGS}" + + AC_LANG_PUSH(C++) + AC_LIB_HAVE_LINKFLAGS(boost_thread-mt,,[ + #include + ],[ + boost::thread id; + ]) + AS_IF([test "x${ac_cv_libboost_thread_mt}" = "xno"],[ + AC_LIB_HAVE_LINKFLAGS(boost_thread,,[ + #include + ],[ + boost::thread id; + ]) + ]) + AC_LANG_POP() + CFLAGS="${save_CFLAGS}" + CXXFLAGS="${save_CXXFLAGS}" + + + AM_CONDITIONAL(HAVE_BOOST_THREAD, + [test "x${ac_cv_libboost_thread}" = "xyes" -o "x${ac_cv_libboost_thread_mt}" = "xyes"]) + BOOST_LIBS="${BOOST_LIBS} ${LTLIBBOOST_THREAD_MT} ${LTLIBBOOST_THREAD}" + AC_SUBST(BOOST_LIBS) +]) + +AC_DEFUN([PANDORA_HAVE_BOOST_THREAD],[ + PANDORA_HAVE_BOOST($1) + _PANDORA_SEARCH_BOOST_THREAD($1) +]) + +AC_DEFUN([PANDORA_REQUIRE_BOOST_THREAD],[ + PANDORA_REQUIRE_BOOST($1) + _PANDORA_SEARCH_BOOST_THREAD($1) + AS_IF([test "x${ac_cv_libboost_thread}" = "xno" -a "x${ac_cv_libboost_thread_mt}" = "xno"], + AC_MSG_ERROR([boost::thread is required for ${PACKAGE}])) +]) + diff --git a/m4/pandora_have_libcurl.m4 b/m4/pandora_have_libcurl.m4 new file mode 100644 index 00000000..d86ee3e5 --- /dev/null +++ b/m4/pandora_have_libcurl.m4 @@ -0,0 +1,62 @@ +dnl Copyright (C) 2010 Monty Taylor +dnl This file is free software; Monty Taylor +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_LIBCURL],[ + AC_REQUIRE([AC_LIB_PREFIX]) + + dnl -------------------------------------------------------------------- + dnl Check for libcurl + dnl -------------------------------------------------------------------- + + AC_ARG_ENABLE([libcurl], + [AS_HELP_STRING([--disable-libcurl], + [Build with libcurl support @<:@default=on@:>@])], + [ac_enable_libcurl="$enableval"], + [ac_enable_libcurl="yes"]) + + AS_IF([test "x$ac_enable_libcurl" = "xyes"],[ + AC_LIB_HAVE_LINKFLAGS(curl,, + [#include ], + [ + CURL *handle; + handle=curl_easy_init(); + ]) + ],[ + ac_cv_libcurl="no" + ]) + + AC_CACHE_CHECK([if libcurl has CURLOPT_USERNAME], + [pandora_cv_curl_have_username],[ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[ + CURL *handle; + handle=curl_easy_init(); + rv= curl_easy_setopt(curl_handle, CURLOPT_USERNAME, "foo"); + ]])], + [pandora_cv_curl_have_username=yes], + [pandora_cv_curl_have_username=no]) + ]) + + AM_CONDITIONAL(HAVE_LIBCURL,[test "x${ac_cv_libcurl}" = "xyes"]) + AS_IF([test "x$pandora_cv_curl_have_username" = "xyes"], + AC_DEFINE([HAVE_CURLOPT_USERNAME],[1], + [Does libcurl provide the CURLOPT_USERNAME constant])) + +]) + +AC_DEFUN([PANDORA_HAVE_LIBCURL],[ + AC_REQUIRE([_PANDORA_SEARCH_LIBCURL]) + AS_IF([test "x${ac_cv_libcurl}" = "xno"],[ + AC_MSG_WARN([libcurl development lib not found. On Debian this is found in libcurl4-gnutls-dev. On RHEL5/Fedora11 it's in curl-devel. On RHEL6/Fedora12 it's in libcurl-devel.]) + ]) +]) + +AC_DEFUN([PANDORA_REQUIRE_LIBCURL],[ + PANDORA_HAVE_LIBCURL($1) + AS_IF([test "x${ac_cv_libcurl}" = "xno"],[ + AC_MSG_ERROR([libcurl is required for ${PACKAGE}]) + ]) +]) diff --git a/m4/pandora_have_libdl.m4 b/m4/pandora_have_libdl.m4 index 1317ee9d..dde71638 100644 --- a/m4/pandora_have_libdl.m4 +++ b/m4/pandora_have_libdl.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libdrizzle.m4 b/m4/pandora_have_libdrizzle.m4 index 58763c1b..bdd4b6a8 100644 --- a/m4/pandora_have_libdrizzle.m4 +++ b/m4/pandora_have_libdrizzle.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libevent.m4 b/m4/pandora_have_libevent.m4 index 87e5a89d..c7a6c645 100644 --- a/m4/pandora_have_libevent.m4 +++ b/m4/pandora_have_libevent.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libgearman.m4 b/m4/pandora_have_libgearman.m4 index d66a9e45..2eeb34fa 100644 --- a/m4/pandora_have_libgearman.m4 +++ b/m4/pandora_have_libgearman.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libgtest.m4 b/m4/pandora_have_libgtest.m4 index f21c7ef4..fe269fb1 100644 --- a/m4/pandora_have_libgtest.m4 +++ b/m4/pandora_have_libgtest.m4 @@ -18,6 +18,8 @@ AC_DEFUN([_PANDORA_SEARCH_LIBGTEST],[ AS_IF([test "x$ac_enable_libgtest" = "xyes"],[ AC_LANG_PUSH(C++) + save_CXXFLAGS="${CXXFLAGS}" + CXXFLAGS="${AM_CXXFLAGS} ${CXXFLAGS}" AC_LIB_HAVE_LINKFLAGS(gtest,,[ #include TEST(pandora_test_libgtest, PandoraTest) @@ -25,6 +27,7 @@ TEST(pandora_test_libgtest, PandoraTest) ASSERT_EQ(1, 1); } ],[]) + CXXFLAGS="${save_CXXFLAGS}" AC_LANG_POP() ],[ ac_cv_libgtest="no" diff --git a/m4/pandora_have_libhaildb.m4 b/m4/pandora_have_libhaildb.m4 new file mode 100644 index 00000000..56f71ccc --- /dev/null +++ b/m4/pandora_have_libhaildb.m4 @@ -0,0 +1,43 @@ +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([_PANDORA_SEARCH_LIBHAILDB],[ + AC_REQUIRE([AC_LIB_PREFIX]) + + dnl -------------------------------------------------------------------- + dnl Check for libhaildb + dnl -------------------------------------------------------------------- + + AC_ARG_ENABLE([libhaildb], + [AS_HELP_STRING([--disable-libhaildb], + [Build with libhaildb support @<:@default=on@:>@])], + [ac_enable_libhaildb="$enableval"], + [ac_enable_libhaildb="yes"]) + + + AS_IF([test "x$ac_enable_libhaildb" = "xyes"],[ + AC_LIB_HAVE_LINKFLAGS(haildb,,[ + #include + ],[ + ib_set_panic_handler(NULL); + ]) + AS_IF([test "x${ac_cv_libhaildb}" = "xyes"],[ + AC_DEFINE([HAVE_HAILDB_H],[1],[Do we have haildb.h]) + ]) + ],[ + ac_cv_libhaildb="no" + ]) + AM_CONDITIONAL(HAVE_LIBHAILDB, [test "x${ac_cv_libhaildb}" = "xyes"]) +]) + +AC_DEFUN([PANDORA_HAVE_LIBHAILDB],[ + AC_REQUIRE([_PANDORA_SEARCH_LIBHAILDB]) +]) + +AC_DEFUN([PANDORA_REQUIRE_LIBHAILDB],[ + AC_REQUIRE([PANDORA_HAVE_LIBHAILDB]) + AS_IF([test "x${ac_cv_libhaildb}" = "xno"], + AC_MSG_ERROR([libhaildb 2.2.0 or later is required for ${PACKAGE}])) +]) diff --git a/m4/pandora_have_libldap.m4 b/m4/pandora_have_libldap.m4 index b3f2f106..7533e856 100644 --- a/m4/pandora_have_libldap.m4 +++ b/m4/pandora_have_libldap.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libmemcached.m4 b/m4/pandora_have_libmemcached.m4 index 8b20afac..a281306b 100644 --- a/m4/pandora_have_libmemcached.m4 +++ b/m4/pandora_have_libmemcached.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libpcre.m4 b/m4/pandora_have_libpcre.m4 index 64c649b0..bfa733a1 100644 --- a/m4/pandora_have_libpcre.m4 +++ b/m4/pandora_have_libpcre.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libpq.m4 b/m4/pandora_have_libpq.m4 index 3812dc59..28675d1a 100644 --- a/m4/pandora_have_libpq.m4 +++ b/m4/pandora_have_libpq.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libreadline.m4 b/m4/pandora_have_libreadline.m4 index bc739d5d..b49e97dd 100644 --- a/m4/pandora_have_libreadline.m4 +++ b/m4/pandora_have_libreadline.m4 @@ -56,8 +56,8 @@ # # COPYLEFT # -# Copyright (c) 2009 Monty Taylor -# Copyright (c) 2002 Ville Laurikari +# Copyright (C) 2009 Monty Taylor +# Copyright (C) 2002 Ville Laurikari # # Copying and distribution of this file, with or without # modification, are permitted in any medium without royalty provided diff --git a/m4/pandora_have_libsqlite3.m4 b/m4/pandora_have_libsqlite3.m4 index 15e0195c..c1120332 100644 --- a/m4/pandora_have_libsqlite3.m4 +++ b/m4/pandora_have_libsqlite3.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libtokyocabinet.m4 b/m4/pandora_have_libtokyocabinet.m4 index eb0062d5..91906a7c 100644 --- a/m4/pandora_have_libtokyocabinet.m4 +++ b/m4/pandora_have_libtokyocabinet.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libuuid.m4 b/m4/pandora_have_libuuid.m4 index 5ba66d78..f1c583e6 100644 --- a/m4/pandora_have_libuuid.m4 +++ b/m4/pandora_have_libuuid.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libxml2.m4 b/m4/pandora_have_libxml2.m4 index eabd0f3a..76c5805c 100644 --- a/m4/pandora_have_libxml2.m4 +++ b/m4/pandora_have_libxml2.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_libz.m4 b/m4/pandora_have_libz.m4 index 823cb4ef..6122120a 100644 --- a/m4/pandora_have_libz.m4 +++ b/m4/pandora_have_libz.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_have_protobuf.m4 b/m4/pandora_have_protobuf.m4 index 068c6762..47f4cd4a 100644 --- a/m4/pandora_have_protobuf.m4 +++ b/m4/pandora_have_protobuf.m4 @@ -23,7 +23,9 @@ AC_DEFUN([_PANDORA_SEARCH_LIBPROTOBUF],[ [#include ], [google::protobuf::FileDescriptor* file;], [system]) - CXXFLAGS="${save_CXXFLAGS}" + CXXFLAGS="${PTHREAD_CFLAGS} ${save_CXXFLAGS}" + LIBPROTOBUF="${LIBPROTOBUF} ${PTHREAD_LIBS}" + LTLIBPROTOBUF="${LTLIBPROTOBUF} ${PTHREAD_LIBS}" AC_LANG_POP() ]) diff --git a/m4/pandora_have_sasl.m4 b/m4/pandora_have_sasl.m4 index 75513d12..ca4a21dc 100644 --- a/m4/pandora_have_sasl.m4 +++ b/m4/pandora_have_sasl.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_header_assert.m4 b/m4/pandora_header_assert.m4 index 1bd95eb5..2fdf9d4c 100644 --- a/m4/pandora_header_assert.m4 +++ b/m4/pandora_header_assert.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_header_stdcxx_98.m4 b/m4/pandora_header_stdcxx_98.m4 new file mode 100644 index 00000000..130daecd --- /dev/null +++ b/m4/pandora_header_stdcxx_98.m4 @@ -0,0 +1,83 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ac_cxx_header_stdcxx_98.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_CXX_HEADER_STDCXX_98 +# +# DESCRIPTION +# +# Check for complete library coverage of the C++1998/2003 standard. +# +# LICENSE +# +# Copyright (C) 2008 Benjamin Kosnik +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AC_CXX_HEADER_STDCXX_98], [ + AC_CACHE_CHECK(for ISO C++ 98 include files, + ac_cv_cxx_stdcxx_98, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([ + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + ],, + ac_cv_cxx_stdcxx_98=yes, ac_cv_cxx_stdcxx_98=no) + AC_LANG_RESTORE + ]) + if test "$ac_cv_cxx_stdcxx_98" = yes; then + AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ]) + fi +]) diff --git a/m4/pandora_intltool.m4 b/m4/pandora_intltool.m4 new file mode 100644 index 00000000..b3e70625 --- /dev/null +++ b/m4/pandora_intltool.m4 @@ -0,0 +1,225 @@ +## intltool.m4 - Configure intltool for the target system. -*-Shell-script-*- +## Copyright (C) 2001 Eazel, Inc. +## Author: Maciej Stachowiak +## Kenneth Christiansen +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Place - Suite 330, Boston, MA 02110-1301, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml]) +# serial 40 IT_PROG_INTLTOOL +AC_DEFUN([IT_PROG_INTLTOOL], [ +AC_PREREQ([2.50])dnl +AC_REQUIRE([AM_NLS])dnl + +case "$am__api_version" in + 1.[01234]) + AC_MSG_ERROR([Automake 1.5 or newer is required to use intltool]) + ;; + *) + ;; +esac + +if test -n "$1"; then + AC_MSG_CHECKING([for intltool >= $1]) + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` + INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3` + [INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` + ] + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found]) + AS_IF([test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"],[ + pandora_have_intltool=yes + ],[ + pandora_have_intltool=no + AC_MSG_WARN([Your intltool is too old. You need intltool $1 or later.]) + ]) +fi +AC_CHECK_HEADERS([libintl.h]) +AS_IF([test "x${ac_cv_header_libintl_h}" = "xfalse" -o "x${ac_cv_header_libintl_h}" = "xno"],[ + pandora_have_intltool=no +]) + +AC_PATH_PROG(INTLTOOL_UPDATE, [intltool-update]) +AC_PATH_PROG(INTLTOOL_MERGE, [intltool-merge]) +AC_PATH_PROG(INTLTOOL_EXTRACT, [intltool-extract]) +if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then + AC_MSG_WARN([The intltool scripts were not found. Please install intltool.]) + AC_MSG_WARN([On Debian: apt-get install intltool. On Redhat: yum install intltool]) +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@' + INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + +_IT_SUBST(INTLTOOL_DESKTOP_RULE) +_IT_SUBST(INTLTOOL_DIRECTORY_RULE) +_IT_SUBST(INTLTOOL_KEYS_RULE) +_IT_SUBST(INTLTOOL_PROP_RULE) +_IT_SUBST(INTLTOOL_OAF_RULE) +_IT_SUBST(INTLTOOL_PONG_RULE) +_IT_SUBST(INTLTOOL_SERVER_RULE) +_IT_SUBST(INTLTOOL_SHEET_RULE) +_IT_SUBST(INTLTOOL_SOUNDLIST_RULE) +_IT_SUBST(INTLTOOL_UI_RULE) +_IT_SUBST(INTLTOOL_XAM_RULE) +_IT_SUBST(INTLTOOL_KBD_RULE) +_IT_SUBST(INTLTOOL_XML_RULE) +_IT_SUBST(INTLTOOL_XML_NOMERGE_RULE) +_IT_SUBST(INTLTOOL_CAVES_RULE) +_IT_SUBST(INTLTOOL_SCHEMAS_RULE) +_IT_SUBST(INTLTOOL_THEME_RULE) +_IT_SUBST(INTLTOOL_SERVICE_RULE) +_IT_SUBST(INTLTOOL_POLICY_RULE) + +# Check the gettext tools to make sure they are GNU +AC_PATH_PROG(XGETTEXT, xgettext) +AC_PATH_PROG(MSGMERGE, msgmerge) +AC_PATH_PROG(MSGFMT, msgfmt) +AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) +if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then + AC_MSG_WARN([GNU gettext tools not found; required for intltool]) +fi +xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`" +mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`" +mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`" +if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then + AC_MSG_WARN([GNU gettext tools not found; required for intltool]) +fi + +AC_PATH_PROG(INTLTOOL_PERL, perl) +if test -z "$INTLTOOL_PERL"; then + AC_MSG_WARN([perl not found]) +fi +AC_MSG_CHECKING([for perl >= 5.8.1]) +$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1 +if test $? -ne 0; then + AC_MSG_WARN([perl 5.8.1 is required for intltool]) +else + IT_PERL_VERSION="`$INTLTOOL_PERL -e \"printf '%vd', $^V\"`" + AC_MSG_RESULT([$IT_PERL_VERSION]) +fi +if test "x$2" != "xno-xml"; then + AC_MSG_CHECKING([for XML::Parser]) + if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then + AC_MSG_RESULT([ok]) + else + AC_MSG_WARN([XML::Parser perl module is required for intltool]) + fi +fi + +# Substitute ALL_LINGUAS so we can use it in po/Makefile +AC_SUBST(ALL_LINGUAS) + +# Set DATADIRNAME correctly if it is not set yet +# (copied from glib-gettext.m4) +if test -z "$DATADIRNAME"; then + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[]], + [[extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr]])], + [DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share + dnl in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [DATADIRNAME=share], [DATADIRNAME=lib]) + ;; + *) + [DATADIRNAME=lib] + ;; + esac]) +fi +AC_SUBST(DATADIRNAME) + +IT_PO_SUBDIR([po]) +]) + + +# IT_PO_SUBDIR(DIRNAME) +# --------------------- +# All po subdirs have to be declared with this macro; the subdir "po" is +# declared by IT_PROG_INTLTOOL. +# +AC_DEFUN([IT_PO_SUBDIR], +[AC_PREREQ([2.53])dnl We use ac_top_srcdir inside AC_CONFIG_COMMANDS. +dnl +dnl The following CONFIG_COMMANDS should be exetuted at the very end +dnl of config.status. +AC_CONFIG_COMMANDS_PRE([ + AC_CONFIG_COMMANDS([$1/stamp-it], [ + if [ ! grep "^# INTLTOOL_MAKEFILE$" "$1/Makefile.in" > /dev/null ]; then + AC_MSG_WARN([$1/Makefile.in.in was not created by intltoolize.]) + else + rm -f "$1/stamp-it" "$1/stamp-it.tmp" "$1/POTFILES" "$1/Makefile.tmp" + >"$1/stamp-it.tmp" + [sed '/^#/d + s/^[[].*] *// + /^[ ]*$/d + '"s|^| $ac_top_srcdir/|" \ + "$srcdir/$1/POTFILES.in" | sed '$!s/$/ \\/' >"$1/POTFILES" + ] + [sed '/^POTFILES =/,/[^\\]$/ { + /^POTFILES =/!d + r $1/POTFILES + } + ' "$1/Makefile.in" >"$1/Makefile"] + rm -f "$1/Makefile.tmp" + mv "$1/stamp-it.tmp" "$1/stamp-it" + fi + ]) +])dnl +]) + +# _IT_SUBST(VARIABLE) +# ------------------- +# Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST +# +AC_DEFUN([_IT_SUBST], +[ +AC_SUBST([$1]) +m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) +] +) + +# deprecated macros +AU_ALIAS([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL]) +# A hint is needed for aclocal from Automake <= 1.9.4: +# AC_DEFUN([AC_PROG_INTLTOOL], ...) + diff --git a/m4/pandora_libtool.m4 b/m4/pandora_libtool.m4 index 543cbb6b..85456198 100644 --- a/m4/pandora_libtool.m4 +++ b/m4/pandora_libtool.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_optimize.m4 b/m4/pandora_optimize.m4 index 65f9cdc8..fb2cd776 100644 --- a/m4/pandora_optimize.m4 +++ b/m4/pandora_optimize.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -22,25 +22,21 @@ AC_DEFUN([PANDORA_OPTIMIZE],[ dnl with using AC_CC_STD_C99 above CC="${CC} -std=gnu99" - AM_CPPFLAGS="-ggdb3 ${AM_CPPFLAGS}" + AM_CPPFLAGS="-g ${AM_CPPFLAGS}" DEBUG_CFLAGS="-O0" DEBUG_CXXFLAGS="-O0" - OPTIMIZE_CFLAGS="-O3" - OPTIMIZE_CXXFLAGS="-O3" + OPTIMIZE_CFLAGS="-O2" + OPTIMIZE_CXXFLAGS="-O2" ]) AS_IF([test "$INTELCC" = "yes"],[ - dnl Once we can use a modern autoconf, we can replace the std=gnu99 here - dnl with using AC_CC_STD_C99 above - CC="${CC} -std=c99" - AM_CPPFLAGS="-g ${AM_CPPFLAGS}" DEBUG_CFLAGS="-O0" DEBUG_CXXFLAGS="-O0" - OPTIMIZE_CFLAGS="-xHOST -O3 -no-prec-div -static" + OPTIMIZE_CFLAGS="-xHOST -O2 -no-prec-div -static" OPTIMIZE_CXXFLAGS="${OPTIMIZE_CFLAGS}" ]) diff --git a/m4/pandora_platform.m4 b/m4/pandora_platform.m4 index aaec77de..0d2f103b 100644 --- a/m4/pandora_platform.m4 +++ b/m4/pandora_platform.m4 @@ -23,11 +23,20 @@ AC_DEFUN([PANDORA_PLATFORM],[ case "$host_os" in - *solaris*|*freebsd*) + *solaris*) AS_IF([test "x${ac_cv_env_CPPFLAGS_set}" = "x"],[ CPPFLAGS="${CPPFLAGS} -I/usr/local/include" ]) + AS_IF([test "x${ac_cv_env_LDFLAGS_set}" = "x"],[ + LDFLAGS="${LDFLAGS} -L/usr/local/lib" + ]) + ;; + *freebsd*) + AS_IF([test "x${ac_cv_env_CPPFLAGS_set}" = "x"],[ + CPPFLAGS="${CPPFLAGS} -isystem /usr/local/include" + ]) + AS_IF([test "x${ac_cv_env_LDFLAGS_set}" = "x"],[ LDFLAGS="${LDFLAGS} -L/usr/local/lib" ]) @@ -50,6 +59,7 @@ AC_DEFUN([PANDORA_PLATFORM],[ *solaris*) TARGET_SOLARIS="true" PANDORA_OPTIMIZE_BITFIELD=0 + AS_IF([test "x${USE_NLS}" = "xyes"],[LIBS="${LIBS} -lintl"]) AC_SUBST(TARGET_SOLARIS) AC_DEFINE([TARGET_OS_SOLARIS], [1], [Whether we are building for Solaris]) ;; @@ -59,9 +69,26 @@ AC_DEFUN([PANDORA_PLATFORM],[ AC_DEFINE([TARGET_OS_FREEBSD], [1], [Whether we are building for FreeBSD]) AC_DEFINE([__APPLE_CC__],[1],[Workaround for bug in FreeBSD headers]) ;; - *) + *mingw32*) + TARGET_WINDOWS="true" + AC_SUBST(TARGET_WINDOWS) + AC_DEFINE([TARGET_OS_WINDOWS], [1], [Whether we are building for Windows]) + AC_DEFINE([WINVER], [WindowsXP], [Version of Windows]) + AC_DEFINE([_WIN32_WINNT], [0x0501], [Magical number to make things work]) + AC_DEFINE([EAI_SYSTEM], [11], [Another magical number]) + AH_BOTTOM([ +#ifndef HAVE_SYS_SOCKET_H +# define SHUT_RD SD_RECEIVE +# define SHUT_WR SD_SEND +# define SHUT_RDWR SD_BOTH +#endif + ]) + + LIBS="$LIBS -lwsock32 -lws2_32" + AM_CFLAGS="${AM_CFLAGS} -I\${top_srcdir}/win32/mingw -I\${top_builddir}/win32/mingw -I\${top_srcdir}/win32 -I\${top_builddir}/win32" ;; esac + AM_CONDITIONAL(BUILD_WIN32, [test "x${TARGET_WINDOWS}" = "xtrue"]) AC_SUBST(PANDORA_OPTIMIZE_BITFIELD) diff --git a/m4/pandora_plugins.m4 b/m4/pandora_plugins.m4 index 217a0968..6ee13da0 100644 --- a/m4/pandora_plugins.m4 +++ b/m4/pandora_plugins.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl-------------------------------------------------------------------- @@ -25,9 +25,14 @@ AC_DEFUN([PANDORA_PLUGINS],[ dnl Add code here to read set plugin lists and set drizzled_default_plugin_list pandora_builtin_list=`echo $pandora_builtin_list | sed 's/, *$//'` pandora_builtin_symbols_list=`echo $pandora_builtin_symbols_list | sed 's/, *$//'` + pandora_builtin_load_list=`echo $pandora_builtin_load_list | sed 's/, *$//'` + pandora_builtin_load_symbols_list=`echo $pandora_builtin_load_symbols_list | sed 's/, *$//'` AS_IF([test "x$pandora_builtin_symbols_list" = "x"], pandora_builtin_symbols_list="NULL") + AS_IF([test "x$pandora_builtin_load_symbols_list" = "x"], pandora_builtin_load_symbols_list="NULL") AC_SUBST([PANDORA_BUILTIN_LIST],[$pandora_builtin_list]) AC_SUBST([PANDORA_BUILTIN_SYMBOLS_LIST],[$pandora_builtin_symbols_list]) + AC_SUBST([PANDORA_BUILTIN_LOAD_LIST],[$pandora_builtin_load_list]) + AC_SUBST([PANDORA_BUILTIN_LOAD_SYMBOLS_LIST],[$pandora_builtin_load_symbols_list]) AC_SUBST([PANDORA_PLUGIN_LIST],[$pandora_default_plugin_list]) m4_ifval(m4_normalize([$1]),[ AC_CONFIG_FILES($*) diff --git a/m4/pandora_print_callstack.m4 b/m4/pandora_print_callstack.m4 index e28b5933..93faa83d 100644 --- a/m4/pandora_print_callstack.m4 +++ b/m4/pandora_print_callstack.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_python3_devel.m4 b/m4/pandora_python3_devel.m4 index 7712ef19..53a5ffdc 100644 --- a/m4/pandora_python3_devel.m4 +++ b/m4/pandora_python3_devel.m4 @@ -4,12 +4,12 @@ dnl dnl pandora-build: A pedantic build system dnl dnl Copyright (C) 2009 Sun Microsystems, Inc. -dnl Copyright (c) 2008 Sebastian Huber -dnl Copyright (c) 2008 Alan W. Irwin -dnl Copyright (c) 2008 Rafael Laboissiere -dnl Copyright (c) 2008 Andrew Collier -dnl Copyright (c) 2008 Matteo Settenvini -dnl Copyright (c) 2008 Horst Knorr +dnl Copyright (C) 2008 Sebastian Huber +dnl Copyright (C) 2008 Alan W. Irwin +dnl Copyright (C) 2008 Rafael Laboissiere +dnl Copyright (C) 2008 Andrew Collier +dnl Copyright (C) 2008 Matteo Settenvini +dnl Copyright (C) 2008 Horst Knorr dnl dnl This program is free software: you can redistribute it and/or modify it dnl under the terms of the GNU General Public License as published by the diff --git a/m4/pandora_run_cpplint.m4 b/m4/pandora_run_cpplint.m4 index 5099acf6..6d3e9527 100644 --- a/m4/pandora_run_cpplint.m4 +++ b/m4/pandora_run_cpplint.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_sasl.m4 b/m4/pandora_sasl.m4 index 75513d12..ca4a21dc 100644 --- a/m4/pandora_sasl.m4 +++ b/m4/pandora_sasl.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_shared_ptr.m4 b/m4/pandora_shared_ptr.m4 index 5d6e8dde..61fdf151 100644 --- a/m4/pandora_shared_ptr.m4 +++ b/m4/pandora_shared_ptr.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_vc_build.m4 b/m4/pandora_vc_build.m4 index c1a8fba5..5e7ed652 100644 --- a/m4/pandora_vc_build.m4 +++ b/m4/pandora_vc_build.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -36,7 +36,14 @@ AC_DEFUN([PANDORA_TEST_VC_DIR],[ ]) AC_DEFUN([PANDORA_BUILDING_FROM_VC],[ - m4_syscmd(PANDORA_TEST_VC_DIR [ + m4_syscmd(PANDORA_TEST_VC_DIR + m4_if(PCT_NO_VC_CHANGELOG,yes,[ + vc_changelog=no + ],[ + vc_changelog=yes + ]) + + [ PANDORA_RELEASE_DATE=`date +%Y.%m` PANDORA_RELEASE_NODOTS_DATE=`date +%Y%m` @@ -53,6 +60,9 @@ AC_DEFUN([PANDORA_BUILDING_FROM_VC],[ PANDORA_VC_REVNO="${PANDORA_BZR_REVNO}" PANDORA_VC_REVID=`bzr log -r-1 --show-ids | grep revision-id | cut -f2 -d' ' | head -1` PANDORA_VC_BRANCH=`bzr nick` + if test "x${vc_changelog}" = "xyes"; then + bzr log --gnu > ChangeLog + fi fi fi diff --git a/m4/pandora_version.m4 b/m4/pandora_version.m4 index 3a62798a..ee0bfb23 100644 --- a/m4/pandora_version.m4 +++ b/m4/pandora_version.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/pandora_visibility.m4 b/m4/pandora_visibility.m4 index cb68644d..a85d68b0 100644 --- a/m4/pandora_visibility.m4 +++ b/m4/pandora_visibility.m4 @@ -20,17 +20,16 @@ dnl "really only recommended for legacy code". dnl Set the variable CFLAG_VISIBILITY. dnl Defines and sets the variable HAVE_VISIBILITY. -AC_DEFUN([PANDORA_VISIBILITY], +AC_DEFUN([PANDORA_CHECK_VISIBILITY], [ AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([PANDORA_PLATFORM]) CFLAG_VISIBILITY= HAVE_VISIBILITY=0 AS_IF([test -n "$GCC"],[ AC_MSG_CHECKING([for simple visibility declarations]) AC_CACHE_VAL([gl_cv_cc_visibility], [ gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fvisibility=hidden" + CFLAGS="$CFLAGS -fvisibility=hidden -Werror" AC_TRY_COMPILE( [extern __attribute__((__visibility__("hidden"))) int hiddenvar; extern __attribute__((__visibility__("default"))) int exportedvar; @@ -43,15 +42,24 @@ AC_DEFUN([PANDORA_VISIBILITY], AC_MSG_RESULT([$gl_cv_cc_visibility]) if test $gl_cv_cc_visibility = yes; then CFLAG_VISIBILITY="-fvisibility=hidden" + NO_VISIBILITY="-fvisibility=default" HAVE_VISIBILITY=1 fi ]) AS_IF([test "x$SUNCC" = "xyes"],[ CFLAG_VISIBILITY="-xldscope=hidden" + NO_VISIBILITY="-xldscope=global" HAVE_VISIBILITY=1 ]) AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([NO_VISIBILITY]) AC_SUBST([HAVE_VISIBILITY]) AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) ]) + +AC_DEFUN([PANDORA_ENABLE_VISIBILITY],[ + AC_REQUIRE([PANDORA_CHECK_VISIBILITY]) + AM_CFLAGS="${AM_CFLAGS} ${CFLAG_VISIBILITY}" + AM_CXXFLAGS="${AM_CXXFLAGS} ${CFLAG_VISIBILITY}" +]) diff --git a/m4/pandora_warnings.m4 b/m4/pandora_warnings.m4 index 9ee365a0..badce21c 100644 --- a/m4/pandora_warnings.m4 +++ b/m4/pandora_warnings.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -34,6 +34,12 @@ AC_DEFUN([PANDORA_WARNINGS],[ [ac_cv_warnings_as_errors=yes], [ac_cv_warnings_as_errors=no])) + AC_ARG_ENABLE([gcc-profile-mode], + [AS_HELP_STRING([--enable-gcc-profile-mode], + [Toggle gcc profile mode @<:@default=off@:>@])], + [ac_gcc_profile_mode="$enableval"], + [ac_gcc_profile_mode="no"]) + AC_ARG_ENABLE([profiling], [AS_HELP_STRING([--enable-profiling], [Toggle profiling @<:@default=off@:>@])], @@ -87,69 +93,47 @@ AC_DEFUN([PANDORA_WARNINGS],[ F_DIAGNOSTICS_SHOW_OPTION="-fdiagnostics-show-option" ]) - AC_CACHE_CHECK([whether it is safe to use -Wconversion], - [ac_cv_safe_to_use_wconversion_], + AC_CACHE_CHECK([whether it is safe to use -floop-parallelize-all], + [ac_cv_safe_to_use_floop_parallelize_all_], [save_CFLAGS="$CFLAGS" - dnl Use -Werror here instead of ${W_FAIL} so that we don't spew - dnl conversion warnings to all the tarball folks - CFLAGS="-Wconversion -Werror -pedantic ${AM_CFLAGS} ${CFLAGS}" + CFLAGS="-floop-parallelize-all ${AM_CFLAGS} ${CFLAGS}" AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ -#include -void foo(bool a) -{ - (void)a; -} - ]],[[ -foo(0); - ]])], - [ac_cv_safe_to_use_wconversion_=yes], - [ac_cv_safe_to_use_wconversion_=no]) + [AC_LANG_PROGRAM([],[])], + [ac_cv_safe_to_use_floop_parallelize_all_=yes], + [ac_cv_safe_to_use_floop_parallelize_all_=no]) CFLAGS="$save_CFLAGS"]) - AS_IF([test "$ac_cv_safe_to_use_wconversion_" = "yes"], - [W_CONVERSION="-Wconversion" - AC_CACHE_CHECK([whether it is safe to use -Wconversion with htons], - [ac_cv_safe_to_use_Wconversion_], - [save_CFLAGS="$CFLAGS" - dnl Use -Werror here instead of ${W_FAIL} so that we don't spew - dnl conversion warnings to all the tarball folks - CFLAGS="-Wconversion -Werror -pedantic ${AM_CFLAGS} ${CFLAGS}" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include - ]],[[ -uint16_t x= htons(80); - ]])], - [ac_cv_safe_to_use_Wconversion_=yes], - [ac_cv_safe_to_use_Wconversion_=no]) - CFLAGS="$save_CFLAGS"]) - - AS_IF([test "$ac_cv_safe_to_use_Wconversion_" = "no"], - [NO_CONVERSION="-Wno-conversion"]) - ]) + AS_IF([test "$ac_cv_safe_to_use_floop_parallelize_all_" = "yes"], + [ + F_LOOP_PARALLELIZE_ALL="-floop-parallelize-all" + ]) NO_STRICT_ALIASING="-fno-strict-aliasing -Wno-strict-aliasing" NO_SHADOW="-Wno-shadow" AS_IF([test "$INTELCC" = "yes"],[ m4_if(PW_LESS_WARNINGS,[no],[ - BASE_WARNINGS="-w1 -Werror -Wcheck -Wformat -Wp64 -Woverloaded-virtual -Wcast-qual" + BASE_WARNINGS="-w1 -Werror -Wcheck -Wp64 -Woverloaded-virtual -Wcast-qual -diag-disable 188" ],[ - BASE_WARNINGS="-w1 -Wcheck -Wformat -Wp64 -Woverloaded-virtual -Wcast-qual -diag-disable 981" + dnl 2203 is like old-style-cast + dnl 1684 is like strict-aliasing + dnl 188 is about using enums as bitfields + dnl 1683 is a warning about _EXPLICIT_ casting, which we want + BASE_WARNINGS="-w1 -Werror -Wcheck -Wp64 -Woverloaded-virtual -Wcast-qual -diag-disable 188,981,2259,2203,1683,1684" ]) CC_WARNINGS="${BASE_WARNINGS}" CXX_WARNINGS="${BASE_WARNINGS}" + PROTOSKIP_WARNINGS="-diag-disable 188,981,967,2259,1683,1684,2203" + ],[ m4_if(PW_LESS_WARNINGS,[no],[ - BASE_WARNINGS_FULL="-Wformat=2 ${W_CONVERSION} -Wstrict-aliasing" + BASE_WARNINGS_FULL="${W_CONVERSION} -Wstrict-aliasing" CC_WARNINGS_FULL="-Wswitch-default -Wswitch-enum -Wwrite-strings" - CXX_WARNINGS_FULL="-Wold-style-cast" + CXX_WARNINGS_FULL="-Weffc++ -Wold-style-cast" NO_OLD_STYLE_CAST="-Wno-old-style-cast" NO_EFF_CXX="-Wno-effc++" ],[ - BASE_WARNINGS_FULL="-Wformat ${NO_STRICT_ALIASING}" + BASE_WARNINGS_FULL="${NO_STRICT_ALIASING}" ]) AS_IF([test "${ac_cv_assert}" = "no"], @@ -169,11 +153,87 @@ uint16_t x= htons(80); [ac_cv_safe_to_use_Wextra_=no]) CFLAGS="$save_CFLAGS"]) - BASE_WARNINGS="${W_FAIL} -pedantic -Wall -Wundef -Wshadow ${NO_UNUSED} ${F_DIAGNOSTICS_SHOW_OPTION} ${CFLAG_VISIBILITY} ${BASE_WARNINGS_FULL}" + BASE_WARNINGS="${W_FAIL} -pedantic -Wall -Wswitch-enum -Wenum-compare -Wundef -Wshadow ${NO_UNUSED} ${F_DIAGNOSTICS_SHOW_OPTION} ${F_LOOP_PARALLELIZE_ALL} ${BASE_WARNINGS_FULL}" AS_IF([test "$ac_cv_safe_to_use_Wextra_" = "yes"], [BASE_WARNINGS="${BASE_WARNINGS} -Wextra"], [BASE_WARNINGS="${BASE_WARNINGS} -W"]) + AC_CACHE_CHECK([whether it is safe to use -Wformat], + [ac_cv_safe_to_use_wformat_], + [save_CFLAGS="$CFLAGS" + dnl Use -Werror here instead of ${W_FAIL} so that we don't spew + dnl conversion warnings to all the tarball folks + CFLAGS="-Wformat -Werror -pedantic ${AM_CFLAGS} ${CFLAGS}" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +void foo(); +void foo() +{ + uint64_t test_u= 0; + printf("This is a %" PRIu64 "test\n", test_u); +} + ]],[[ +foo(); + ]])], + [ac_cv_safe_to_use_wformat_=yes], + [ac_cv_safe_to_use_wformat_=no]) + CFLAGS="$save_CFLAGS"]) + AS_IF([test "$ac_cv_safe_to_use_wformat_" = "yes"],[ + BASE_WARNINGS="${BASE_WARNINGS} -Wformat -Wno-format-nonliteral -Wno-format-security" + BASE_WARNINGS_FULL="${BASE_WARNINGS_FULL} -Wformat=2 -Wno-format-nonliteral -Wno-format-security" + ],[ + BASE_WARNINGS="${BASE_WARNINGS} -Wno-format" + BASE_WARNINGS_FULL="${BASE_WARNINGS_FULL} -Wno-format" + ]) + + + + AC_CACHE_CHECK([whether it is safe to use -Wconversion], + [ac_cv_safe_to_use_wconversion_], + [save_CFLAGS="$CFLAGS" + dnl Use -Werror here instead of ${W_FAIL} so that we don't spew + dnl conversion warnings to all the tarball folks + CFLAGS="-Wconversion -Werror -pedantic ${AM_CFLAGS} ${CFLAGS}" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#include +void foo(bool a) +{ + (void)a; +} + ]],[[ +foo(0); + ]])], + [ac_cv_safe_to_use_wconversion_=yes], + [ac_cv_safe_to_use_wconversion_=no]) + CFLAGS="$save_CFLAGS"]) + + AS_IF([test "$ac_cv_safe_to_use_wconversion_" = "yes"], + [W_CONVERSION="-Wconversion" + AC_CACHE_CHECK([whether it is safe to use -Wconversion with htons], + [ac_cv_safe_to_use_Wconversion_], + [save_CFLAGS="$CFLAGS" + dnl Use -Werror here instead of ${W_FAIL} so that we don't spew + dnl conversion warnings to all the tarball folks + CFLAGS="-Wconversion -Werror -pedantic ${AM_CFLAGS} ${CFLAGS}" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include + ]],[[ +uint16_t x= htons(80); + ]])], + [ac_cv_safe_to_use_Wconversion_=yes], + [ac_cv_safe_to_use_Wconversion_=no]) + CFLAGS="$save_CFLAGS"]) + + AS_IF([test "$ac_cv_safe_to_use_Wconversion_" = "no"], + [NO_CONVERSION="-Wno-conversion"]) + ]) + CC_WARNINGS="${BASE_WARNINGS} -Wstrict-prototypes -Wmissing-prototypes -Wredundant-decls -Wmissing-declarations -Wcast-align ${CC_WARNINGS_FULL}" CXX_WARNINGS="${BASE_WARNINGS} -Woverloaded-virtual -Wnon-virtual-dtor -Wctor-dtor-privacy -Wno-long-long ${CXX_WARNINGS_FULL}" @@ -196,6 +256,25 @@ uint16_t x= htons(80); AS_IF([test "$ac_cv_safe_to_use_Wmissing_declarations_" = "yes"], [CXX_WARNINGS="${CXX_WARNINGS} -Wmissing-declarations"]) + AC_CACHE_CHECK([whether it is safe to use -Wframe-larger-than], + [ac_cv_safe_to_use_Wframe_larger_than_], + [AC_LANG_PUSH(C++) + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="-Werror -pedantic -Wframe-larger-than=32768 ${AM_CXXFLAGS}" + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[ +#include + ]], [[]]) + ], + [ac_cv_safe_to_use_Wframe_larger_than_=yes], + [ac_cv_safe_to_use_Wframe_larger_than_=no]) + CXXFLAGS="$save_CXXFLAGS" + AC_LANG_POP() + ]) + AS_IF([test "$ac_cv_safe_to_use_Wframe_larger_than_" = "yes"], + [CXX_WARNINGS="${CXX_WARNINGS} -Wframe-larger-than=32768"]) + AC_CACHE_CHECK([whether it is safe to use -Wlogical-op], [ac_cv_safe_to_use_Wlogical_op_], [save_CFLAGS="$CFLAGS" @@ -292,7 +371,7 @@ inline const EnumDescriptor* GetEnumDescriptor() { dnl TODO: Figure out a better way to deal with this: PROTOSKIP_WARNINGS="-Wno-effc++ -Wno-shadow -Wno-missing-braces ${NO_ATTRIBUTES}" NO_WERROR="-Wno-error" - INNOBASE_SKIP_WARNINGS="-Wno-shadow -Wno-cast-align" + PERMISSIVE_WARNINGS="-Wno-error -Wno-unused-function -fpermissive" AS_IF([test "$host_vendor" = "apple"],[ BOOSTSKIP_WARNINGS="-Wno-uninitialized" ]) @@ -326,17 +405,19 @@ inline const EnumDescriptor* GetEnumDescriptor() { m4_if(PW_LESS_WARNINGS, [no],[ - CC_WARNINGS_FULL="-erroff=E_INTEGER_OVERFLOW_DETECTED${W_PASTE_RESULT}" + CC_WARNINGS_FULL="-erroff=E_STATEMENT_NOT_REACHED,E_INTEGER_OVERFLOW_DETECTED${W_PASTE_RESULT}" CXX_WARNINGS_FULL="-erroff=inllargeuse" ],[ - CC_WARNINGS_FULL="-erroff=E_ATTRIBUTE_NOT_VAR" + CC_WARNINGS_FULL="-erroff=E_ATTRIBUTE_NOT_VAR,E_STATEMENT_NOT_REACHED" CXX_WARNINGS_FULL="-erroff=attrskipunsup,doubunder,reftotemp,inllargeuse,truncwarn1,signextwarn,inllargeint" ]) - CC_WARNINGS="-v -errtags=yes ${W_FAIL} ${CC_WARNINGS_FULL} ${CFLAG_VISIBILITY}" - CXX_WARNINGS="+w +w2 -xwe -xport64 -errtags=yes ${CXX_WARNINGS_FULL} ${W_FAIL} ${CFLAG_VISIBILITY}" + CC_WARNINGS="-v -errtags=yes ${W_FAIL} ${CC_WARNINGS_FULL}" + CXX_WARNINGS="+w +w2 -xwe -xport64 -errtags=yes ${CXX_WARNINGS_FULL} ${W_FAIL}" PROTOSKIP_WARNINGS="-erroff=attrskipunsup,doubunder,reftotemp,wbadinitl,identexpected,inllargeuse,truncwarn1,signextwarn,partinit,notused,badargtype2w,wbadinit" BOOSTSKIP_WARNINGS="-erroff=attrskipunsup,doubunder,reftotemp,inllargeuse,truncwarn1,signextwarn,inllargeint,hidef,wvarhidenmem" + PERMISSIVE_WARNINGS="-erroff=attrskipunsup,doubunder,reftotemp,inllargeuse,truncwarn1,signextwarn,inllargeint,hidef,wvarhidenmem,notused,badargtype2w,wunreachable" + INNOBASE_SKIP_WARNINGS="-erroff=attrskipunsup,doubunder,reftotemp,wbadinitl,identexpected,inllargeuse,truncwarn1,signextwarn,partinit,notused,badargtype2w,wbadinit,wunreachable" NO_UNREACHED="-erroff=E_STATEMENT_NOT_REACHED" NO_WERROR="-errwarn=%none" @@ -350,8 +431,9 @@ inline const EnumDescriptor* GetEnumDescriptor() { AC_SUBST(NO_EFF_CXX) AC_SUBST(NO_OLD_STYLE_CAST) AC_SUBST(PROTOSKIP_WARNINGS) - AC_SUBST(BOOSTSKIP_WARNINGS) AC_SUBST(INNOBASE_SKIP_WARNINGS) + AC_SUBST(BOOSTSKIP_WARNINGS) + AC_SUBST(PERMISSIVE_WARNINGS) AC_SUBST(NO_WERROR) AC_SUBST([GCOV_LIBS]) diff --git a/m4/pandora_with_memcached.m4 b/m4/pandora_with_memcached.m4 index 81fc5955..4ea906b6 100644 --- a/m4/pandora_with_memcached.m4 +++ b/m4/pandora_with_memcached.m4 @@ -1,5 +1,5 @@ -dnl Copyright (C) 2009 Sun Microsystems -dnl This file is free software; Sun Microsystems +dnl Copyright (C) 2009 Sun Microsystems, Inc. +dnl This file is free software; Sun Microsystems, Inc. dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/po.m4 b/m4/po.m4 index 0734762a..47f36a41 100644 --- a/m4/po.m4 +++ b/m4/po.m4 @@ -1,5 +1,5 @@ -# po.m4 serial 15 (gettext-0.17) -dnl Copyright (C) 1995-2007 Free Software Foundation, Inc. +# po.m4 serial 17 (gettext-0.18) +dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -17,7 +17,7 @@ dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. -AC_PREREQ(2.50) +AC_PREREQ([2.50]) dnl Checks for all prerequisites of the po subdirectory. AC_DEFUN([AM_PO_SUBDIRS], @@ -29,7 +29,7 @@ AC_DEFUN([AM_PO_SUBDIRS], dnl Release version of the gettext macros. This is used to ensure that dnl the gettext macros and po/Makefile.in.in are in sync. - AC_SUBST([GETTEXT_MACRO_VERSION], [0.17]) + AC_SUBST([GETTEXT_MACRO_VERSION], [0.18]) dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. @@ -41,7 +41,7 @@ AC_DEFUN([AM_PO_SUBDIRS], [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) dnl Test whether it is GNU msgfmt >= 0.15. changequote(,)dnl diff --git a/m4/progtest.m4 b/m4/progtest.m4 index a56365cd..2d804ac9 100644 --- a/m4/progtest.m4 +++ b/m4/progtest.m4 @@ -1,5 +1,5 @@ -# progtest.m4 serial 4 (gettext-0.14.2) -dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc. +# progtest.m4 serial 6 (gettext-0.18) +dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -16,7 +16,7 @@ dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. -AC_PREREQ(2.50) +AC_PREREQ([2.50]) # Search path for a program which passes the given test. @@ -55,7 +55,7 @@ rm -f conf$$.file # Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL(ac_cv_path_$1, +AC_CACHE_VAL([ac_cv_path_$1], [case "[$]$1" in [[\\/]]* | ?:[[\\/]]*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. @@ -84,9 +84,9 @@ ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$]$1) + AC_MSG_RESULT([$][$1]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi -AC_SUBST($1)dnl +AC_SUBST([$1])dnl ]) diff --git a/m4/protocol_binary.m4 b/m4/protocol_binary.m4 index ba7acaf5..5c00b556 100644 --- a/m4/protocol_binary.m4 +++ b/m4/protocol_binary.m4 @@ -1,22 +1,34 @@ dnl --------------------------------------------------------------------------- dnl Macro: PROTOCOL_BINARY_TEST dnl --------------------------------------------------------------------------- + AC_DEFUN([PROTOCOL_BINARY_TEST], - [AC_LANG_PUSH([C]) - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -I${srcdir}" - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[ +[ + AC_CACHE_CHECK([for supported struct padding], [ac_cv_supported_struct_padding], [ + AC_LANG_PUSH([C]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I${srcdir}" + AC_TRY_COMPILE([ #include #include "libmemcached/memcached/protocol_binary.h" - ]],[[ + ], [ protocol_binary_request_set request; - if (sizeof(request) != sizeof(request.bytes)) { - return 1; + int a = 1; + switch (a) { + case sizeof(request): + case sizeof(request.bytes): + break; + default: + a = 2; } - ]])],, AC_MSG_ERROR([Unsupported struct padding done by compiler.])) + ], + [ ac_cv_supported_struct_padding=no ], + [ ac_cv_supported_struct_padding=yes ]) CFLAGS="$save_CFLAGS" AC_LANG_POP + ]) + AS_IF([test "x$ac_cv_supported_struct_padding" = "xno"],[ + AC_MSG_ERROR([Unsupported struct padding done by compiler.])]) ]) dnl --------------------------------------------------------------------------- diff --git a/m4/setsockopt.m4 b/m4/setsockopt.m4 index e37fe2ae..58c61c0a 100644 --- a/m4/setsockopt.m4 +++ b/m4/setsockopt.m4 @@ -2,6 +2,7 @@ dnl --------------------------------------------------------------------------- dnl Macro: SETSOCKOPT_SANITY dnl --------------------------------------------------------------------------- AC_DEFUN([SETSOCKOPT_SANITY],[ + AC_CACHE_CHECK([for working SO_SNDTIMEO], [ac_cv_have_so_sndtimeo], AC_LANG_PUSH([C]) AC_RUN_IFELSE([ AC_LANG_PROGRAM([[ @@ -25,8 +26,17 @@ AC_DEFUN([SETSOCKOPT_SANITY],[ } return 0; ]])], - [AC_DEFINE(HAVE_SNDTIMEO, 1, [Define to 1 if you have a working SO_SNDTIMEO])]) + [ac_cv_have_so_sndtimeo=yes], + [ac_cv_have_so_sndtimeo=no], + [ac_cv_have_so_sndtimeo=yes]) + AS_IF([test "x$ac_cv_have_so_sndtimeo" = "xyes"], [ + AC_DEFINE(HAVE_SNDTIMEO, 1, [Define to 1 if you have a working SO_SNDTIMEO])]) + AC_LANG_POP + ) + + AC_CACHE_CHECK([for working SO_RCVTIMEO], [ac_cv_have_so_rcvtimeo], + AC_LANG_PUSH([C]) AC_RUN_IFELSE([ AC_LANG_PROGRAM([[ #include @@ -34,7 +44,7 @@ AC_DEFUN([SETSOCKOPT_SANITY],[ #include #include #include - ]],[[ + ]],[[ int sock = socket(AF_INET, SOCK_STREAM, 0); struct timeval waittime; @@ -48,9 +58,15 @@ AC_DEFUN([SETSOCKOPT_SANITY],[ } } return 0; - ]])], [AC_DEFINE(HAVE_RCVTIMEO, 1, [Define to 1 if you have a working SO_RCVTIMEO])]) + ]])], + [ac_cv_have_so_rcvtimeo=yes], + [ac_cv_have_so_rcvtimeo=no], + [ac_cv_have_so_rcvtimeo=yes]) - AC_LANG_POP + AS_IF([test "x$ac_cv_have_so_rcvtimeo" = "xyes"], [ + AC_DEFINE(HAVE_RCVTIMEO, 1, [Define to 1 if you have a working SO_RCVTIMEO])]) + AC_LANG_POP + ) ]) dnl --------------------------------------------------------------------------- dnl End Macro: SETSOCKOPT_SANITY diff --git a/support/libmemcached.spec.in b/support/libmemcached.spec.in index 6b022b43..ee9f20f9 100644 --- a/support/libmemcached.spec.in +++ b/support/libmemcached.spec.in @@ -83,11 +83,11 @@ you will need to install %{name}-devel. %exclude %{_libdir}/libmemcachedutil.la %exclude %{_libdir}/libmemcachedprotocol.la %{_libdir}/libhashkit.so.0.0.0 -%{_libdir}/libmemcached.so.5.0.2 +%{_libdir}/libmemcached.so.6.0.0 %{_libdir}/libmemcachedutil.so.1.0.0 %{_libdir}/libmemcachedprotocol.so.0.0.0 %{_libdir}/libhashkit.so.0 -%{_libdir}/libmemcached.so.5 +%{_libdir}/libmemcached.so.6 %{_libdir}/libmemcachedprotocol.so.0 %{_libdir}/libmemcachedutil.so.1 %{_mandir}/man1/memcapable.1.gz diff --git a/tests/hash_results.h b/tests/hash_results.h index 26f1ed85..c05053a7 100644 --- a/tests/hash_results.h +++ b/tests/hash_results.h @@ -105,6 +105,7 @@ static uint32_t hsieh_values[]= { 3738850110U, 3636226060U, 3821074029U, 3489929 static uint32_t hsieh_values[]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; #endif +#ifdef HAVE_MURMUR_HASH static uint32_t murmur_values[]= { 4142305122U, 734504955U, 3802834688U, 4076891445U, 387802650U, 560515427U, 3274673488U, 3150339524U, 1527441970U, 2728642900U, 3613992239U, 2938419259U, @@ -112,6 +113,9 @@ static uint32_t murmur_values[]= { 4142305122U, 734504955U, 3802834688U, 407689 264013145U, 3995512858U, 2400956718U, 2346666219U, 926327338U, 442757446U, 1770805201U, 560483147U, 3902279934U }; +#else +static uint32_t murmur_values[]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +#endif static uint32_t jenkins_values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U, 3261968576U, 3515188778U, 4232909173U, 4288625128U, diff --git a/tests/hashkit_functions.c b/tests/hashkit_functions.c index 46f53934..d1f846e7 100644 --- a/tests/hashkit_functions.c +++ b/tests/hashkit_functions.c @@ -251,6 +251,7 @@ static test_return_t hsieh_run (hashkit_st *hashk __attribute__((unused))) static test_return_t murmur_run (hashkit_st *hashk __attribute__((unused))) { #ifdef WORDS_BIGENDIAN + (void)murmur_values; return TEST_SKIPPED; #else uint32_t x; @@ -260,7 +261,11 @@ static test_return_t murmur_run (hashkit_st *hashk __attribute__((unused))) { uint32_t hash_val; +#ifdef HAVE_MURMUR_HASH hash_val= libhashkit_murmur(*ptr, strlen(*ptr)); +#else + hash_val= 1; +#endif assert(murmur_values[x] == hash_val); } @@ -319,8 +324,15 @@ static test_return_t hashkit_set_function_test(hashkit_st *hashk) rc= hashkit_set_function(hashk, algo); /* Hsieh is disabled most of the time for patent issues */ +#ifndef HAVE_HSIEH_HASH if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_HSIEH) continue; +#endif + +#ifndef HAVE_MURMUR_HASH + if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_MURMUR) + continue; +#endif if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_CUSTOM) continue; diff --git a/tests/include.am b/tests/include.am index 501939df..27a7bf51 100644 --- a/tests/include.am +++ b/tests/include.am @@ -47,7 +47,11 @@ tests_testapp_DEPENDENCIES= \ tests/libtest.la \ libmemcached/libmemcachedinternal.la \ $(TESTS_LDADDS) -tests_testapp_LDADD= $(tests_testapp_DEPENDENCIES) $(LIBSASL) +tests_testapp_LDADD= clients/libgenexec.la \ + tests/libserver.la \ + tests/libtest.la \ + libmemcached/libmemcachedinternal.la \ + $(TESTS_LDADDS) $(LIBSASL) tests_testplus_SOURCES= tests/plus.cpp tests_testplus_CXXFLAGS = $(AM_CXXFLAGS) $(NO_EFF_CXX) diff --git a/tests/mem_functions.c b/tests/mem_functions.c index 06c414a8..389bfdc1 100644 --- a/tests/mem_functions.c +++ b/tests/mem_functions.c @@ -97,6 +97,23 @@ static memcached_return_t server_display_function(const memcached_st *ptr __att return MEMCACHED_SUCCESS; } +static memcached_return_t dump_server_information(const memcached_st *ptr __attribute__((unused)), + const memcached_server_st *instance, + void *context) +{ + /* Do Nothing */ + FILE *stream= (FILE *)context; + + fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n", + memcached_server_name(instance), + memcached_server_port(instance), + instance->major_version, + instance->minor_version, + instance->micro_version); + + return MEMCACHED_SUCCESS; +} + static test_return_t server_sort_test(memcached_st *ptr __attribute__((unused))) { size_t bigger= 0; /* Prime the value for the test_true in server_display_function */ @@ -1014,7 +1031,7 @@ static test_return_t set_test3(memcached_st *memc) { char key[16]; - sprintf(key, "foo%u", x); + snprintf(key, sizeof(key), "foo%u", x); rc= memcached_set(memc, key, strlen(key), value, value_length, @@ -1683,7 +1700,7 @@ static test_return_t mget_execute(memcached_st *memc) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); test_true(keys[x] != NULL); rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0); @@ -2037,7 +2054,7 @@ static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc) return TEST_SUCCESS; } -static test_return_t fetch_all_results(memcached_st *memc) +static test_return_t fetch_all_results(memcached_st *memc, size_t *keys_returned) { memcached_return_t rc= MEMCACHED_SUCCESS; char return_key[MEMCACHED_MAX_KEY]; @@ -2046,15 +2063,20 @@ static test_return_t fetch_all_results(memcached_st *memc) size_t return_value_length; uint32_t flags; + *keys_returned= 0; + while ((return_value= memcached_fetch(memc, return_key, &return_key_length, &return_value_length, &flags, &rc))) { test_true(return_value); test_true(rc == MEMCACHED_SUCCESS); free(return_value); + *keys_returned= *keys_returned +1; } - return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE; + test_true_got(rc == MEMCACHED_END || rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + + return TEST_SUCCESS; } /* Test case provided by Cal Haldenbrand */ @@ -2192,7 +2214,8 @@ static test_return_t user_supplied_bug3(memcached_st *memc) rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT); test_true(rc == MEMCACHED_SUCCESS); - test_true(fetch_all_results(memc) == TEST_SUCCESS); + size_t keys_returned; + test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS); for (x= 0; x < KEY_COUNT; x++) free(keys[x]); @@ -2988,7 +3011,8 @@ static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count) alarm(0); signal(SIGALRM, oldalarm); - test_true(fetch_all_results(memc) == TEST_SUCCESS); + size_t keys_returned; + test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS); for (x= 0; x < key_count; x++) free(keys[x]); @@ -3143,7 +3167,7 @@ static test_return_t output_ketama_weighted_keys(memcached_st *trash) for (int x= 0; x < 10000; x++) { char key[10]; - sprintf(key, "%d", x); + snprintf(key, sizeof(key), "%d", x); uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key)); char *hostname = memc->hosts[server_idx].hostname; @@ -3342,7 +3366,9 @@ static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unus static test_return_t generate_data(memcached_st *memc) { - execute_set(memc, global_pairs, global_count); + unsigned int check_execute= execute_set(memc, global_pairs, global_count); + + test_true(check_execute == global_count); return TEST_SUCCESS; } @@ -3352,7 +3378,9 @@ static test_return_t generate_data_with_stats(memcached_st *memc) memcached_stat_st *stat_p; memcached_return_t rc; uint32_t host_index= 0; - execute_set(memc, global_pairs, global_count); + unsigned int check_execute= execute_set(memc, global_pairs, global_count); + + test_true(check_execute == global_count); //TODO: hosts used size stats stat_p= memcached_stat(memc, NULL, &rc); @@ -3448,9 +3476,22 @@ static test_return_t mget_read(memcached_st *memc) { memcached_return_t rc; + if (! libmemcached_util_version_check(memc, 1, 4, 4)) + return TEST_SKIPPED; + rc= memcached_mget(memc, global_keys, global_keys_length, global_count); - test_true(rc == MEMCACHED_SUCCESS); - test_true(fetch_all_results(memc) == TEST_SUCCESS); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + + // Go fetch the keys and test to see if all of them were returned + { + size_t keys_returned; + test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS); + char buffer[30]; + snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)keys_returned); + test_true_got(global_count == keys_returned, buffer); + } + return TEST_SUCCESS; } @@ -3459,8 +3500,13 @@ static test_return_t mget_read_result(memcached_st *memc) { memcached_return_t rc; + if (! libmemcached_util_version_check(memc, 1, 4, 4)) + return TEST_SKIPPED; + rc= memcached_mget(memc, global_keys, global_keys_length, global_count); - test_true(rc == MEMCACHED_SUCCESS); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + /* Turn this into a help function */ { memcached_result_st results_obj; @@ -3486,8 +3532,12 @@ static test_return_t mget_read_function(memcached_st *memc) size_t counter; memcached_execute_fn callbacks[1]; + if (! libmemcached_util_version_check(memc, 1, 4, 4)) + return TEST_SKIPPED; + rc= memcached_mget(memc, global_keys, global_keys_length, global_count); - test_true(rc == MEMCACHED_SUCCESS); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); callbacks[0]= &callback_counter; counter= 0; @@ -3535,7 +3585,7 @@ static test_return_t add_host_test1(memcached_st *memc) { char buffer[SMALL_STRING_LEN]; - snprintf(buffer, SMALL_STRING_LEN, "%zu.example.com", 400+x); + snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x)); servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0, &rc); test_true(rc == MEMCACHED_SUCCESS); @@ -3603,7 +3653,7 @@ static test_return_t pre_nonblock_binary(memcached_st *memc) // will not toggle protocol on an connection. memcached_version(memc_clone); - if (libmemcached_util_version_check(memc_clone, 1, 3, 0)) + if (libmemcached_util_version_check(memc_clone, 1, 4, 4)) { memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0); rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); @@ -3622,9 +3672,13 @@ static test_return_t pre_nonblock_binary(memcached_st *memc) static test_return_t pre_murmur(memcached_st *memc) { +#ifdef HAVE_MURMUR_HASH memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR); - return TEST_SUCCESS; +#else + (void) memc; + return TEST_SKIPPED; +#endif } static test_return_t pre_jenkins(memcached_st *memc) @@ -3729,7 +3783,7 @@ static test_return_t pre_binary(memcached_st *memc) { memcached_return_t rc= MEMCACHED_FAILURE; - if (libmemcached_util_version_check(memc, 1, 3, 0)) + if (libmemcached_util_version_check(memc, 1, 4, 4)) { rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); test_true(rc == MEMCACHED_SUCCESS); @@ -4151,7 +4205,11 @@ static test_return_t noreply_test(memcached_st *memc) for (size_t x= 0; x < 100; ++x) { char key[10]; - size_t len= (size_t)sprintf(key, "%zu", x); + int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x); + test_false((size_t)check_length >= sizeof(key) || check_length < 0); + + size_t len= (size_t)check_length; + switch (count) { case 0: @@ -4199,7 +4257,11 @@ static test_return_t noreply_test(memcached_st *memc) { char key[10]; - size_t len= (size_t)sprintf(key, "%zu", x); + int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x); + + test_false((size_t)check_length >= sizeof(key) || check_length < 0); + + size_t len= (size_t)check_length; size_t length; uint32_t flags; char* value=memcached_get(memc, key, strlen(key), @@ -4336,14 +4398,15 @@ static void* connection_release(void *arg) return arg; } +#define POOL_SIZE 10 static test_return_t connection_pool_test(memcached_st *memc) { - memcached_pool_st* pool= memcached_pool_create(memc, 5, 10); + memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE); test_true(pool != NULL); - memcached_st* mmc[10]; + memcached_st *mmc[POOL_SIZE]; memcached_return_t rc; - for (size_t x= 0; x < 10; ++x) + for (size_t x= 0; x < POOL_SIZE; ++x) { mmc[x]= memcached_pool_pop(pool, false, &rc); test_true(mmc[x] != NULL); @@ -4370,7 +4433,7 @@ static test_return_t connection_pool_test(memcached_st *memc) rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0); test_true(rc == MEMCACHED_SUCCESS); - for (size_t x= 0; x < 10; ++x) + for (size_t x= 0; x < POOL_SIZE; ++x) { uint64_t number_value; rc= memcached_increment(mmc[x], key, keylen, 1, &number_value); @@ -4379,7 +4442,7 @@ static test_return_t connection_pool_test(memcached_st *memc) } // Release them.. - for (size_t x= 0; x < 10; ++x) + for (size_t x= 0; x < POOL_SIZE; ++x) { test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS); } @@ -4406,8 +4469,8 @@ static test_return_t connection_pool_test(memcached_st *memc) test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999); test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS); - test_true(memcached_pool_destroy(pool) == memc); + return TEST_SUCCESS; } @@ -4419,6 +4482,18 @@ static test_return_t util_version_test(memcached_st *memc) test_true(if_successful == true); if_successful= libmemcached_util_version_check(memc, 9, 9, 9); + + // We expect failure + if (if_successful) + { + fprintf(stderr, "\n----------------------------------------------------------------------\n"); + fprintf(stderr, "\nDumping Server Information\n\n"); + memcached_server_fn callbacks[1]; + + callbacks[0]= dump_server_information; + memcached_server_cursor(memc, callbacks, (void *)stderr, 1); + fprintf(stderr, "\n----------------------------------------------------------------------\n"); + } test_true(if_successful == false); memcached_server_instance_st instance= @@ -4760,6 +4835,19 @@ static test_return_t hsieh_avaibility_test (memcached_st *memc) return TEST_SUCCESS; } +static test_return_t murmur_avaibility_test (memcached_st *memc) +{ + memcached_return_t expected_rc= MEMCACHED_FAILURE; +#ifdef HAVE_MURMUR_HASH + expected_rc= MEMCACHED_SUCCESS; +#endif + memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, + (uint64_t)MEMCACHED_HASH_MURMUR); + test_true(rc == expected_rc); + + return TEST_SUCCESS; +} + static test_return_t one_at_a_time_run (memcached_st *memc __attribute__((unused))) { uint32_t x; @@ -4892,6 +4980,7 @@ static test_return_t hsieh_run (memcached_st *memc __attribute__((unused))) static test_return_t murmur_run (memcached_st *memc __attribute__((unused))) { #ifdef WORDS_BIGENDIAN + (void)murmur_values; return TEST_SKIPPED; #else uint32_t x; @@ -5036,7 +5125,7 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc) test_false(value); test_true(len == 0); - test_true(rc == MEMCACHED_ERRNO); + test_false(rc == MEMCACHED_SUCCESS); memcached_free(tl_memc_h); @@ -5093,7 +5182,7 @@ static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc) test_false(value); test_true(len == 0); - test_true(rc == MEMCACHED_ERRNO); + test_false(rc == MEMCACHED_SUCCESS); memcached_free(tl_memc_h); @@ -5296,7 +5385,7 @@ static test_return_t regression_bug_434843(memcached_st *memc) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); test_true(keys[x] != NULL); } @@ -5437,7 +5526,7 @@ static test_return_t regression_bug_447342(memcached_st *memc) memcached_server_instance_st instance_one; memcached_server_instance_st instance_two; - if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS) + if (memcached_server_count(memc) < 3 || pre_replication(memc) != TEST_SUCCESS) return TEST_SKIPPED; memcached_return_t rc; @@ -5453,7 +5542,7 @@ static test_return_t regression_bug_447342(memcached_st *memc) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); test_true(keys[x] != NULL); rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0); @@ -5582,19 +5671,19 @@ static test_return_t regression_bug_463297(memcached_st *memc) memcached_return_t rc= memcached_delete(memc, "foo", 3, 1); /* but there is a bug in some of the memcached servers (1.4) that treats - * the counter as noreply so it doesn't send the proper error message - */ - test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR); + * the counter as noreply so it doesn't send the proper error message + */ + test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc)); /* And buffered mode should be disabled and we should get protocol error */ test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS); rc= memcached_delete(memc, "foo", 3, 1); - test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR); + test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc)); /* Same goes for noreply... */ test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS); rc= memcached_delete(memc, "foo", 3, 1); - test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR); + test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc)); /* but a normal request should go through (and be buffered) */ test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED); @@ -5850,7 +5939,7 @@ static test_return_t regression_bug_490486(memcached_st *memc) for (size_t x= 0; x < max_keys; ++x) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); assert(keys[x] != NULL); rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0); @@ -5943,7 +6032,7 @@ static test_return_t regression_bug_583031(memcached_st *unused) (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc); - test_true(rc == MEMCACHED_TIMEOUT); + test_true_got(rc == MEMCACHED_TIMEOUT, memcached_strerror(NULL, rc)); memcached_free(memc); @@ -6320,6 +6409,11 @@ test_st hsieh_availability[] ={ {0, 0, (test_callback_fn)0} }; +test_st murmur_availability[] ={ + {"murmur_avaibility_test", 0, (test_callback_fn)murmur_avaibility_test}, + {0, 0, (test_callback_fn)0} +}; + #if 0 test_st hash_sanity[] ={ {"hash sanity", 0, (test_callback_fn)hash_sanity_test}, @@ -6361,6 +6455,7 @@ collection_st collection[] ={ {"hash_sanity", 0, 0, hash_sanity}, #endif {"hsieh_availability", 0, 0, hsieh_availability}, + {"murmur_availability", 0, 0, murmur_availability}, {"block", 0, 0, tests}, {"binary", (test_callback_fn)pre_binary, 0, tests}, {"nonblock", (test_callback_fn)pre_nonblock, 0, tests}, diff --git a/tests/server.c b/tests/server.c index f8d06dbf..84f15de0 100644 --- a/tests/server.c +++ b/tests/server.c @@ -15,21 +15,70 @@ #define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT+10 +#define PID_FILE_BASE "/tmp/%ulibmemcached_memc.pid" + #include "config.h" +#include +#include +#include #include #include #include +#include #include -#include -#include +#include + #include #include -#include -#include #include "server.h" +static struct timespec global_sleep_value= { .tv_sec= 0, .tv_nsec= 50000 }; + +static void global_sleep(void) +{ +#ifdef WIN32 + sleep(1); +#else + nanosleep(&global_sleep_value, NULL); +#endif +} + +static void kill_file(const char *file_buffer) +{ + FILE *fp= fopen(file_buffer, "r"); + + while ((fp= fopen(file_buffer, "r"))) + { + char pid_buffer[1024]; + + if (fgets(pid_buffer, sizeof(pid_buffer), fp) != NULL) + { + pid_t pid= (pid_t)atoi(pid_buffer); + if (pid != 0) + { + if (kill(pid, SIGTERM) == -1) + { + remove(file_buffer); // If this happens we may be dealing with a dead server that left its pid file. + } + else + { + uint32_t counter= 3; + while ((kill(pid, 0) == 0) && --counter) + { + global_sleep(); + } + } + } + } + + global_sleep(); + + fclose(fp); + } +} + void server_startup(server_startup_st *construct) { if ((construct->server_list= getenv("MEMCACHED_SERVERS"))) @@ -48,86 +97,118 @@ void server_startup(server_startup_st *construct) for (uint32_t x= 0; x < construct->count; x++) { - char buffer[1024]; /* Nothing special for number */ - int count; int status; + in_port_t port; - sprintf(buffer, "/tmp/%umemc.pid", x); - if (access(buffer, F_OK) == 0) { - FILE *fp= fopen(buffer, "r"); - remove(buffer); + char *var; + char variable_buffer[1024]; - if (fp != NULL) - { - if (fgets(buffer, sizeof(buffer), fp) != NULL) - { - pid_t pid= (pid_t)atoi(buffer); - if (pid != 0) - kill(pid, SIGTERM); - } + snprintf(variable_buffer, sizeof(variable_buffer), "LIBMEMCACHED_PORT_%u", x); - fclose(fp); + if ((var= getenv(variable_buffer))) + { + port= (in_port_t)atoi(var); + } + else + { + port= (in_port_t)(x + TEST_PORT_BASE); } } + char buffer[PATH_MAX]; + snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x); + kill_file(buffer); + if (x == 0) { - sprintf(buffer, "%s -d -u root -P /tmp/%umemc.pid -t 1 -p %u -U %u -m 128", - MEMCACHED_BINARY, x, x + TEST_PORT_BASE, x + TEST_PORT_BASE); + snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u -m 128", + MEMCACHED_BINARY, x, port, port); } else { - sprintf(buffer, "%s -d -u root -P /tmp/%umemc.pid -t 1 -p %u -U %u", - MEMCACHED_BINARY, x, x + TEST_PORT_BASE, x + TEST_PORT_BASE); + snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u", + MEMCACHED_BINARY, x, port, port); } - if (libmemcached_util_ping("localhost", (in_port_t)(x + TEST_PORT_BASE), NULL)) + if (libmemcached_util_ping("localhost", port, NULL)) { - fprintf(stderr, "Server on port %u already exists\n", x + TEST_PORT_BASE); + fprintf(stderr, "Server on port %u already exists\n", port); } else { status= system(buffer); fprintf(stderr, "STARTING SERVER: %s status:%d\n", buffer, status); } - count= sprintf(end_ptr, "localhost:%u,", x + TEST_PORT_BASE); + int count; + size_t remaining_length= sizeof(server_string_buffer) - (size_t)(end_ptr -server_string_buffer); + count= snprintf(end_ptr, remaining_length, "localhost:%u,", port); + + if ((size_t)count >= remaining_length || count < 0) + { + fprintf(stderr, "server names grew to be larger then buffer allowed\n"); + abort(); + } end_ptr+= count; } *end_ptr= 0; + + int *pids= calloc(construct->count, sizeof(int)); for (uint32_t x= 0; x < construct->count; x++) { - uint32_t counter= 3; - char buffer[1024]; /* Nothing special for number */ + char buffer[PATH_MAX]; /* Nothing special for number */ - snprintf(buffer, sizeof(buffer), "/tmp/%umemc.pid", x); + snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x); - while (--counter) + uint32_t counter= 3000; // Absurd, just to catch run away process + while (pids[x] <= 0 && --counter) { - int memcached_pid; - - FILE *file; - file= fopen(buffer, "r"); - if (file == NULL) + FILE *file= fopen(buffer, "r"); + if (file) { -#ifndef WIN32 - struct timespec req= { .tv_sec= 0, .tv_nsec= 5000 }; - nanosleep(&req, NULL); -#endif - continue; + char pid_buffer[1024]; + char *found= fgets(pid_buffer, sizeof(pid_buffer), file); + + if (found) + { + pids[x]= atoi(pid_buffer); + fclose(file); + + if (pids[x] > 0) + break; + } + fclose(file); } - char *found= fgets(buffer, sizeof(buffer), file); - if (!found) + global_sleep(); + } + + bool was_started= false; + if (pids[x] > 0) + { + counter= 30; + while (--counter) { - abort(); + if (kill(pids[x], 0) == 0) + { + was_started= true; + break; + } + global_sleep(); } - // Yes, we currently pitch this and don't make use of it. - memcached_pid= atoi(buffer); - fclose(file); } - + if (was_started == false) + { + fprintf(stderr, "Failed to open buffer %s(%d)\n", buffer, pids[x]); + for (uint32_t y= 0; y < construct->count; y++) + { + if (pids[y] > 0) + kill(pids[y], SIGTERM); + } + abort(); + } } + free(pids); construct->server_list= strdup(server_string_buffer); } @@ -155,13 +236,9 @@ void server_shutdown(server_startup_st *construct) { for (uint32_t x= 0; x < construct->count; x++) { - char buffer[1024]; /* Nothing special for number */ - sprintf(buffer, "cat /tmp/%umemc.pid | xargs kill", x); - /* We have to check the return value of this or the compiler will yell */ - int sys_ret= system(buffer); - assert(sys_ret != -1); - sprintf(buffer, "/tmp/%umemc.pid", x); - unlink(buffer); + char file_buffer[PATH_MAX]; /* Nothing special for number */ + snprintf(file_buffer, sizeof(file_buffer), PID_FILE_BASE, x); + kill_file(file_buffer); } free(construct->server_list); diff --git a/tests/test.h b/tests/test.h index 77aa5303..cc0fd78a 100644 --- a/tests/test.h +++ b/tests/test.h @@ -153,7 +153,7 @@ const char *test_strerror(test_return_t code); do \ { \ if (1) { \ - fprintf(stderr, "\nFailed in %s:%d: %s\n", __FILE__, __LINE__, #A);\ + fprintf(stderr, "\nFailed at %s:%d: %s\n", __FILE__, __LINE__, #A);\ create_core(); \ return TEST_FAILURE; \ } \ @@ -163,7 +163,17 @@ do \ do \ { \ if (! (A)) { \ - fprintf(stderr, "\nAssertion failed in %s:%d: %s\n", __FILE__, __LINE__, #A);\ + fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\ + create_core(); \ + return TEST_FAILURE; \ + } \ +} while (0) + +#define test_true_got(A,B) \ +do \ +{ \ + if (! (A)) { \ + fprintf(stderr, "\nAssertion failed at %s:%d: \"%s\" received \"%s\"\n", __FILE__, __LINE__, #A, (B));\ create_core(); \ return TEST_FAILURE; \ } \ @@ -173,7 +183,7 @@ do \ do \ { \ if ((A)) { \ - fprintf(stderr, "\nAssertion failed in %s:%d: %s\n", __FILE__, __LINE__, #A);\ + fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\ create_core(); \ return TEST_FAILURE; \ } \ diff --git a/unittests/include.am b/unittests/include.am index 6c217208..c1443418 100644 --- a/unittests/include.am +++ b/unittests/include.am @@ -10,7 +10,7 @@ unittests_unittests_SOURCES= \ unittests/main.cc \ unittests/strings.cc -unittests_unittest_CXXFLAGS= ${AM_CXXFLAGS} ${NO_WERROR} +unittests_unittests_CXXFLAGS= ${AM_CXXFLAGS} ${NO_WERROR} ${NO_EFF_CXX} unittests_unittests_LDADD= \ tests/libserver.la \ libmemcached/libmemcachedinternal.la \ diff --git a/unittests/strings.cc b/unittests/strings.cc index 921fe876..8728926b 100644 --- a/unittests/strings.cc +++ b/unittests/strings.cc @@ -8,9 +8,6 @@ #include "config.h" -#define __STDC_LIMIT_MACROS -#include - #include #include diff --git a/win32/wrappers.h b/win32/wrappers.h index 20218fd5..80b44651 100644 --- a/win32/wrappers.h +++ b/win32/wrappers.h @@ -12,6 +12,8 @@ #ifndef WIN32_WRAPPERS_H #define WIN32_WRAPPERS_H 1 +#include + /* * One of the Windows headers define interface as a macro, but that * is causing problems with the member named "interface" in some of the @@ -19,6 +21,10 @@ */ #undef interface +#undef malloc +#undef realloc + + /* * WinSock use a separate range for error codes. Let's just map to the * WinSock ones.