From db064ed6e69bdc04cf3d1cb5ef31441b7bce16cc Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: The simplejson module is bundled with python2.6 but renamed to json --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b1ff0bc..13d1b4b 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,8 @@ checkPython() { return fi PYTHON=$1 - if $PYTHON -c 'import simplejson' 2>/dev/null + if $PYTHON -c 'import json' 2>/dev/null \ + || $PYTHON -c 'import simplejson' 2>/dev/null then found_python=yes AC_MSG_RESULT($PYTHON) -- cgit v1.2.1 From 76e825b388c6c3b65ef238a245748f38d3f1c1fc Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: Move all includes of popt.h into common.h, which depends on it anyway --- tools/common.c | 2 -- tools/common.h | 2 ++ tools/consume.c | 2 -- tools/get.c | 2 -- tools/publish.c | 2 -- 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/common.c b/tools/common.c index 6a38a95..6c0e871 100644 --- a/tools/common.c +++ b/tools/common.c @@ -61,8 +61,6 @@ #include #include -#include - #include "common.h" extern char **environ; diff --git a/tools/common.h b/tools/common.h index 09a9242..8ea754c 100644 --- a/tools/common.h +++ b/tools/common.h @@ -50,6 +50,8 @@ #include +#include + #include #include diff --git a/tools/consume.c b/tools/consume.c index 40b61d1..b6bd5e2 100644 --- a/tools/consume.c +++ b/tools/consume.c @@ -53,8 +53,6 @@ #include #include -#include - #include "common.h" /* Convert a amqp_bytes_t to an escaped string form for printing. We diff --git a/tools/get.c b/tools/get.c index f746fd1..8f8e0d0 100644 --- a/tools/get.c +++ b/tools/get.c @@ -52,8 +52,6 @@ #include -#include - #include "common.h" static int do_get(amqp_connection_state_t conn, char *queue) diff --git a/tools/publish.c b/tools/publish.c index 21314b2..15d2386 100644 --- a/tools/publish.c +++ b/tools/publish.c @@ -54,8 +54,6 @@ #include #include -#include - #include "common.h" static void do_publish(amqp_connection_state_t conn, -- cgit v1.2.1 From 2347dc9977d3bf0c9ed19f7ed3a905eb4e65fa46 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: Add amqp_end_connection, which closes the socket and destroys the connection --- examples/amqp_bind.c | 3 +-- examples/amqp_consumer.c | 3 +-- examples/amqp_exchange_declare.c | 3 +-- examples/amqp_listen.c | 3 +-- examples/amqp_listenq.c | 3 +-- examples/amqp_producer.c | 3 +-- examples/amqp_sendstring.c | 3 +-- examples/amqp_unbind.c | 3 +-- librabbitmq/amqp.h | 1 + librabbitmq/amqp_connection.c | 9 +++++++++ tools/common.c | 11 +++++------ 11 files changed, 23 insertions(+), 22 deletions(-) diff --git a/examples/amqp_bind.c b/examples/amqp_bind.c index 697df2a..cf7c377 100644 --- a/examples/amqp_bind.c +++ b/examples/amqp_bind.c @@ -99,7 +99,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_consumer.c b/examples/amqp_consumer.c index aa33639..331fe1d 100644 --- a/examples/amqp_consumer.c +++ b/examples/amqp_consumer.c @@ -180,8 +180,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_exchange_declare.c b/examples/amqp_exchange_declare.c index 14bc163..32e71b0 100644 --- a/examples/amqp_exchange_declare.c +++ b/examples/amqp_exchange_declare.c @@ -94,7 +94,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_listen.c b/examples/amqp_listen.c index 0162ce6..c1401ee 100644 --- a/examples/amqp_listen.c +++ b/examples/amqp_listen.c @@ -187,8 +187,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_listenq.c b/examples/amqp_listenq.c index 9100dec..00dd2d7 100644 --- a/examples/amqp_listenq.c +++ b/examples/amqp_listenq.c @@ -171,8 +171,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_producer.c b/examples/amqp_producer.c index ac6eebc..94c529d 100644 --- a/examples/amqp_producer.c +++ b/examples/amqp_producer.c @@ -151,7 +151,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_sendstring.c b/examples/amqp_sendstring.c index 6e8e0b6..e669505 100644 --- a/examples/amqp_sendstring.c +++ b/examples/amqp_sendstring.c @@ -108,7 +108,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_unbind.c b/examples/amqp_unbind.c index 27df916..bc92efe 100644 --- a/examples/amqp_unbind.c +++ b/examples/amqp_unbind.c @@ -99,7 +99,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - amqp_destroy_connection(conn); - die_on_error(close(sockfd), "Closing socket"); + die_on_error(amqp_end_connection(conn), "Ending connection"); return 0; } diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index 139de5d..b67d6c8 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -310,6 +310,7 @@ extern int amqp_tune_connection(amqp_connection_state_t state, int heartbeat); int amqp_get_channel_max(amqp_connection_state_t state); extern void amqp_destroy_connection(amqp_connection_state_t state); +extern int amqp_end_connection(amqp_connection_state_t state); extern int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data, diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index 8623eed..7531fac 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -170,6 +170,15 @@ void amqp_destroy_connection(amqp_connection_state_t state) { free(state); } +int amqp_end_connection(amqp_connection_state_t state) { + int s = state->sockfd; + amqp_destroy_connection(state); + if (close(s) < 0) + return -errno; + else + return 0; +} + static void return_to_idle(amqp_connection_state_t state) { state->inbound_buffer.bytes = NULL; state->inbound_offset = 0; diff --git a/tools/common.c b/tools/common.c index 6c0e871..d4771ac 100644 --- a/tools/common.c +++ b/tools/common.c @@ -245,16 +245,15 @@ amqp_connection_state_t make_connection(void) void close_connection(amqp_connection_state_t conn) { - int s = amqp_get_sockfd(conn); - + int res; die_rpc(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "closing channel"); die_rpc(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "closing connection"); - amqp_destroy_connection(conn); - - if (close(s) < 0) - die_errno(errno, "closing socket"); + + res = amqp_end_connection(conn); + if (res < 0) + die_errno(-res, "closing connection"); } amqp_bytes_t read_all(int fd) -- cgit v1.2.1 From 7e8fbea4c9212774c101e33218d26a0dc992dc03 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: Remove uses of the GNU-specific %ll printf format modifier The MS C runtime doesn't support it. Use the C99 inttypes.h macros instead, which is supplied by MinGW. --- examples/amqp_consumer.c | 4 ++-- examples/amqp_producer.c | 8 ++++---- tests/test_tables.c | 28 ++++++++++++++-------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/amqp_consumer.c b/examples/amqp_consumer.c index 331fe1d..45db990 100644 --- a/examples/amqp_consumer.c +++ b/examples/amqp_consumer.c @@ -84,8 +84,8 @@ static void run(amqp_connection_state_t conn) if (now > next_summary_time) { int countOverInterval = received - previous_received; double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0); - printf("%lld ms: Received %d - %d since last report (%d Hz)\n", - (now - start_time) / 1000, received, countOverInterval, (int) intervalRate); + printf("%d ms: Received %d - %d since last report (%d Hz)\n", + (int)(now - start_time) / 1000, received, countOverInterval, (int) intervalRate); previous_received = received; previous_report_time = now; diff --git a/examples/amqp_producer.c b/examples/amqp_producer.c index 94c529d..61cc925 100644 --- a/examples/amqp_producer.c +++ b/examples/amqp_producer.c @@ -95,8 +95,8 @@ static void send_batch(amqp_connection_state_t conn, if (now > next_summary_time) { int countOverInterval = sent - previous_sent; double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0); - printf("%lld ms: Sent %d - %d since last report (%d Hz)\n", - (now - start_time) / 1000, sent, countOverInterval, (int) intervalRate); + printf("%d ms: Sent %d - %d since last report (%d Hz)\n", + (int)(now - start_time) / 1000, sent, countOverInterval, (int) intervalRate); previous_sent = sent; previous_report_time = now; @@ -111,10 +111,10 @@ static void send_batch(amqp_connection_state_t conn, { long long stop_time = now_microseconds(); - long long total_delta = stop_time - start_time; + int total_delta = stop_time - start_time; printf("PRODUCER - Message count: %d\n", message_count); - printf("Total time, milliseconds: %lld\n", total_delta / 1000); + printf("Total time, milliseconds: %d\n", total_delta / 1000); printf("Overall messages-per-second: %g\n", (message_count / (total_delta / 1000000.0))); } } diff --git a/tests/test_tables.c b/tests/test_tables.c index e620443..282aa8f 100644 --- a/tests/test_tables.c +++ b/tests/test_tables.c @@ -54,7 +54,8 @@ #include #include -#include +#include + #include #include #include @@ -75,13 +76,13 @@ static void dump_value(int indent, amqp_field_value_t v) { putchar(' '); switch (v.kind) { case AMQP_FIELD_KIND_BOOLEAN: puts(v.value.boolean ? "true" : "false"); break; - case AMQP_FIELD_KIND_I8: printf("%d\n", v.value.i8); break; - case AMQP_FIELD_KIND_U8: printf("%d\n", v.value.u8); break; - case AMQP_FIELD_KIND_I16: printf("%d\n", v.value.i16); break; - case AMQP_FIELD_KIND_U16: printf("%d\n", v.value.u16); break; - case AMQP_FIELD_KIND_I32: printf("%ld\n", (long) v.value.i32); break; - case AMQP_FIELD_KIND_U32: printf("%lu\n", (unsigned long) v.value.u32); break; - case AMQP_FIELD_KIND_I64: printf("%lld\n", (long long) v.value.i64); break; + case AMQP_FIELD_KIND_I8: printf("%"PRId8"\n", v.value.i8); break; + case AMQP_FIELD_KIND_U8: printf("%"PRIu8"\n", v.value.u8); break; + case AMQP_FIELD_KIND_I16: printf("%"PRId16"\n", v.value.i16); break; + case AMQP_FIELD_KIND_U16: printf("%"PRIu16"\n", v.value.u16); break; + case AMQP_FIELD_KIND_I32: printf("%"PRId32"\n", v.value.i32); break; + case AMQP_FIELD_KIND_U32: printf("%"PRIu32"\n", v.value.u32); break; + case AMQP_FIELD_KIND_I64: printf("%"PRId64"\n", v.value.i64); break; case AMQP_FIELD_KIND_F32: printf("%g\n", (double) v.value.f32); break; case AMQP_FIELD_KIND_F64: printf("%g\n", v.value.f64); break; case AMQP_FIELD_KIND_DECIMAL: @@ -106,7 +107,7 @@ static void dump_value(int indent, amqp_field_value_t v) { } } break; - case AMQP_FIELD_KIND_TIMESTAMP: printf("%llu\n", (unsigned long long) v.value.u64); break; + case AMQP_FIELD_KIND_TIMESTAMP: printf("%"PRIu64"\n", v.value.u64); break; case AMQP_FIELD_KIND_TABLE: putchar('\n'); { @@ -272,7 +273,7 @@ int main(int argc, char const * const *argv) { if ((sizeof(float) != 4) || (vi.i != 0x40490fdb)) { printf("*** ERROR: single floating point encoding does not work as expected\n"); printf("sizeof float is %lu, float is %g, u32 is 0x%08lx\n", - sizeof(float), + (unsigned long)sizeof(float), vi.f, (unsigned long) vi.i); } @@ -280,10 +281,9 @@ int main(int argc, char const * const *argv) { vl.d = M_PI; if ((sizeof(double) != 8) || (vl.l != 0x400921fb54442d18L)) { printf("*** ERROR: double floating point encoding does not work as expected\n"); - printf("sizeof double is %lu, double is %g, u64 is 0x%16llx\n", - sizeof(double), - vl.d, - (unsigned long long) vl.l); + printf("sizeof double is %lu, double is %g, u64 is 0x%16"PRIx64"\n", + (unsigned long)sizeof(double), + vl.d, vl.l); } test_table_codec(); -- cgit v1.2.1 From 66a0a987914626fc0ea86067a0ea1dd7a2bebdd2 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: Make error codes returned by librabbitmq functions opaque Windows doesn't generally use POSIX error codes, which poses a problem for librabbitmq's approach of using those error codes in its API. So make the librabbitmq error codes opaque: They are still be integers, but client code is not supposed to assume anything about them, except that they can be passed to a new amqp_error_string() function which returns the corresponding error message Internally, the error codes are either taken from a set of librabbitmq-specific values, or correspond to an OS-specific (POSIX or win32) error code, with a simple encoding to indicate which is which. --- examples/amqp_consumer.c | 10 +++++-- examples/amqp_listen.c | 6 ++-- examples/amqp_listenq.c | 6 ++-- examples/example_utils.c | 5 ++-- librabbitmq/amqp.h | 10 ++++++- librabbitmq/amqp_api.c | 35 +++++++++++++++++++++++ librabbitmq/amqp_connection.c | 10 +++---- librabbitmq/amqp_mem.c | 19 ++++++------- librabbitmq/amqp_private.h | 33 ++++++++++++++++------ librabbitmq/amqp_socket.c | 66 ++++++++++++++++++++++++------------------- librabbitmq/amqp_table.c | 16 +++++------ librabbitmq/codegen.py | 14 ++++----- tests/test_tables.c | 6 ++-- tools/common.c | 54 ++++++++++++++++------------------- tools/common.h | 6 ++-- tools/consume.c | 8 +++--- tools/publish.c | 3 +- 17 files changed, 185 insertions(+), 122 deletions(-) diff --git a/examples/amqp_consumer.c b/examples/amqp_consumer.c index 45db990..5dfbb33 100644 --- a/examples/amqp_consumer.c +++ b/examples/amqp_consumer.c @@ -94,7 +94,8 @@ static void run(amqp_connection_state_t conn) amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) return; + if (result < 0) + return; if (frame.frame_type != AMQP_FRAME_METHOD) continue; @@ -103,7 +104,9 @@ static void run(amqp_connection_state_t conn) continue; result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) return; + if (result < 0) + return; + if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); abort(); @@ -114,7 +117,8 @@ static void run(amqp_connection_state_t conn) while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) return; + if (result < 0) + return; if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); diff --git a/examples/amqp_listen.c b/examples/amqp_listen.c index c1401ee..412dcd5 100644 --- a/examples/amqp_listen.c +++ b/examples/amqp_listen.c @@ -125,7 +125,7 @@ int main(int argc, char const * const *argv) { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); printf("Result %d\n", result); - if (result <= 0) + if (result < 0) break; printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel); @@ -143,7 +143,7 @@ int main(int argc, char const * const *argv) { (int) d->routing_key.len, (char *) d->routing_key.bytes); result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) + if (result < 0) break; if (frame.frame_type != AMQP_FRAME_HEADER) { @@ -162,7 +162,7 @@ int main(int argc, char const * const *argv) { while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) + if (result < 0) break; if (frame.frame_type != AMQP_FRAME_BODY) { diff --git a/examples/amqp_listenq.c b/examples/amqp_listenq.c index 00dd2d7..1fc7db0 100644 --- a/examples/amqp_listenq.c +++ b/examples/amqp_listenq.c @@ -107,7 +107,7 @@ int main(int argc, char const * const *argv) { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); printf("Result %d\n", result); - if (result <= 0) + if (result < 0) break; printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel); @@ -125,7 +125,7 @@ int main(int argc, char const * const *argv) { (int) d->routing_key.len, (char *) d->routing_key.bytes); result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) + if (result < 0) break; if (frame.frame_type != AMQP_FRAME_HEADER) { @@ -144,7 +144,7 @@ int main(int argc, char const * const *argv) { while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); - if (result <= 0) + if (result < 0) break; if (frame.frame_type != AMQP_FRAME_BODY) { diff --git a/examples/example_utils.c b/examples/example_utils.c index 628572c..ae8f093 100644 --- a/examples/example_utils.c +++ b/examples/example_utils.c @@ -61,7 +61,7 @@ void die_on_error(int x, char const *context) { if (x < 0) { - fprintf(stderr, "%s: %s\n", context, strerror(-x)); + fprintf(stderr, "%s: %s\n", context, amqp_error_string(-x)); exit(1); } } @@ -76,8 +76,7 @@ void die_on_amqp_error(amqp_rpc_reply_t x, char const *context) { break; case AMQP_RESPONSE_LIBRARY_EXCEPTION: - fprintf(stderr, "%s: %s\n", context, - x.library_errno ? strerror(x.library_errno) : "(end-of-stream)"); + fprintf(stderr, "%s: %s\n", context, amqp_error_string(x.library_error)); break; case AMQP_RESPONSE_SERVER_EXCEPTION: diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index b67d6c8..58864e9 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -263,7 +263,7 @@ typedef enum amqp_response_type_enum_ { typedef struct amqp_rpc_reply_t_ { amqp_response_type_enum reply_type; amqp_method_t reply; - int library_errno; /* if AMQP_RESPONSE_LIBRARY_EXCEPTION, then 0 here means socket EOF */ + int library_error; /* if AMQP_RESPONSE_LIBRARY_EXCEPTION, then 0 here means socket EOF */ } amqp_rpc_reply_t; typedef enum amqp_sasl_method_enum_ { @@ -495,6 +495,14 @@ extern amqp_boolean_t amqp_data_in_buffer(amqp_connection_state_t state); */ extern amqp_rpc_reply_t amqp_get_rpc_reply(amqp_connection_state_t state); +/* + * Get the error string for the given error code. + * + * The returned string resides on the heap; the caller is responsible + * for freeing it. + */ +extern const char *amqp_error_string(int err); + #ifdef __cplusplus } #endif diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c index 91b0bf8..3a4440f 100644 --- a/librabbitmq/amqp_api.c +++ b/librabbitmq/amqp_api.c @@ -60,6 +60,41 @@ #include +static const char *client_error_strings[ERROR_MAX] = { + "could not allocate memory", /* ERROR_NO_MEMORY */ + "received bad AMQP data", /* ERROR_BAD_AQMP_DATA */ + "unknown AMQP class id", /* ERROR_UNKOWN_CLASS */ + "unknown AMQP method id", /* ERROR_UNKOWN_METHOD */ + "unknown host", /* ERROR_HOST_NOT_FOUND */ + "incompatible AMQP version", /* ERROR_INCOMPATIBLE_AMQP_VERSION */ + "connection closed unexpectedly", /* ERROR_CONNECTION_CLOSED */ +}; + +const char *amqp_error_string(int err) +{ + const char *str; + int category = (err & ERROR_CATEGORY_MASK); + err = (err & ~ERROR_CATEGORY_MASK); + + switch (category) { + case ERROR_CATEGORY_CLIENT: + if (err < 1 || err > ERROR_MAX) + str = "(undefined librabbitmq error)"; + else + str = client_error_strings[err - 1]; + break; + + case ERROR_CATEGORY_OS: + str = strerror(err); + break; + + default: + str = "(undefined error category)"; + } + + return strdup(str); +} + #define RPC_REPLY(replytype) \ (state->most_recent_api_result.reply_type == AMQP_RESPONSE_NORMAL \ ? (replytype *) state->most_recent_api_result.reply.decoded \ diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index 7531fac..4fdc71e 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -151,7 +151,7 @@ int amqp_tune_connection(amqp_connection_state_t state, newbuf = realloc(state->outbound_buffer.bytes, frame_max); if (newbuf == NULL) { amqp_destroy_connection(state); - return -ENOMEM; + return -ERROR_NO_MEMORY; } state->outbound_buffer.bytes = newbuf; @@ -174,7 +174,7 @@ int amqp_end_connection(amqp_connection_state_t state) { int s = state->sockfd; amqp_destroy_connection(state); if (close(s) < 0) - return -errno; + return -encoded_errno(); else return 0; } @@ -208,7 +208,7 @@ int amqp_handle_input(amqp_connection_state_t state, /* state->inbound_buffer.len is always nonzero, because it corresponds to frame_max, which is not permitted to be less than AMQP_FRAME_MIN_SIZE (currently 4096 bytes). */ - return -ENOMEM; + return -ERROR_NO_MEMORY; } state->state = CONNECTION_STATE_WAITING_FOR_HEADER; } @@ -255,7 +255,7 @@ int amqp_handle_input(amqp_connection_state_t state, /* Check frame end marker (footer) */ if (D_8(state->inbound_buffer, state->target_size - 1) != AMQP_FRAME_END) { - return -EINVAL; + return -ERROR_BAD_AMQP_DATA; } decoded_frame->channel = D_16(state->inbound_buffer, 1); @@ -401,7 +401,7 @@ static int inner_send_frame(amqp_connection_state_t state, break; default: - return -EINVAL; + abort(); } E_32(state->outbound_buffer, 3, *payload_len); diff --git a/librabbitmq/amqp_mem.c b/librabbitmq/amqp_mem.c index 6e52dc8..7783cbb 100644 --- a/librabbitmq/amqp_mem.c +++ b/librabbitmq/amqp_mem.c @@ -102,25 +102,24 @@ void empty_amqp_pool(amqp_pool_t *pool) { empty_blocklist(&pool->pages); } +/* Returns 1 on success, 0 on failure */ static int record_pool_block(amqp_pool_blocklist_t *x, void *block) { size_t blocklistlength = sizeof(void *) * (x->num_blocks + 1); if (x->blocklist == NULL) { x->blocklist = malloc(blocklistlength); - if (x->blocklist == NULL) { - return -ENOMEM; - } + if (x->blocklist == NULL) + return 0; } else { void *newbl = realloc(x->blocklist, blocklistlength); - if (newbl == NULL) { - return -ENOMEM; - } + if (newbl == NULL) + return 0; x->blocklist = newbl; } x->blocklist[x->num_blocks] = block; x->num_blocks++; - return 0; + return 1; } void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount) { @@ -135,9 +134,8 @@ void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount) { if (result == NULL) { return NULL; } - if (record_pool_block(&pool->large_blocks, result) != 0) { + if (!record_pool_block(&pool->large_blocks, result)) return NULL; - } return result; } @@ -156,9 +154,8 @@ void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount) { if (pool->alloc_block == NULL) { return NULL; } - if (record_pool_block(&pool->pages, pool->alloc_block) != 0) { + if (!record_pool_block(&pool->pages, pool->alloc_block)) return NULL; - } pool->next_page = pool->pages.num_blocks; } else { pool->alloc_block = pool->pages.blocklist[pool->next_page]; diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h index 3985619..f922933 100644 --- a/librabbitmq/amqp_private.h +++ b/librabbitmq/amqp_private.h @@ -57,6 +57,30 @@ extern "C" { #include /* ntohl, htonl, ntohs, htons */ +/* Error numbering: Because of differences in error numbering on + * different platforms, we want to keep error numbers opaque for + * client code. Internally, we encode the category of an error + * (i.e. where its number comes from) in the top bits of the number + * (assuming that an int has at least 32 bits). + */ +#define ERROR_CATEGORY_MASK (1 << 29) + +#define ERROR_CATEGORY_CLIENT (0 << 29) /* librabbitmq error codes */ +#define ERROR_CATEGORY_OS (1 << 29) /* OS-specific error codes */ + +/* librabbitmq error codes */ +#define ERROR_NO_MEMORY 1 +#define ERROR_BAD_AMQP_DATA 2 +#define ERROR_UNKNOWN_CLASS 3 +#define ERROR_UNKNOWN_METHOD 4 +#define ERROR_HOST_NOT_FOUND 5 +#define ERROR_INCOMPATIBLE_AMQP_VERSION 6 +#define ERROR_CONNECTION_CLOSED 7 +#define ERROR_MAX 7 + +/* Get the encoded form of errno */ +#define encoded_errno() (errno | ERROR_CATEGORY_OS) + /* * Connection states: * @@ -125,7 +149,7 @@ struct amqp_connection_state_t_ { amqp_rpc_reply_t most_recent_api_result; }; -#define CHECK_LIMIT(b, o, l, v) ({ if ((o + l) > (b).len) { return -EFAULT; } (v); }) +#define CHECK_LIMIT(b, o, l, v) ({ if ((o + l) > (b).len) { return -ERROR_BAD_AMQP_DATA; } (v); }) #define BUF_AT(b, o) (&(((uint8_t *) (b).bytes)[o])) #define D_8(b, o) CHECK_LIMIT(b, o, 1, * (uint8_t *) BUF_AT(b, o)) @@ -176,13 +200,6 @@ extern int amqp_encode_table(amqp_bytes_t encoded, #define AMQP_CHECK_RESULT(expr) AMQP_CHECK_RESULT_CLEANUP(expr, ) -#define AMQP_CHECK_EOF_RESULT(expr) \ - ({ \ - int _result = (expr); \ - if (_result <= 0) return _result; \ - _result; \ - }) - #ifndef NDEBUG extern void amqp_dump(void const *buffer, size_t len); #else diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index d16c319..8f3f05b 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -76,9 +76,8 @@ int amqp_open_socket(char const *hostname, struct hostent *he; he = gethostbyname(hostname); - if (he == NULL) { - return -ENOENT; - } + if (he == NULL) + return -ERROR_HOST_NOT_FOUND; addr.sin_family = AF_INET; addr.sin_port = htons(portnumber); @@ -86,7 +85,7 @@ int amqp_open_socket(char const *hostname, sockfd = socket(PF_INET, SOCK_STREAM, 0); if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - int result = -errno; + int result = -encoded_errno(); close(sockfd); return result; } @@ -183,10 +182,9 @@ static int wait_frame_inner(amqp_connection_state_t state, AMQP_CHECK_RESULT((result = amqp_handle_input(state, buffer, decoded_frame))); state->sock_inbound_offset += result; - if (decoded_frame->frame_type != 0) { + if (decoded_frame->frame_type != 0) /* Complete frame was read. Return it. */ - return 1; - } + return 0; /* Incomplete or ignored frame. Keep processing input. */ assert(result != 0); @@ -195,12 +193,11 @@ static int wait_frame_inner(amqp_connection_state_t state, result = read(state->sockfd, state->sock_inbound_buffer.bytes, state->sock_inbound_buffer.len); - if (result < 0) { - return -errno; - } - if (result == 0) { - /* EOF. */ - return 0; + if (result <= 0) { + if (result == 0) + return -ERROR_CONNECTION_CLOSED; + else + return -encoded_errno(); } state->sock_inbound_limit = result; @@ -218,7 +215,7 @@ int amqp_simple_wait_frame(amqp_connection_state_t state, state->last_queued_frame = NULL; } *decoded_frame = *f; - return 1; + return 0; } else { return wait_frame_inner(state, decoded_frame); } @@ -230,8 +227,10 @@ int amqp_simple_wait_method(amqp_connection_state_t state, amqp_method_t *output) { amqp_frame_t frame; - - AMQP_CHECK_EOF_RESULT(amqp_simple_wait_frame(state, &frame)); + int res = amqp_simple_wait_frame(state, &frame); + if (res < 0) + return res; + amqp_assert(frame.channel == expected_channel, "Expected 0x%08X method frame on channel %d, got frame on channel %d", expected_method, @@ -248,7 +247,7 @@ int amqp_simple_wait_method(amqp_connection_state_t state, expected_channel, frame.payload.method.id); *output = frame.payload.method; - return 1; + return 0; } int amqp_send_method(amqp_connection_state_t state, @@ -288,7 +287,7 @@ amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state, status = amqp_send_method(state, channel, request_id, decoded_request_method); if (status < 0) { result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; - result.library_errno = -status; + result.library_error = -status; return result; } @@ -297,9 +296,9 @@ amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state, retry: status = wait_frame_inner(state, &frame); - if (status <= 0) { + if (status < 0) { result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; - result.library_errno = -status; + result.library_error = -status; return result; } @@ -324,7 +323,7 @@ amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state, if (frame_copy == NULL || link == NULL) { result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; - result.library_errno = ENOMEM; + result.library_error = ERROR_NO_MEMORY; return result; } @@ -359,6 +358,7 @@ static int amqp_login_inner(amqp_connection_state_t state, amqp_sasl_method_enum sasl_method, va_list vl) { + int res; amqp_method_t method; uint32_t server_frame_max; uint16_t server_channel_max; @@ -366,12 +366,16 @@ static int amqp_login_inner(amqp_connection_state_t state, amqp_send_header(state); - AMQP_CHECK_EOF_RESULT(amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD, &method)); + res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD, + &method); + if (res < 0) + return res; + { amqp_connection_start_t *s = (amqp_connection_start_t *) method.decoded; if ((s->version_major != AMQP_PROTOCOL_VERSION_MAJOR) || (s->version_minor != AMQP_PROTOCOL_VERSION_MINOR)) { - return -EPROTOTYPE; + return -ERROR_INCOMPATIBLE_AMQP_VERSION; } /* TODO: check that our chosen SASL mechanism is in the list of @@ -383,7 +387,7 @@ static int amqp_login_inner(amqp_connection_state_t state, amqp_bytes_t response_bytes = sasl_response(&state->decoding_pool, sasl_method, vl); amqp_connection_start_ok_t s; if (response_bytes.bytes == NULL) { - return -ENOMEM; + return -ERROR_NO_MEMORY; } s = (amqp_connection_start_ok_t) { @@ -397,7 +401,11 @@ static int amqp_login_inner(amqp_connection_state_t state, amqp_release_buffers(state); - AMQP_CHECK_EOF_RESULT(amqp_simple_wait_method(state, 0, AMQP_CONNECTION_TUNE_METHOD, &method)); + res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_TUNE_METHOD, + &method); + if (res < 0) + return res; + { amqp_connection_tune_t *s = (amqp_connection_tune_t *) method.decoded; server_channel_max = s->channel_max; @@ -431,7 +439,7 @@ static int amqp_login_inner(amqp_connection_state_t state, amqp_release_buffers(state); - return 1; + return 0; } amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, @@ -449,11 +457,11 @@ amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, va_start(vl, sasl_method); status = amqp_login_inner(state, channel_max, frame_max, heartbeat, sasl_method, vl); - if (status <= 0) { + if (status < 0) { result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; result.reply.id = 0; result.reply.decoded = NULL; - result.library_errno = -status; + result.library_error = -status; return result; } @@ -481,6 +489,6 @@ amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, result.reply_type = AMQP_RESPONSE_NORMAL; result.reply.id = 0; result.reply.decoded = NULL; - result.library_errno = 0; + result.library_error = 0; return result; } diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c index 25c5932..db45588 100644 --- a/librabbitmq/amqp_table.c +++ b/librabbitmq/amqp_table.c @@ -86,7 +86,7 @@ static int amqp_decode_array(amqp_bytes_t encoded, int limit; if (entries == NULL) { - return -ENOMEM; + return -ERROR_NO_MEMORY; } offset += 4; @@ -99,7 +99,7 @@ static int amqp_decode_array(amqp_bytes_t encoded, newentries = realloc(entries, allocated_entries * sizeof(amqp_field_value_t)); if (newentries == NULL) { free(entries); - return -ENOMEM; + return -ERROR_NO_MEMORY; } entries = newentries; } @@ -117,7 +117,7 @@ static int amqp_decode_array(amqp_bytes_t encoded, if (output->entries == NULL && num_entries > 0) { /* NULL is legitimate if we requested a zero-length block. */ free(entries); - return -ENOMEM; + return -ERROR_NO_MEMORY; } memcpy(output->entries, entries, num_entries * sizeof(amqp_field_value_t)); @@ -140,7 +140,7 @@ int amqp_decode_table(amqp_bytes_t encoded, int limit; if (entries == NULL) { - return -ENOMEM; + return -ERROR_NO_MEMORY; } offset += 4; @@ -159,7 +159,7 @@ int amqp_decode_table(amqp_bytes_t encoded, newentries = realloc(entries, allocated_entries * sizeof(amqp_table_entry_t)); if (newentries == NULL) { free(entries); - return -ENOMEM; + return -ERROR_NO_MEMORY; } entries = newentries; } @@ -182,7 +182,7 @@ int amqp_decode_table(amqp_bytes_t encoded, if (output->entries == NULL && num_entries > 0) { /* NULL is legitimate if we requested a zero-length block. */ free(entries); - return -ENOMEM; + return -ERROR_NO_MEMORY; } memcpy(output->entries, entries, num_entries * sizeof(amqp_table_entry_t)); @@ -274,7 +274,7 @@ static int amqp_decode_field_value(amqp_bytes_t encoded, case AMQP_FIELD_KIND_VOID: break; default: - return -EINVAL; + return -ERROR_BAD_AMQP_DATA; } *offsetptr = offset; @@ -410,7 +410,7 @@ static int amqp_encode_field_value(amqp_bytes_t encoded, case AMQP_FIELD_KIND_VOID: break; default: - return -EINVAL; + abort(); } *offsetptr = offset; diff --git a/librabbitmq/codegen.py b/librabbitmq/codegen.py index 7aea9f4..9a82fbe 100644 --- a/librabbitmq/codegen.py +++ b/librabbitmq/codegen.py @@ -170,7 +170,7 @@ def genErl(spec): if m.arguments: print " %s *m = (%s *) amqp_pool_alloc(pool, sizeof(%s));" % \ (m.structName(), m.structName(), m.structName()) - print " if (m == NULL) { return -ENOMEM; }" + print " if (m == NULL) { return -ERROR_NO_MEMORY; }" else: print " %s *m = NULL; /* no fields */" % (m.structName(),) bitindex = None @@ -197,7 +197,7 @@ def genErl(spec): print " case %d: {" % (c.index,) print " %s *p = (%s *) amqp_pool_alloc(pool, sizeof(%s));" % \ (c.structName(), c.structName(), c.structName()) - print " if (p == NULL) { return -ENOMEM; }" + print " if (p == NULL) { return -ERROR_NO_MEMORY; }" print " p->_flags = flags;" for f in c.fields: if spec.resolveDomain(f.domain) == 'bit': @@ -261,8 +261,6 @@ def genErl(spec): print '#include ' print '#include ' print '#include ' - print '#include ' - print '#include /* ntohl, htonl, ntohs, htons */' print print '#include "amqp.h"' print '#include "amqp_framing.h"' @@ -317,7 +315,7 @@ int amqp_decode_method(amqp_method_number_t methodNumber, switch (methodNumber) {""" for m in methods: genDecodeMethodFields(m) - print """ default: return -ENOENT; + print """ default: return -ERROR_UNKNOWN_METHOD; } }""" @@ -343,7 +341,7 @@ int amqp_decode_properties(uint16_t class_id, switch (class_id) {""" for c in spec.allClasses(): genDecodeProperties(c) - print """ default: return -ENOENT; + print """ default: return -ERROR_UNKNOWN_CLASS; } }""" @@ -358,7 +356,7 @@ int amqp_encode_method(amqp_method_number_t methodNumber, switch (methodNumber) {""" for m in methods: genEncodeMethodFields(m) - print """ default: return -ENOENT; + print """ default: return -ERROR_UNKNOWN_METHOD; } }""" @@ -390,7 +388,7 @@ int amqp_encode_properties(uint16_t class_id, switch (class_id) {""" for c in spec.allClasses(): genEncodeProperties(c) - print """ default: return -ENOENT; + print """ default: return -ERROR_UNKNOWN_CLASS; } }""" diff --git a/tests/test_tables.c b/tests/test_tables.c index 282aa8f..1a0652a 100644 --- a/tests/test_tables.c +++ b/tests/test_tables.c @@ -210,7 +210,8 @@ static void test_table_codec(void) { int decoding_offset = 0; result = amqp_decode_table(decoding_bytes, &pool, &decoded, &decoding_offset); if (result < 0) { - printf("Table decoding failed: %d (%s)\n", result, strerror(-result)); + printf("Table decoding failed: %d (%s)\n", result, + amqp_error_string(-result)); abort(); } printf("BBBBBBBBBB\n"); @@ -228,7 +229,8 @@ static void test_table_codec(void) { result = amqp_encode_table(encoding_result, &table, &offset); if (result < 0) { - printf("Table encoding failed: %d (%s)\n", result, strerror(-result)); + printf("Table encoding failed: %d (%s)\n", result, + amqp_error_string(-result)); abort(); } diff --git a/tools/common.c b/tools/common.c index d4771ac..ec24085 100644 --- a/tools/common.c +++ b/tools/common.c @@ -84,11 +84,24 @@ void die_errno(int err, const char *fmt, ...) va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - fprintf(stderr, ": %s\n", strerror(err)); + fprintf(stderr, ": %s\n", strerror(errno)); exit(1); } -char *amqp_server_exception_string(amqp_rpc_reply_t r) +void die_amqp_error(int err, const char *fmt, ...) +{ + if (err <= 0) + return; + + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, ": %s\n", amqp_error_string(err)); + exit(1); +} + +const char *amqp_server_exception_string(amqp_rpc_reply_t r) { int res; char *s; @@ -123,26 +136,17 @@ char *amqp_server_exception_string(amqp_rpc_reply_t r) return res >= 0 ? s : NULL; } -char *amqp_rpc_reply_string(amqp_rpc_reply_t r) +const char *amqp_rpc_reply_string(amqp_rpc_reply_t r) { - const char *s; - switch (r.reply_type) { case AMQP_RESPONSE_NORMAL: - s = "normal response"; - break; + return strdup("normal response"); case AMQP_RESPONSE_NONE: - s = "missing RPC reply type"; - break; + return strdup("missing RPC reply type"); case AMQP_RESPONSE_LIBRARY_EXCEPTION: - if (r.library_errno) - s = strerror(r.library_errno); - else - s = "end of stream"; - - break; + return amqp_error_string(r.library_error); case AMQP_RESPONSE_SERVER_EXCEPTION: return amqp_server_exception_string(r); @@ -150,8 +154,6 @@ char *amqp_rpc_reply_string(amqp_rpc_reply_t r) default: abort(); } - - return strdup(s); } void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) @@ -220,13 +222,8 @@ amqp_connection_state_t make_connection(void) } s = amqp_open_socket(host, port ? port : 5672); - if (s < 0) { - if (s == -ENOENT) - die("unknown host %s", host); - else - die_errno(-s, "opening socket to %s", amqp_server); - } - + die_amqp_error(-s, "opening socket to %s", amqp_server); + set_cloexec(s); conn = amqp_new_connection(); @@ -252,8 +249,7 @@ void close_connection(amqp_connection_state_t conn) "closing connection"); res = amqp_end_connection(conn); - if (res < 0) - die_errno(-res, "closing connection"); + die_amqp_error(-res, "closing connection"); } amqp_bytes_t read_all(int fd) @@ -304,8 +300,7 @@ void copy_body(amqp_connection_state_t conn, int fd) amqp_frame_t frame; int res = amqp_simple_wait_frame(conn, &frame); - if (res < 0) - die_errno(-res, "waiting for header frame"); + die_amqp_error(-res, "waiting for header frame"); if (frame.frame_type != AMQP_FRAME_HEADER) die("expected header, got frame type 0x%X", frame.frame_type); @@ -313,8 +308,7 @@ void copy_body(amqp_connection_state_t conn, int fd) body_remaining = frame.payload.properties.body_size; while (body_remaining) { res = amqp_simple_wait_frame(conn, &frame); - if (res < 0) - die_errno(-res, "waiting for body frame"); + die_amqp_error(-res, "waiting for body frame"); if (frame.frame_type != AMQP_FRAME_BODY) die("expected body, got frame type 0x%X", frame.frame_type); diff --git a/tools/common.h b/tools/common.h index 8ea754c..b3d8ab9 100644 --- a/tools/common.h +++ b/tools/common.h @@ -55,13 +55,15 @@ #include #include -extern char *amqp_server_exception_string(amqp_rpc_reply_t r); -extern char *amqp_rpc_reply_string(amqp_rpc_reply_t r); +extern const char *amqp_server_exception_string(amqp_rpc_reply_t r); +extern const char *amqp_rpc_reply_string(amqp_rpc_reply_t r); extern void die(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern void die_errno(int err, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +extern void die_amqp_error(int err, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); extern void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/tools/consume.c b/tools/consume.c index b6bd5e2..9999960 100644 --- a/tools/consume.c +++ b/tools/consume.c @@ -155,8 +155,7 @@ static void do_consume(amqp_connection_state_t conn, amqp_bytes_t queue, struct pipeline pl; uint64_t delivery_tag; int res = amqp_simple_wait_frame(conn, &frame); - if (res < 0) - die_errno(-res, "waiting for header frame"); + die_amqp_error(res, "waiting for header frame"); if (frame.frame_type != AMQP_FRAME_METHOD || frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) @@ -170,8 +169,9 @@ static void do_consume(amqp_connection_state_t conn, amqp_bytes_t queue, copy_body(conn, pl.infd); if (finish_pipeline(&pl) && !no_ack) - die_errno(-amqp_basic_ack(conn, 1, delivery_tag, 0), - "basic.ack"); + die_amqp_error(amqp_basic_ack(conn, 1, delivery_tag, + 0), + "basic.ack"); amqp_maybe_release_buffers(conn); } diff --git a/tools/publish.c b/tools/publish.c index 15d2386..0917dae 100644 --- a/tools/publish.c +++ b/tools/publish.c @@ -64,8 +64,7 @@ static void do_publish(amqp_connection_state_t conn, cstring_bytes(exchange), cstring_bytes(routing_key), 0, 0, props, body); - if (res != 0) - die_errno(-res, "basic.publish"); + die_amqp_error(res, "basic.publish"); } int main(int argc, const char **argv) -- cgit v1.2.1 From bf06e86975f474da30e9c74faff7a99b0734e00e Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: Propagate write and writev errors correctly in amqp_send_frame --- librabbitmq/amqp_connection.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index 4fdc71e..a264ad3 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -428,16 +428,14 @@ int amqp_send_frame(amqp_connection_state_t state, amqp_frame_t const *frame) { amqp_bytes_t encoded; - int payload_len; - int separate_body; + int payload_len, res; - separate_body = inner_send_frame(state, frame, &encoded, &payload_len); - switch (separate_body) { + res = inner_send_frame(state, frame, &encoded, &payload_len); + switch (res) { case 0: - AMQP_CHECK_RESULT(write(state->sockfd, - state->outbound_buffer.bytes, - payload_len + (HEADER_SIZE + FOOTER_SIZE))); - return 0; + res = write(state->sockfd, state->outbound_buffer.bytes, + payload_len + (HEADER_SIZE + FOOTER_SIZE)); + break; case 1: { struct iovec iov[3]; @@ -449,13 +447,18 @@ int amqp_send_frame(amqp_connection_state_t state, iov[2].iov_base = &frame_end_byte; assert(FOOTER_SIZE == 1); iov[2].iov_len = FOOTER_SIZE; - AMQP_CHECK_RESULT(writev(state->sockfd, &iov[0], 3)); - return 0; + res = writev(state->sockfd, &iov[0], 3); + break; } default: - return separate_body; + return res; } + + if (res < 0) + return -encoded_errno(); + else + return 0; } int amqp_send_frame_to(amqp_connection_state_t state, -- cgit v1.2.1 From 1c198e88d1a0c74676f8d6fade99b2531ba815b8 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 30 May 2010 23:31:40 +0100 Subject: A Windows port, using MinGW/MSYS --- README.windows | 77 ++++++++++++++++ configure.ac | 27 +++++- etc/install-mingw.sh | 69 ++++++++++++++ librabbitmq/Makefile.am | 8 +- librabbitmq/amqp_api.c | 6 +- librabbitmq/amqp_connection.c | 20 ++--- librabbitmq/amqp_mem.c | 1 - librabbitmq/amqp_private.h | 5 +- librabbitmq/amqp_socket.c | 36 ++++---- librabbitmq/amqp_table.c | 2 +- librabbitmq/codegen.py | 1 + librabbitmq/unix/socket.c | 85 ++++++++++++++++++ librabbitmq/unix/socket.h | 80 +++++++++++++++++ librabbitmq/windows/socket.c | 88 ++++++++++++++++++ librabbitmq/windows/socket.h | 92 +++++++++++++++++++ tests/Makefile.am | 2 +- tools/Makefile.am | 16 ++-- tools/common.c | 59 +----------- tools/common.h | 8 -- tools/consume.c | 1 + tools/unix/process.c | 100 +++++++++++++++++++++ tools/unix/process.h | 57 ++++++++++++ tools/windows/compat.c | 73 +++++++++++++++ tools/windows/compat.h | 51 +++++++++++ tools/windows/process.c | 204 ++++++++++++++++++++++++++++++++++++++++++ tools/windows/process.h | 59 ++++++++++++ 26 files changed, 1113 insertions(+), 114 deletions(-) create mode 100644 README.windows create mode 100755 etc/install-mingw.sh create mode 100644 librabbitmq/unix/socket.c create mode 100644 librabbitmq/unix/socket.h create mode 100644 librabbitmq/windows/socket.c create mode 100644 librabbitmq/windows/socket.h create mode 100644 tools/unix/process.c create mode 100644 tools/unix/process.h create mode 100644 tools/windows/compat.c create mode 100644 tools/windows/compat.h create mode 100644 tools/windows/process.c create mode 100644 tools/windows/process.h diff --git a/README.windows b/README.windows new file mode 100644 index 0000000..1a20c00 --- /dev/null +++ b/README.windows @@ -0,0 +1,77 @@ +# rabbitmq-c and Windows + +rabbitmq-c can now be built on Windows using the MinGW/MSYS ports of +the GNU toolchain and miscellaneous utilities. This includes the +example programs and tools. + +The results are native Windows DLLs and EXEs, and can be used without +having MinGW installed. But the librabbitmq header files currently +use GCC extensions, and for this reason it is still not possible to +use Microsoft's C/C++ to build applications against the librabbitmq +DLL. Hopefully this will get fixed before long. + + +# Building rabbitmq-c + +rabbitmq-c is built on Windows using MinGW and MSYS. In brief, MinGW +is a native port of the GNU toolchain to Windows; MSYS is a set of +ports of common GNU utilities to run under Windows, so that typical +autotools-based builds will work there. MinGW/MSYS can be used to +build native Windows applications and DLLs, which do not depend on +MinGW/MSYS to run. + +So to build rabbitmq-c on Windows, you need to download and install +the relevant parts of MinGW/MSYS. This can be a fairly time consuming +process - there are about 20 files to be downloaded and unpacked. To +make it easier, we provide a bash script that automates this process, +in rabbitmq-c/etc/install-mingw.sh. You can run this cygwin, or under +Linux and copy the results over or put them on a shared drive. Some +MinGW packages are .tar.lzma files, so it requires a system with xz +and a tar that supports the -J option, which probably rules out OSX. + +Run install-mingw.sh specifying the destination directory, e.g. + + $ etc/install-mingw.sh /tmp/mingw + +Python is needed for the rabbitmq-c build, so you will also need to +install python under Windows. The Windows installer from python.org +will do fine. + +You will need to get the rabbitmq-c and rabbitmq-codegen source code. +If you are getting it from Mercurial, you will need to run "autoreconf +-i" within rabbitmq-c somewhere other than under MinGW first (perhaps +this can be done under MinGW/MSYS, but the packages installed by +install-mingw.sh are not sufficient). + +Open a cmd window, and ensure that both the MinGW bin directory and the python install directory are in the path, e.g. + + C:\>set PATH=%PATH%;C:\mingw\bin;C:\Python26 + +Then start bash, and run the following mount command (substituting the +Windows path of your MinGW install): + + C:\>bash + bash-3.1$ mount 'C:\mingw' /mingw + +Then go to the rabbitmq-c directory, and configure and make as normal: + + bash-3.1$ ./configure && make + [...] + + +# Running the tools without mingw + +You can run the resulting tools EXEs without the rest of MinGW. To do +this, copy the following files into a directory: + +- rabbitmq-c/tools/.libs/*.exe + +- rabbitmq-c/librabbitmq/.libs/librabbitmq-0.dll + +- /lib/libpopt-0.dll + +- /lib/libiconv-2.dll + +- /lib/libintl-8.dll + + diff --git a/configure.ac b/configure.ac index 13d1b4b..f7cfb74 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,7 @@ AC_GNU_SOURCE AC_PROG_CC dnl Library checks +AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl Header-file checks @@ -21,6 +22,26 @@ if test "x$GCC" = "xyes"; then fi fi +dnl Detect the kind of host we're building for +AC_CANONICAL_HOST +windows=no +case "${host}" in +*-*-mingw*) + windows=yes + ;; +esac +AM_CONDITIONAL(WINDOWS, test "x$windows" = xyes) +AS_IF([test "x$windows" = xyes], + [AC_DEFINE([WINDOWS], [1], [Define to 1 if on Windows.])] +) + +dnl Decide which API abstraction layer to use +PLATFORM_DIR=unix +if test "x$windows" = xyes ; then + PLATFORM_DIR=windows +fi +AC_SUBST(PLATFORM_DIR) + dnl Enable -m64 if we were asked to do so AC_ARG_ENABLE(64-bit, [ --enable-64-bit produce 64-bit library], @@ -65,8 +86,12 @@ AC_SUBST(AMQP_CODEGEN_DIR) AC_SUBST(AMQP_SPEC_JSON_PATH) AC_SUBST(PYTHON) -# Check for libpopt, which we need to build the tools +dnl Decide which extra win32 libs we need +EXTRA_LIBS= +AS_IF([test "x$windows" = xyes], [EXTRA_LIBS="-lws2_32 $EXTRA_LIBS"]) +AC_SUBST(EXTRA_LIBS) +dnl Check for libpopt, which we need to build the tools AC_ARG_WITH([popt], [AS_HELP_STRING([--with-popt], [use the popt library. Needed for tools.])], [], diff --git a/etc/install-mingw.sh b/etc/install-mingw.sh new file mode 100755 index 0000000..de953d4 --- /dev/null +++ b/etc/install-mingw.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +if [ $# -ne 1 ] ; then + echo "usage: install-mingw.sh " 1>&2 + exit 1 +fi + +unpack_dir=$1 + +if [ -eb "$unpack_dir" ] ; then + echo "Destination directory already exists; please delete it if you are sure" 1>&2 + exit 1 +fi + +set -e + +download_dir=/tmp/install-mingw.$$ +mkdir -p $download_dir $unpack_dir + +while read f ; do + wget -P $download_dir -N http://switch.dl.sourceforge.net/project/mingw/$f +done <&2 + exit 1 + ;; + esac +done + +rm -rf $download_dir diff --git a/librabbitmq/Makefile.am b/librabbitmq/Makefile.am index b4c8843..9211c8f 100644 --- a/librabbitmq/Makefile.am +++ b/librabbitmq/Makefile.am @@ -1,15 +1,19 @@ lib_LTLIBRARIES = librabbitmq.la -librabbitmq_la_SOURCES = amqp_mem.c amqp_table.c amqp_connection.c amqp_socket.c amqp_debug.c amqp_api.c +AM_CFLAGS = -I$(PLATFORM_DIR) +librabbitmq_la_SOURCES = amqp_mem.c amqp_table.c amqp_connection.c amqp_socket.c amqp_debug.c amqp_api.c $(PLATFORM_DIR)/socket.c +librabbitmq_la_LDFLAGS = -no-undefined nodist_librabbitmq_la_SOURCES = amqp_framing.c include_HEADERS = amqp_framing.h amqp.h -noinst_HEADERS = amqp_private.h +noinst_HEADERS = amqp_private.h $(PLATFORM_DIR)/socket.h BUILT_SOURCES = amqp_framing.h amqp_framing.c CLEANFILES = amqp_framing.h amqp_framing.c EXTRA_DIST = codegen.py CODEGEN_PY=$(srcdir)/codegen.py +LDADD=$(EXTRA_LIBS) + amqp_framing.h: $(AMQP_SPEC_JSON_PATH) $(CODEGEN_PY) PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) header $< $@ diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c index 3a4440f..9918819 100644 --- a/librabbitmq/amqp_api.c +++ b/librabbitmq/amqp_api.c @@ -52,7 +52,6 @@ #include #include #include -#include #include "amqp.h" #include "amqp_framing.h" @@ -85,9 +84,8 @@ const char *amqp_error_string(int err) break; case ERROR_CATEGORY_OS: - str = strerror(err); - break; - + return amqp_os_error_string(err); + default: str = "(undefined error category)"; } diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index a264ad3..63af96a 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -52,17 +52,13 @@ #include #include #include -#include - -#include -#include -#include +#include #include "amqp.h" #include "amqp_framing.h" #include "amqp_private.h" -#include +#include "socket.h" #define INITIAL_FRAME_POOL_PAGE_SIZE 65536 #define INITIAL_DECODING_POOL_PAGE_SIZE 131072 @@ -173,8 +169,8 @@ void amqp_destroy_connection(amqp_connection_state_t state) { int amqp_end_connection(amqp_connection_state_t state) { int s = state->sockfd; amqp_destroy_connection(state); - if (close(s) < 0) - return -encoded_errno(); + if (socket_close(s) < 0) + return -encoded_socket_errno(); else return 0; } @@ -433,8 +429,8 @@ int amqp_send_frame(amqp_connection_state_t state, res = inner_send_frame(state, frame, &encoded, &payload_len); switch (res) { case 0: - res = write(state->sockfd, state->outbound_buffer.bytes, - payload_len + (HEADER_SIZE + FOOTER_SIZE)); + res = socket_write(state->sockfd, state->outbound_buffer.bytes, + payload_len + (HEADER_SIZE + FOOTER_SIZE)); break; case 1: { @@ -447,7 +443,7 @@ int amqp_send_frame(amqp_connection_state_t state, iov[2].iov_base = &frame_end_byte; assert(FOOTER_SIZE == 1); iov[2].iov_len = FOOTER_SIZE; - res = writev(state->sockfd, &iov[0], 3); + res = socket_writev(state->sockfd, &iov[0], 3); break; } @@ -456,7 +452,7 @@ int amqp_send_frame(amqp_connection_state_t state, } if (res < 0) - return -encoded_errno(); + return -encoded_socket_errno(); else return 0; } diff --git a/librabbitmq/amqp_mem.c b/librabbitmq/amqp_mem.c index 7783cbb..021151a 100644 --- a/librabbitmq/amqp_mem.c +++ b/librabbitmq/amqp_mem.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include "amqp.h" diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h index f922933..7206ae5 100644 --- a/librabbitmq/amqp_private.h +++ b/librabbitmq/amqp_private.h @@ -55,8 +55,6 @@ extern "C" { #endif -#include /* ntohl, htonl, ntohs, htons */ - /* Error numbering: Because of differences in error numbering on * different platforms, we want to keep error numbers opaque for * client code. Internally, we encode the category of an error @@ -78,8 +76,7 @@ extern "C" { #define ERROR_CONNECTION_CLOSED 7 #define ERROR_MAX 7 -/* Get the encoded form of errno */ -#define encoded_errno() (errno | ERROR_CATEGORY_OS) +extern const char *amqp_os_error_string(int err); /* * Connection states: diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index 8f3f05b..6425c34 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -52,29 +52,27 @@ #include #include #include -#include #include +#include #include "amqp.h" #include "amqp_framing.h" #include "amqp_private.h" -#include -#include -#include -#include -#include -#include +#include "socket.h" -#include int amqp_open_socket(char const *hostname, int portnumber) { - int sockfd; + int sockfd, res; struct sockaddr_in addr; struct hostent *he; + res = socket_init(); + if (res) + return res; + he = gethostbyname(hostname); if (he == NULL) return -ERROR_HOST_NOT_FOUND; @@ -83,11 +81,11 @@ int amqp_open_socket(char const *hostname, addr.sin_port = htons(portnumber); addr.sin_addr.s_addr = * (uint32_t *) he->h_addr_list[0]; - sockfd = socket(PF_INET, SOCK_STREAM, 0); - if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - int result = -encoded_errno(); - close(sockfd); - return result; + sockfd = socket_socket(PF_INET, SOCK_STREAM, 0); + if (socket_connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + res = -encoded_socket_errno(); + socket_close(sockfd); + return res; } return sockfd; @@ -107,7 +105,7 @@ static char *header() { } int amqp_send_header(amqp_connection_state_t state) { - return write(state->sockfd, header(), 8); + return socket_write(state->sockfd, header(), 8); } int amqp_send_header_to(amqp_connection_state_t state, @@ -190,14 +188,14 @@ static int wait_frame_inner(amqp_connection_state_t state, assert(result != 0); } - result = read(state->sockfd, - state->sock_inbound_buffer.bytes, - state->sock_inbound_buffer.len); + result = socket_read(state->sockfd, + state->sock_inbound_buffer.bytes, + state->sock_inbound_buffer.len); if (result <= 0) { if (result == 0) return -ERROR_CONNECTION_CLOSED; else - return -encoded_errno(); + return -encoded_socket_errno(); } state->sock_inbound_limit = result; diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c index db45588..3f5eb61 100644 --- a/librabbitmq/amqp_table.c +++ b/librabbitmq/amqp_table.c @@ -52,10 +52,10 @@ #include #include #include -#include #include "amqp.h" #include "amqp_private.h" +#include "socket.h" #include diff --git a/librabbitmq/codegen.py b/librabbitmq/codegen.py index 9a82fbe..6b38666 100644 --- a/librabbitmq/codegen.py +++ b/librabbitmq/codegen.py @@ -265,6 +265,7 @@ def genErl(spec): print '#include "amqp.h"' print '#include "amqp_framing.h"' print '#include "amqp_private.h"' + print '#include "socket.h"' print """ char const *amqp_constant_name(int constantNumber) { diff --git a/librabbitmq/unix/socket.c b/librabbitmq/unix/socket.c new file mode 100644 index 0000000..51db413 --- /dev/null +++ b/librabbitmq/unix/socket.c @@ -0,0 +1,85 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include +#include + +#include "amqp.h" +#include "amqp_private.h" +#include "socket.h" + +int socket_socket(int domain, int type, int proto) +{ + int flags; + + int s = socket(domain, type, proto); + if (s < 0) + return s; + + /* Always enable CLOEXEC on the socket */ + flags = fcntl(s, F_GETFD); + if (flags == -1 + || fcntl(s, F_SETFD, (long)(flags | FD_CLOEXEC)) == -1) { + int e = errno; + close(s); + errno = e; + return -1; + } + + return s; +} + +const char *amqp_os_error_string(int err) +{ + return strdup(strerror(err)); +} diff --git a/librabbitmq/unix/socket.h b/librabbitmq/unix/socket.h new file mode 100644 index 0000000..d7295c3 --- /dev/null +++ b/librabbitmq/unix/socket.h @@ -0,0 +1,80 @@ +#ifndef librabbitmq_unix_socket_h +#define librabbitmq_unix_socket_h + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include +#include +#include +#include + +static inline int socket_init(void) +{ + return 0; +} + +extern int socket_socket(int domain, int type, int proto); + +#define socket_connect connect +#define socket_close close +#define socket_read read +#define socket_write write +#define socket_writev writev + +static inline int encoded_socket_errno() +{ + return errno | ERROR_CATEGORY_OS; +} + +#endif diff --git a/librabbitmq/windows/socket.c b/librabbitmq/windows/socket.c new file mode 100644 index 0000000..f809f62 --- /dev/null +++ b/librabbitmq/windows/socket.c @@ -0,0 +1,88 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include +#include + +#include "amqp.h" +#include "amqp_private.h" +#include "socket.h" + +static int called_wsastartup; + +int socket_init(void) +{ + if (!called_wsastartup) { + WSADATA data; + int res = WSAStartup(0x0202, &data); + if (res) + return -res; + + called_wsastartup = 1; + } + + return 0; +} + +const char *amqp_os_error_string(int err) +{ + char *msg, *copy; + + if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&msg, 0, NULL)) + return strdup("(error retrieving Windows error message)"); + + copy = strdup(msg); + LocalFree(msg); + return copy; +} diff --git a/librabbitmq/windows/socket.h b/librabbitmq/windows/socket.h new file mode 100644 index 0000000..bff6efc --- /dev/null +++ b/librabbitmq/windows/socket.h @@ -0,0 +1,92 @@ +#ifndef librabbitmq_windows_socket_h +#define librabbitmq_windows_socket_h + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include + +extern int socket_init(void); + +#define socket_socket socket +#define socket_connect connect +#define socket_close closesocket + +static inline int socket_read(int sock, void *buf, size_t count) +{ + return recv(sock, buf, count, 0); +} + +static inline int socket_write(int sock, void *buf, size_t count) +{ + return send(sock, buf, count, 0); +} + +/* same as WSABUF */ +struct iovec { + u_long iov_len; + char *iov_base; +}; + +static inline int socket_writev(int sock, struct iovec *iov, int nvecs) +{ + DWORD ret; + if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) + return ret; + else + return -1; +} + +static inline int encoded_socket_errno() +{ + return WSAGetLastError() | ERROR_CATEGORY_OS; +} + +#endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 1ac6faf..7c8a4fe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ noinst_PROGRAMS = test_tables -AM_CFLAGS = -I$(top_srcdir)/librabbitmq +AM_CFLAGS = -I$(top_srcdir)/librabbitmq -I$(top_srcdir)/librabbitmq/$(PLATFORM_DIR) AM_LDFLAGS = $(top_builddir)/librabbitmq/librabbitmq.la diff --git a/tools/Makefile.am b/tools/Makefile.am index 307fbd2..3f9fd6a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,15 +1,21 @@ bin_PROGRAMS = amqp-publish amqp-get amqp-consume -AM_CFLAGS = -I$(top_srcdir)/librabbitmq +AM_CFLAGS = -I$(top_srcdir)/librabbitmq -I$(PLATFORM_DIR) AM_LDFLAGS = $(top_builddir)/librabbitmq/librabbitmq.la LDADD=$(LIBPOPT) -noinst_HEADERS = common.h +noinst_HEADERS = common.h $(PLATFORM_DIR)/process.h -amqp_publish_SOURCES = publish.c common.c -amqp_get_SOURCES = get.c common.c -amqp_consume_SOURCES = consume.c common.c +COMMON_SOURCES = common.c + +if WINDOWS +COMMON_SOURCES += windows/compat.c +endif + +amqp_publish_SOURCES = publish.c $(COMMON_SOURCES) +amqp_get_SOURCES = get.c $(COMMON_SOURCES) +amqp_consume_SOURCES = consume.c $(PLATFORM_DIR)/process.c $(COMMON_SOURCES) if TOOLS_DOC man_MANS = doc/amqp-publish.1 doc/amqp-consume.1 doc/amqp-get.1 doc/librabbitmq-tools.7 diff --git a/tools/common.c b/tools/common.c index ec24085..39099c1 100644 --- a/tools/common.c +++ b/tools/common.c @@ -58,12 +58,12 @@ #include #include #include -#include -#include #include "common.h" -extern char **environ; +#ifdef WINDOWS +#include "compat.h" +#endif void die(const char *fmt, ...) { @@ -169,16 +169,6 @@ void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) exit(1); } -void set_cloexec(int fd) -{ - int flags; - - flags = fcntl(fd, F_GETFD); - if (flags == -1 - || fcntl(fd, F_SETFD, (long)(flags | FD_CLOEXEC)) == -1) - die_errno(errno, "set_cloexec"); -} - static char *amqp_server = "localhost"; static char *amqp_vhost = "/"; static char *amqp_username = "guest"; @@ -224,8 +214,6 @@ amqp_connection_state_t make_connection(void) s = amqp_open_socket(host, port ? port : 5672); die_amqp_error(-s, "opening socket to %s", amqp_server); - set_cloexec(s); - conn = amqp_new_connection(); amqp_set_sockfd(conn, s); @@ -318,47 +306,6 @@ void copy_body(amqp_connection_state_t conn, int fd) } } -void pipeline(const char * const *argv, struct pipeline *pl) -{ - posix_spawn_file_actions_t file_acts; - - int pipefds[2]; - if (pipe(pipefds)) - die_errno(errno, "pipe"); - - die_errno(posix_spawn_file_actions_init(&file_acts), - "posix_spawn_file_actions_init"); - die_errno(posix_spawn_file_actions_adddup2(&file_acts, pipefds[0], 0), - "posix_spawn_file_actions_adddup2"); - die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[0]), - "posix_spawn_file_actions_addclose"); - die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[1]), - "posix_spawn_file_actions_addclose"); - - die_errno(posix_spawnp(&pl->pid, argv[0], &file_acts, NULL, - (char * const *)argv, environ), - "posix_spawnp: %s", argv[0]); - - die_errno(posix_spawn_file_actions_destroy(&file_acts), - "posix_spawn_file_actions_destroy"); - - if (close(pipefds[0])) - die_errno(errno, "close"); - - pl->infd = pipefds[1]; -} - -int finish_pipeline(struct pipeline *pl) -{ - int status; - - if (close(pl->infd)) - die_errno(errno, "close"); - if (waitpid(pl->pid, &status, 0) < 0) - die_errno(errno, "waitpid"); - return WIFEXITED(status) && WEXITSTATUS(status) == 0; -} - poptContext process_options(int argc, const char **argv, struct poptOption *options, const char *help) diff --git a/tools/common.h b/tools/common.h index b3d8ab9..0caee98 100644 --- a/tools/common.h +++ b/tools/common.h @@ -77,14 +77,6 @@ extern void write_all(int fd, amqp_bytes_t data); extern void copy_body(amqp_connection_state_t conn, int fd); -struct pipeline { - int pid; - int infd; -}; - -extern void pipeline(const char * const *argv, struct pipeline *pl); -extern int finish_pipeline(struct pipeline *pl); - #define INCLUDE_OPTIONS(options) \ {NULL, 0, POPT_ARG_INCLUDE_TABLE, options, 0, options ## _title, NULL} diff --git a/tools/consume.c b/tools/consume.c index 9999960..2117bba 100644 --- a/tools/consume.c +++ b/tools/consume.c @@ -54,6 +54,7 @@ #include #include "common.h" +#include "process.h" /* Convert a amqp_bytes_t to an escaped string form for printing. We use the same escaping conventions as rabbitmqctl. */ diff --git a/tools/unix/process.c b/tools/unix/process.c new file mode 100644 index 0000000..8a02afb --- /dev/null +++ b/tools/unix/process.c @@ -0,0 +1,100 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "common.h" +#include "process.h" + +extern char **environ; + +void pipeline(const char *const *argv, struct pipeline *pl) +{ + posix_spawn_file_actions_t file_acts; + + int pipefds[2]; + if (pipe(pipefds)) + die_errno(errno, "pipe"); + + die_errno(posix_spawn_file_actions_init(&file_acts), + "posix_spawn_file_actions_init"); + die_errno(posix_spawn_file_actions_adddup2(&file_acts, pipefds[0], 0), + "posix_spawn_file_actions_adddup2"); + die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[0]), + "posix_spawn_file_actions_addclose"); + die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[1]), + "posix_spawn_file_actions_addclose"); + + die_errno(posix_spawnp(&pl->pid, argv[0], &file_acts, NULL, + (char * const *)argv, environ), + "posix_spawnp: %s", argv[0]); + + die_errno(posix_spawn_file_actions_destroy(&file_acts), + "posix_spawn_file_actions_destroy"); + + if (close(pipefds[0])) + die_errno(errno, "close"); + + pl->infd = pipefds[1]; +} + +int finish_pipeline(struct pipeline *pl) +{ + int status; + + if (close(pl->infd)) + die_errno(errno, "close"); + if (waitpid(pl->pid, &status, 0) < 0) + die_errno(errno, "waitpid"); + return WIFEXITED(status) && WEXITSTATUS(status) == 0; +} diff --git a/tools/unix/process.h b/tools/unix/process.h new file mode 100644 index 0000000..ac2939d --- /dev/null +++ b/tools/unix/process.h @@ -0,0 +1,57 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +struct pipeline { + int pid; + int infd; +}; + +extern void pipeline(const char *const *argv, struct pipeline *pl); +extern int finish_pipeline(struct pipeline *pl); diff --git a/tools/windows/compat.c b/tools/windows/compat.c new file mode 100644 index 0000000..f0508b2 --- /dev/null +++ b/tools/windows/compat.c @@ -0,0 +1,73 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "compat.h" + +int asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = _vscprintf(fmt, ap); + *strp = malloc(len+1); + if (!*strp) + return -1; + + len = vsprintf(*strp, fmt, ap); + *strp[len] = 0; + + va_end(ap); + return len; +} diff --git a/tools/windows/compat.h b/tools/windows/compat.h new file mode 100644 index 0000000..8211b37 --- /dev/null +++ b/tools/windows/compat.h @@ -0,0 +1,51 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +extern int asprintf(char **strp, const char *fmt, ...); diff --git a/tools/windows/process.c b/tools/windows/process.c new file mode 100644 index 0000000..9a0b893 --- /dev/null +++ b/tools/windows/process.c @@ -0,0 +1,204 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "common.h" +#include "process.h" + +void die_windows_error(const char *fmt, ...) +{ + char *msg; + + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&msg, 0, NULL)) + msg = "(failed to retrieving Windows error message)"; + + fprintf(stderr, ": %s\n", msg); + exit(1); +} + +static char *make_command_line(const char *const *argv) +{ + int i; + size_t len = 1; /* initial quotes */ + char *buf; + char *dest; + + /* calculate the length of the required buffer, making worst + case assumptions for simplicity */ + for (i = 0;;) { + len += strlen(argv[i]) * 2; + + if (!argv[++i]) + break; + + len += 3; /* quotes, space, quotes */ + } + + len += 2; /* final quotes and the terminating zero */ + + dest = buf = malloc(len); + if (!buf) + die("allocating memory for subprocess command line"); + + *dest++ = '\"'; + + for (i = 0;;) { + const char *src = argv[i]; + for (;;) { + switch (*src) { + case 0: + goto done; + + case '\"': + case '\\': + *dest++ = '\\'; + /* fall through */ + + default: + *dest++ = *src++; + break; + } + } + done: + + if (!argv[++i]) + break; + + *dest++ = '\"'; + *dest++ = ' '; + *dest++ = '\"'; + } + + *dest++ = '\"'; + *dest++ = 0; + return buf; +} + +void pipeline(const char *const *argv, struct pipeline *pl) +{ + HANDLE in_read_handle, in_write_handle; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION proc_info; + STARTUPINFO start_info; + char *cmdline = make_command_line(argv); + + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = TRUE; + sec_attr.lpSecurityDescriptor = NULL; + + if (!CreatePipe(&in_read_handle, &in_write_handle, &sec_attr, 0)) + die_windows_error("CreatePipe"); + + if (!SetHandleInformation(in_write_handle, HANDLE_FLAG_INHERIT, 0)) + die_windows_error("SetHandleInformation"); + + /* when in Rome... */ + ZeroMemory(&proc_info, sizeof proc_info); + ZeroMemory(&start_info, sizeof start_info); + + start_info.cb = sizeof start_info; + start_info.dwFlags |= STARTF_USESTDHANDLES; + + if ((start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE)) + == INVALID_HANDLE_VALUE + || (start_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)) + == INVALID_HANDLE_VALUE) + die_windows_error("GetStdHandle"); + + start_info.hStdInput = in_read_handle; + + if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, + NULL, NULL, &start_info, &proc_info)) + die_windows_error("CreateProcess"); + + if (!CloseHandle(proc_info.hThread)) + die_windows_error("CloseHandle for thread"); + if (!CloseHandle(in_read_handle)) + die_windows_error("CloseHandle"); + + pl->proc_handle = proc_info.hProcess; + pl->infd = _open_osfhandle((intptr_t)in_write_handle, 0); +} + +int finish_pipeline(struct pipeline *pl) +{ + DWORD code; + + if (close(pl->infd)) + die_errno(errno, "close"); + + for (;;) { + if (!GetExitCodeProcess(pl->proc_handle, &code)) + die_windows_error("GetExitCodeProcess"); + if (code != STILL_ACTIVE) + break; + + if (WaitForSingleObject(pl->proc_handle, INFINITE) + == WAIT_FAILED) + die_windows_error("WaitForSingleObject"); + } + + if (!CloseHandle(pl->proc_handle)) + die_windows_error("CloseHandle for process"); + + return code; +} diff --git a/tools/windows/process.h b/tools/windows/process.h new file mode 100644 index 0000000..df276a7 --- /dev/null +++ b/tools/windows/process.h @@ -0,0 +1,59 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The Original Code is librabbitmq. + * + * The Initial Developers of the Original Code are LShift Ltd, Cohesive + * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions + * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive + * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright + * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and + * Rabbit Technologies Ltd. + * + * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift + * Ltd. Portions created by Cohesive Financial Technologies LLC are + * Copyright (C) 2007-2010 Cohesive Financial Technologies + * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C) + * 2007-2010 Rabbit Technologies Ltd. + * + * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010 + * LShift Ltd and Tony Garnock-Jones. + * + * All Rights Reserved. + * + * Contributor(s): ______________________________________. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 2 or later (the "GPL"), in + * which case the provisions of the GPL are applicable instead of those + * above. If you wish to allow use of your version of this file only + * under the terms of the GPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the + * notice and other provisions required by the GPL. If you do not + * delete the provisions above, a recipient may use your version of + * this file under the terms of any one of the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** + */ + +#include + +struct pipeline { + HANDLE proc_handle; + int infd; +}; + +extern void pipeline(const char *const *argv, struct pipeline *pl); +extern int finish_pipeline(struct pipeline *pl); -- cgit v1.2.1 From b2b9a30f2854d24fa0941ed78f13ca8bd4fc8061 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Fri, 4 Jun 2010 08:57:43 +0100 Subject: Fix EXTRA_LIBS dependencies of librabbitmq I broke this with a last-minute change that I didn't test on Windows. Will I ever learn? --- librabbitmq/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/librabbitmq/Makefile.am b/librabbitmq/Makefile.am index 9211c8f..53c9ea1 100644 --- a/librabbitmq/Makefile.am +++ b/librabbitmq/Makefile.am @@ -3,6 +3,7 @@ lib_LTLIBRARIES = librabbitmq.la AM_CFLAGS = -I$(PLATFORM_DIR) librabbitmq_la_SOURCES = amqp_mem.c amqp_table.c amqp_connection.c amqp_socket.c amqp_debug.c amqp_api.c $(PLATFORM_DIR)/socket.c librabbitmq_la_LDFLAGS = -no-undefined +librabbitmq_la_LIBADD = $(EXTRA_LIBS) nodist_librabbitmq_la_SOURCES = amqp_framing.c include_HEADERS = amqp_framing.h amqp.h noinst_HEADERS = amqp_private.h $(PLATFORM_DIR)/socket.h @@ -12,8 +13,6 @@ EXTRA_DIST = codegen.py CODEGEN_PY=$(srcdir)/codegen.py -LDADD=$(EXTRA_LIBS) - amqp_framing.h: $(AMQP_SPEC_JSON_PATH) $(CODEGEN_PY) PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) header $< $@ -- cgit v1.2.1 From 40c24ac6856723e14e6b9336f80bd63550d2407b Mon Sep 17 00:00:00 2001 From: David Wragg Date: Fri, 4 Jun 2010 08:57:44 +0100 Subject: The MinGW team has changed all the download URLs on SourceForge Thanks guys. --- etc/install-mingw.sh | 54 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/etc/install-mingw.sh b/etc/install-mingw.sh index de953d4..7fdd339 100755 --- a/etc/install-mingw.sh +++ b/etc/install-mingw.sh @@ -20,33 +20,33 @@ mkdir -p $download_dir $unpack_dir while read f ; do wget -P $download_dir -N http://switch.dl.sourceforge.net/project/mingw/$f done < Date: Sun, 6 Jun 2010 02:26:31 +0100 Subject: Fix some incorrect paths --- README.windows | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.windows b/README.windows index 1a20c00..723c25e 100644 --- a/README.windows +++ b/README.windows @@ -68,10 +68,10 @@ this, copy the following files into a directory: - rabbitmq-c/librabbitmq/.libs/librabbitmq-0.dll -- /lib/libpopt-0.dll +- /bin/libpopt-0.dll -- /lib/libiconv-2.dll +- /bin/libiconv-2.dll -- /lib/libintl-8.dll +- /bin/libintl-8.dll -- cgit v1.2.1 From d7e0dd52b6c1283cb42be72238274781958f0f5e Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 6 Jun 2010 20:57:59 +1200 Subject: Include both unix and windows support files in distributions --- librabbitmq/Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/librabbitmq/Makefile.am b/librabbitmq/Makefile.am index 53c9ea1..35680d0 100644 --- a/librabbitmq/Makefile.am +++ b/librabbitmq/Makefile.am @@ -9,7 +9,10 @@ include_HEADERS = amqp_framing.h amqp.h noinst_HEADERS = amqp_private.h $(PLATFORM_DIR)/socket.h BUILT_SOURCES = amqp_framing.h amqp_framing.c CLEANFILES = amqp_framing.h amqp_framing.c -EXTRA_DIST = codegen.py +EXTRA_DIST = \ + codegen.py \ + unix/socket.c unix/socket.h \ + windows/socket.c windows/socket.h CODEGEN_PY=$(srcdir)/codegen.py -- cgit v1.2.1 From 5e48c730f768e40663af19e01b143d95d1e11fef Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 6 Jun 2010 21:06:15 +1200 Subject: More unix and windows support files in distributions --- tools/Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/Makefile.am b/tools/Makefile.am index ad53d88..ef7a9bc 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,3 +20,8 @@ amqp_get_SOURCES = get.c $(COMMON_SOURCES) amqp_consume_SOURCES = consume.c $(PLATFORM_DIR)/process.c $(COMMON_SOURCES) amqp_declare_queue_SOURCES = declare_queue.c $(COMMON_SOURCES) amqp_delete_queue_SOURCES = delete_queue.c $(COMMON_SOURCES) + +EXTRA_DIST = \ + unix/process.c unix/process.h \ + windows/process.c windows/process.h \ + windows/compat.c windows/compat.h -- cgit v1.2.1 From d2fb070fe6e36075de389f59729ff4b022eed9a0 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Fri, 2 Jul 2010 17:05:57 +1200 Subject: Turn on TCP_NODELAY by default. --- librabbitmq/amqp_socket.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index a78056b..d62f744 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -65,6 +65,7 @@ #include #include #include +#include #include @@ -89,6 +90,15 @@ int amqp_open_socket(char const *hostname, return -errno; } + { + int one = 1; + if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) { + int result = -errno; + close(sockfd); + return result; + } + } + if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { int result = -errno; close(sockfd); -- cgit v1.2.1 From 252e5ac851fe74ed6cbac0f456e2067efbdaac7c Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 11 Jul 2010 14:11:11 +1200 Subject: Dedup error handling code --- librabbitmq/amqp_socket.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index d62f744..35e9c3d 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -75,6 +75,7 @@ int amqp_open_socket(char const *hostname, int sockfd; struct sockaddr_in addr; struct hostent *he; + int one = 1; /* used as a buffer by setsockopt below */ he = gethostbyname(hostname); if (he == NULL) { @@ -90,16 +91,9 @@ int amqp_open_socket(char const *hostname, return -errno; } + if ((setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) || + (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)) { - int one = 1; - if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) { - int result = -errno; - close(sockfd); - return result; - } - } - - if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { int result = -errno; close(sockfd); return result; -- cgit v1.2.1 From 7178efdeed81380bffa8013774efbac15e45bf81 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 26 Jul 2010 02:24:26 +0100 Subject: ERROR_HOST_NOT_FOUND -> ERROR_GETHOSTBYNAME_FAILED --- librabbitmq/amqp_api.c | 2 +- librabbitmq/amqp_private.h | 2 +- librabbitmq/amqp_socket.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c index 3724a37..722bc86 100644 --- a/librabbitmq/amqp_api.c +++ b/librabbitmq/amqp_api.c @@ -64,7 +64,7 @@ static const char *client_error_strings[ERROR_MAX] = { "received bad AMQP data", /* ERROR_BAD_AQMP_DATA */ "unknown AMQP class id", /* ERROR_UNKOWN_CLASS */ "unknown AMQP method id", /* ERROR_UNKOWN_METHOD */ - "unknown host", /* ERROR_HOST_NOT_FOUND */ + "unknown host", /* ERROR_GETHOSTBYNAME_FAILED */ "incompatible AMQP version", /* ERROR_INCOMPATIBLE_AMQP_VERSION */ "connection closed unexpectedly", /* ERROR_CONNECTION_CLOSED */ }; diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h index 7206ae5..a9969be 100644 --- a/librabbitmq/amqp_private.h +++ b/librabbitmq/amqp_private.h @@ -71,7 +71,7 @@ extern "C" { #define ERROR_BAD_AMQP_DATA 2 #define ERROR_UNKNOWN_CLASS 3 #define ERROR_UNKNOWN_METHOD 4 -#define ERROR_HOST_NOT_FOUND 5 +#define ERROR_GETHOSTBYNAME_FAILED 5 #define ERROR_INCOMPATIBLE_AMQP_VERSION 6 #define ERROR_CONNECTION_CLOSED 7 #define ERROR_MAX 7 diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index 3c82e1d..ff19372 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -76,7 +76,7 @@ int amqp_open_socket(char const *hostname, he = gethostbyname(hostname); if (he == NULL) - return -ERROR_HOST_NOT_FOUND; + return -ERROR_GETHOSTBYNAME_FAILED; addr.sin_family = AF_INET; addr.sin_port = htons(portnumber); -- cgit v1.2.1 From 61e18281077967ce3684f9182e8d7337da37c0b2 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 26 Jul 2010 02:36:39 +0100 Subject: Replace socket_{read,write} with recv and send --- librabbitmq/amqp_connection.c | 4 ++-- librabbitmq/amqp_socket.c | 7 +++---- librabbitmq/unix/socket.h | 2 -- librabbitmq/windows/socket.h | 10 ---------- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index 63af96a..7860669 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -429,8 +429,8 @@ int amqp_send_frame(amqp_connection_state_t state, res = inner_send_frame(state, frame, &encoded, &payload_len); switch (res) { case 0: - res = socket_write(state->sockfd, state->outbound_buffer.bytes, - payload_len + (HEADER_SIZE + FOOTER_SIZE)); + res = send(state->sockfd, state->outbound_buffer.bytes, + payload_len + (HEADER_SIZE + FOOTER_SIZE), 0); break; case 1: { diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index ff19372..3f88120 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -111,7 +111,7 @@ static char *header() { } int amqp_send_header(amqp_connection_state_t state) { - return socket_write(state->sockfd, header(), 8); + return send(state->sockfd, header(), 8, 0); } int amqp_send_header_to(amqp_connection_state_t state, @@ -194,9 +194,8 @@ static int wait_frame_inner(amqp_connection_state_t state, assert(result != 0); } - result = socket_read(state->sockfd, - state->sock_inbound_buffer.bytes, - state->sock_inbound_buffer.len); + result = recv(state->sockfd, state->sock_inbound_buffer.bytes, + state->sock_inbound_buffer.len, 0); if (result <= 0) { if (result == 0) return -ERROR_CONNECTION_CLOSED; diff --git a/librabbitmq/unix/socket.h b/librabbitmq/unix/socket.h index dff88c9..e54c4cb 100644 --- a/librabbitmq/unix/socket.h +++ b/librabbitmq/unix/socket.h @@ -70,8 +70,6 @@ extern int socket_socket(int domain, int type, int proto); #define socket_connect connect #define socket_setsockopt setsockopt #define socket_close close -#define socket_read read -#define socket_write write #define socket_writev writev static inline int encoded_socket_errno() diff --git a/librabbitmq/windows/socket.h b/librabbitmq/windows/socket.h index e0a9799..a5b091d 100644 --- a/librabbitmq/windows/socket.h +++ b/librabbitmq/windows/socket.h @@ -67,16 +67,6 @@ static inline int socket_setsockopt(int sock, int level, int optname, return setsockopt(sock, level, optname, (const char *)optval, optlen); } -static inline int socket_read(int sock, void *buf, size_t count) -{ - return recv(sock, buf, count, 0); -} - -static inline int socket_write(int sock, void *buf, size_t count) -{ - return send(sock, buf, count, 0); -} - /* same as WSABUF */ struct iovec { u_long iov_len; -- cgit v1.2.1 From e16672cf9ded0b329090b8612a2b1d3f9831288c Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 26 Jul 2010 02:41:55 +0100 Subject: Eliminate the socket_ prefix on connect To be consistent with the reduced consistency. --- librabbitmq/amqp_socket.c | 2 +- librabbitmq/unix/socket.h | 1 - librabbitmq/windows/socket.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index 3f88120..fc823be 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -87,7 +87,7 @@ int amqp_open_socket(char const *hostname, return -encoded_socket_errno(); if (socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0 - || socket_connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + || connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { res = -encoded_socket_errno(); socket_close(sockfd); diff --git a/librabbitmq/unix/socket.h b/librabbitmq/unix/socket.h index e54c4cb..185e651 100644 --- a/librabbitmq/unix/socket.h +++ b/librabbitmq/unix/socket.h @@ -67,7 +67,6 @@ static inline int socket_init(void) extern int socket_socket(int domain, int type, int proto); -#define socket_connect connect #define socket_setsockopt setsockopt #define socket_close close #define socket_writev writev diff --git a/librabbitmq/windows/socket.h b/librabbitmq/windows/socket.h index a5b091d..6a2da25 100644 --- a/librabbitmq/windows/socket.h +++ b/librabbitmq/windows/socket.h @@ -56,7 +56,6 @@ extern int socket_init(void); #define socket_socket socket -#define socket_connect connect #define socket_close closesocket static inline int socket_setsockopt(int sock, int level, int optname, -- cgit v1.2.1 From 6cc7fe86a01628483646a0b1eca423a9d8a34025 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 26 Jul 2010 02:54:33 +0100 Subject: Convert the socket_ prefix to amqp_socket_ --- librabbitmq/amqp_connection.c | 8 ++++---- librabbitmq/amqp_socket.c | 13 +++++++------ librabbitmq/unix/socket.c | 2 +- librabbitmq/unix/socket.h | 12 ++++++------ librabbitmq/windows/socket.c | 2 +- librabbitmq/windows/socket.h | 12 ++++++------ 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index 7860669..5b5e813 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -169,8 +169,8 @@ void amqp_destroy_connection(amqp_connection_state_t state) { int amqp_end_connection(amqp_connection_state_t state) { int s = state->sockfd; amqp_destroy_connection(state); - if (socket_close(s) < 0) - return -encoded_socket_errno(); + if (amqp_socket_close(s) < 0) + return -amqp_socket_error(); else return 0; } @@ -443,7 +443,7 @@ int amqp_send_frame(amqp_connection_state_t state, iov[2].iov_base = &frame_end_byte; assert(FOOTER_SIZE == 1); iov[2].iov_len = FOOTER_SIZE; - res = socket_writev(state->sockfd, &iov[0], 3); + res = amqp_socket_writev(state->sockfd, &iov[0], 3); break; } @@ -452,7 +452,7 @@ int amqp_send_frame(amqp_connection_state_t state, } if (res < 0) - return -encoded_socket_errno(); + return -amqp_socket_error(); else return 0; } diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index fc823be..d39f29d 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -70,7 +70,7 @@ int amqp_open_socket(char const *hostname, struct hostent *he; int one = 1; /* used as a buffer by setsockopt below */ - res = socket_init(); + res = amqp_socket_init(); if (res) return res; @@ -84,13 +84,14 @@ int amqp_open_socket(char const *hostname, sockfd = socket(PF_INET, SOCK_STREAM, 0); if (sockfd == -1) - return -encoded_socket_errno(); + return -amqp_socket_error(); - if (socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0 + if (amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, + sizeof(one)) < 0 || connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - res = -encoded_socket_errno(); - socket_close(sockfd); + res = -amqp_socket_error(); + amqp_socket_close(sockfd); return res; } @@ -200,7 +201,7 @@ static int wait_frame_inner(amqp_connection_state_t state, if (result == 0) return -ERROR_CONNECTION_CLOSED; else - return -encoded_socket_errno(); + return -amqp_socket_error(); } state->sock_inbound_limit = result; diff --git a/librabbitmq/unix/socket.c b/librabbitmq/unix/socket.c index 51db413..f4a7195 100644 --- a/librabbitmq/unix/socket.c +++ b/librabbitmq/unix/socket.c @@ -58,7 +58,7 @@ #include "amqp_private.h" #include "socket.h" -int socket_socket(int domain, int type, int proto) +int amqp_socket_socket(int domain, int type, int proto) { int flags; diff --git a/librabbitmq/unix/socket.h b/librabbitmq/unix/socket.h index 185e651..5cb37f1 100644 --- a/librabbitmq/unix/socket.h +++ b/librabbitmq/unix/socket.h @@ -60,18 +60,18 @@ #include #include -static inline int socket_init(void) +static inline int amqp_socket_init(void) { return 0; } -extern int socket_socket(int domain, int type, int proto); +extern int amqp_socket_socket(int domain, int type, int proto); -#define socket_setsockopt setsockopt -#define socket_close close -#define socket_writev writev +#define amqp_socket_setsockopt setsockopt +#define amqp_socket_close close +#define amqp_socket_writev writev -static inline int encoded_socket_errno() +static inline int amqp_socket_error() { return errno | ERROR_CATEGORY_OS; } diff --git a/librabbitmq/windows/socket.c b/librabbitmq/windows/socket.c index f809f62..62a1e50 100644 --- a/librabbitmq/windows/socket.c +++ b/librabbitmq/windows/socket.c @@ -57,7 +57,7 @@ static int called_wsastartup; -int socket_init(void) +int amqp_socket_init(void) { if (!called_wsastartup) { WSADATA data; diff --git a/librabbitmq/windows/socket.h b/librabbitmq/windows/socket.h index 6a2da25..3e0a378 100644 --- a/librabbitmq/windows/socket.h +++ b/librabbitmq/windows/socket.h @@ -53,12 +53,12 @@ #include -extern int socket_init(void); +extern int amqp_socket_init(void); -#define socket_socket socket -#define socket_close closesocket +#define amqp_socket_socket socket +#define amqp_socket_close closesocket -static inline int socket_setsockopt(int sock, int level, int optname, +static inline int amqp_socket_setsockopt(int sock, int level, int optname, const void *optval, size_t optlen) { /* the winsock setsockopt function has its 4th argument as a @@ -72,7 +72,7 @@ struct iovec { char *iov_base; }; -static inline int socket_writev(int sock, struct iovec *iov, int nvecs) +static inline int amqp_socket_writev(int sock, struct iovec *iov, int nvecs) { DWORD ret; if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) @@ -81,7 +81,7 @@ static inline int socket_writev(int sock, struct iovec *iov, int nvecs) return -1; } -static inline int encoded_socket_errno() +static inline int amqp_socket_error() { return WSAGetLastError() | ERROR_CATEGORY_OS; } -- cgit v1.2.1 From 7290a2692cd0f597573de51599c9b50088c02f90 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 26 Jul 2010 03:09:38 +0100 Subject: Fold amqp_end_connection socket closing into amqp_destroy_connection --- examples/amqp_bind.c | 2 +- examples/amqp_consumer.c | 2 +- examples/amqp_exchange_declare.c | 2 +- examples/amqp_listen.c | 2 +- examples/amqp_listenq.c | 2 +- examples/amqp_producer.c | 2 +- examples/amqp_sendstring.c | 2 +- examples/amqp_unbind.c | 2 +- librabbitmq/amqp.h | 5 ++--- librabbitmq/amqp_connection.c | 12 +++++------- tools/common.c | 2 +- 11 files changed, 16 insertions(+), 19 deletions(-) diff --git a/examples/amqp_bind.c b/examples/amqp_bind.c index cf7c377..1f183a5 100644 --- a/examples/amqp_bind.c +++ b/examples/amqp_bind.c @@ -99,6 +99,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_consumer.c b/examples/amqp_consumer.c index 5dfbb33..6b24d8c 100644 --- a/examples/amqp_consumer.c +++ b/examples/amqp_consumer.c @@ -184,7 +184,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_exchange_declare.c b/examples/amqp_exchange_declare.c index 32e71b0..27bff1a 100644 --- a/examples/amqp_exchange_declare.c +++ b/examples/amqp_exchange_declare.c @@ -94,6 +94,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_listen.c b/examples/amqp_listen.c index 412dcd5..6025e5c 100644 --- a/examples/amqp_listen.c +++ b/examples/amqp_listen.c @@ -187,7 +187,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_listenq.c b/examples/amqp_listenq.c index 1fc7db0..94d89eb 100644 --- a/examples/amqp_listenq.c +++ b/examples/amqp_listenq.c @@ -171,7 +171,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_producer.c b/examples/amqp_producer.c index 61cc925..b83e030 100644 --- a/examples/amqp_producer.c +++ b/examples/amqp_producer.c @@ -151,6 +151,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_sendstring.c b/examples/amqp_sendstring.c index e669505..ccd3866 100644 --- a/examples/amqp_sendstring.c +++ b/examples/amqp_sendstring.c @@ -108,6 +108,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/examples/amqp_unbind.c b/examples/amqp_unbind.c index bc92efe..4b92e12 100644 --- a/examples/amqp_unbind.c +++ b/examples/amqp_unbind.c @@ -99,6 +99,6 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); - die_on_error(amqp_end_connection(conn), "Ending connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; } diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index fa76637..58d042c 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -308,9 +308,8 @@ extern int amqp_tune_connection(amqp_connection_state_t state, int channel_max, int frame_max, int heartbeat); -int amqp_get_channel_max(amqp_connection_state_t state); -extern void amqp_destroy_connection(amqp_connection_state_t state); -extern int amqp_end_connection(amqp_connection_state_t state); +extern int amqp_get_channel_max(amqp_connection_state_t state); +extern int amqp_destroy_connection(amqp_connection_state_t state); extern int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data, diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c index 5b5e813..3d95e98 100644 --- a/librabbitmq/amqp_connection.c +++ b/librabbitmq/amqp_connection.c @@ -158,22 +158,20 @@ int amqp_get_channel_max(amqp_connection_state_t state) { return state->channel_max; } -void amqp_destroy_connection(amqp_connection_state_t state) { +int amqp_destroy_connection(amqp_connection_state_t state) { + int s = state->sockfd; + empty_amqp_pool(&state->frame_pool); empty_amqp_pool(&state->decoding_pool); free(state->outbound_buffer.bytes); free(state->sock_inbound_buffer.bytes); free(state); -} -int amqp_end_connection(amqp_connection_state_t state) { - int s = state->sockfd; - amqp_destroy_connection(state); - if (amqp_socket_close(s) < 0) + if (s >= 0 && amqp_socket_close(s) < 0) return -amqp_socket_error(); else return 0; -} +} static void return_to_idle(amqp_connection_state_t state) { state->inbound_buffer.bytes = NULL; diff --git a/tools/common.c b/tools/common.c index 39099c1..1d8fbd8 100644 --- a/tools/common.c +++ b/tools/common.c @@ -236,7 +236,7 @@ void close_connection(amqp_connection_state_t conn) die_rpc(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "closing connection"); - res = amqp_end_connection(conn); + res = amqp_destroy_connection(conn); die_amqp_error(-res, "closing connection"); } -- cgit v1.2.1 From 0185d7019f3f83ed6c9ad5e23170682f1dde8d81 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 26 Jul 2010 04:20:49 +0100 Subject: Add msys packages and instructions to run autoreconf under Windows --- README.windows | 24 ++++++++++++++++-------- etc/install-mingw.sh | 12 +++++++++++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/README.windows b/README.windows index 723c25e..e4ae433 100644 --- a/README.windows +++ b/README.windows @@ -31,19 +31,17 @@ and a tar that supports the -J option, which probably rules out OSX. Run install-mingw.sh specifying the destination directory, e.g. - $ etc/install-mingw.sh /tmp/mingw + $ etc/install-mingw.sh mingw Python is needed for the rabbitmq-c build, so you will also need to install python under Windows. The Windows installer from python.org will do fine. -You will need to get the rabbitmq-c and rabbitmq-codegen source code. -If you are getting it from Mercurial, you will need to run "autoreconf --i" within rabbitmq-c somewhere other than under MinGW first (perhaps -this can be done under MinGW/MSYS, but the packages installed by -install-mingw.sh are not sufficient). +You will need to copy the source code for rabbitmq-c and +rabbitmq-codegen somewhere under your mingw directory. -Open a cmd window, and ensure that both the MinGW bin directory and the python install directory are in the path, e.g. +Open a cmd window, and ensure that both the MinGW bin directory and +the python install directory are in the path, e.g. C:\>set PATH=%PATH%;C:\mingw\bin;C:\Python26 @@ -53,7 +51,17 @@ Windows path of your MinGW install): C:\>bash bash-3.1$ mount 'C:\mingw' /mingw -Then go to the rabbitmq-c directory, and configure and make as normal: +Then go to the rabbitmq-c directory. If you got the rabbitmq-c +directory from Mercurial (which is the only way to get it at the +moment), you will need to run autoreconf to produce the configuration +scripts: + + bash-3.1$ autoreconf -i + +This will produce a few lines of informational output while it runs, +but as long as it doesn't mention any errors, you are ok. + +Finally, configure and make: bash-3.1$ ./configure && make [...] diff --git a/etc/install-mingw.sh b/etc/install-mingw.sh index 7fdd339..891c6fe 100755 --- a/etc/install-mingw.sh +++ b/etc/install-mingw.sh @@ -7,7 +7,7 @@ fi unpack_dir=$1 -if [ -eb "$unpack_dir" ] ; then +if [ -e "$unpack_dir" ] ; then echo "Destination directory already exists; please delete it if you are sure" 1>&2 exit 1 fi @@ -47,6 +47,16 @@ MinGW/gettext/gettext-0.17-1/gettext-0.17-1-mingw32-dev.tar.lzma MinGW/libiconv/libiconv-1.13.1-1/libiconv-1.13.1-1-mingw32-dll-2.tar.lzma MinGW/libiconv/libiconv-1.13.1-1/libiconv-1.13.1-1-mingw32-dev.tar.lzma MinGW/libiconv/libiconv-1.13.1-1/libcharset-1.13.1-1-mingw32-dll-1.tar.lzma +MSYS/autoconf/autoconf-2.65-1/autoconf-2.65-1-msys-1.0.13-bin.tar.lzma +MSYS/automake/automake-1.11.1-1/automake-1.11.1-1-msys-1.0.13-bin.tar.lzma +MSYS/m4/m4-1.4.14-1/m4-1.4.14-1-msys-1.0.13-bin.tar.lzma +MSYS/libtool/libtool-2.2.7a-2/libtool-2.2.7a-2-msys-1.0.13-bin.tar.lzma +MSYS/tar/tar-1.23-1/tar-1.23-1-msys-1.0.13-bin.tar.lzma +MSYS/regex/regex-1.20090805-2/libregex-1.20090805-2-msys-1.0.13-dll-1.tar.lzma +MSYS/libiconv/libiconv-1.13.1-2/libiconv-1.13.1-2-msys-1.0.13-dll-2.tar.lzma +MSYS/gettext/gettext-0.17-2/libintl-0.17-2-msys-dll-8.tar.lzma +MSYS/perl/perl-5.6.1_2-2/perl-5.6.1_2-2-msys-1.0.13-bin.tar.lzma +MSYS/crypt/crypt-1.1_1-3/libcrypt-1.1_1-3-msys-1.0.13-dll-0.tar.lzma EOF for f in $download_dir/* ; do -- cgit v1.2.1 From 7032fcd3e646d5e25cd8c40144a03ab869a9f5ff Mon Sep 17 00:00:00 2001 From: David Wragg Date: Tue, 27 Jul 2010 18:17:24 +0100 Subject: Remove redundant includes of popt.h --- tools/declare_queue.c | 2 -- tools/delete_queue.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/tools/declare_queue.c b/tools/declare_queue.c index 662531f..3536455 100644 --- a/tools/declare_queue.c +++ b/tools/declare_queue.c @@ -55,8 +55,6 @@ #include #include -#include - #include "common.h" int main(int argc, const char **argv) diff --git a/tools/delete_queue.c b/tools/delete_queue.c index 41d0d13..ccd157e 100644 --- a/tools/delete_queue.c +++ b/tools/delete_queue.c @@ -55,8 +55,6 @@ #include #include -#include - #include "common.h" int main(int argc, const char **argv) -- cgit v1.2.1 From a39a656ffb1a72b031aa586a37ff77b39939b6fb Mon Sep 17 00:00:00 2001 From: David Wragg Date: Tue, 27 Jul 2010 18:32:21 +0100 Subject: die_on_error expects a librabbitmq error code --- examples/amqp_consumer.c | 3 ++- examples/amqp_listen.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/amqp_consumer.c b/examples/amqp_consumer.c index 6b24d8c..1557fb1 100644 --- a/examples/amqp_consumer.c +++ b/examples/amqp_consumer.c @@ -169,7 +169,8 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); queuename = amqp_bytes_malloc_dup(r->queue); if (queuename.bytes == NULL) { - die_on_error(-ENOMEM, "Copying queue name"); + fprintf(stderr, "Out of memory while copying queue name"); + return 1; } } diff --git a/examples/amqp_listen.c b/examples/amqp_listen.c index 6025e5c..ba7d80a 100644 --- a/examples/amqp_listen.c +++ b/examples/amqp_listen.c @@ -101,7 +101,8 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); queuename = amqp_bytes_malloc_dup(r->queue); if (queuename.bytes == NULL) { - die_on_error(-ENOMEM, "Copying queue name"); + fprintf(stderr, "Out of memory while copying queue name"); + return 1; } } -- cgit v1.2.1 From 4f30d164910f88f181489f591c0957317142da01 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Tue, 27 Jul 2010 19:36:36 +0100 Subject: Free heap-allocated error strings Even though we are about to exit anyway. --- examples/example_utils.c | 4 +++- tests/test_tables.c | 10 ++++++---- tools/common.c | 19 +++++++++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/examples/example_utils.c b/examples/example_utils.c index ae8f093..48f21f9 100644 --- a/examples/example_utils.c +++ b/examples/example_utils.c @@ -61,7 +61,9 @@ void die_on_error(int x, char const *context) { if (x < 0) { - fprintf(stderr, "%s: %s\n", context, amqp_error_string(-x)); + char *errstr = amqp_error_string(-x); + fprintf(stderr, "%s: %s\n", context, errstr); + free(errstr); exit(1); } } diff --git a/tests/test_tables.c b/tests/test_tables.c index 1a0652a..9c8a041 100644 --- a/tests/test_tables.c +++ b/tests/test_tables.c @@ -210,8 +210,9 @@ static void test_table_codec(void) { int decoding_offset = 0; result = amqp_decode_table(decoding_bytes, &pool, &decoded, &decoding_offset); if (result < 0) { - printf("Table decoding failed: %d (%s)\n", result, - amqp_error_string(-result)); + char *errstr = amqp_error_string(-result); + printf("Table decoding failed: %d (%s)\n", result, errstr); + free(errstr); abort(); } printf("BBBBBBBBBB\n"); @@ -229,8 +230,9 @@ static void test_table_codec(void) { result = amqp_encode_table(encoding_result, &table, &offset); if (result < 0) { - printf("Table encoding failed: %d (%s)\n", result, - amqp_error_string(-result)); + char *errstr = amqp_error_string(-result); + printf("Table encoding failed: %d (%s)\n", result, errstr); + free(errstr); abort(); } diff --git a/tools/common.c b/tools/common.c index 1d8fbd8..2a640be 100644 --- a/tools/common.c +++ b/tools/common.c @@ -77,10 +77,11 @@ void die(const char *fmt, ...) void die_errno(int err, const char *fmt, ...) { + va_list ap; + if (err == 0) return; - va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); @@ -90,14 +91,17 @@ void die_errno(int err, const char *fmt, ...) void die_amqp_error(int err, const char *fmt, ...) { + va_list ap; + char *errstr; + if (err <= 0) return; - - va_list ap; + va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - fprintf(stderr, ": %s\n", amqp_error_string(err)); + fprintf(stderr, ": %s\n", errstr = amqp_error_string(err)); + free(errstr); exit(1); } @@ -158,14 +162,17 @@ const char *amqp_rpc_reply_string(amqp_rpc_reply_t r) void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) { + va_list ap; + char *errstr; + if (r.reply_type == AMQP_RESPONSE_NORMAL) return; - va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - fprintf(stderr, ": %s\n", amqp_rpc_reply_string(r)); + fprintf(stderr, ": %s\n", errstr = amqp_rpc_reply_string(r)); + free(errstr); exit(1); } -- cgit v1.2.1 From d0509667889cf799a252bb0c4e8b2d86d75645b6 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Wed, 28 Jul 2010 00:58:31 +0100 Subject: Eliminate unnecessary includes of errno.h --- examples/amqp_consumer.c | 1 - examples/amqp_listen.c | 1 - examples/amqp_listenq.c | 1 - tests/test_tables.c | 1 - 4 files changed, 4 deletions(-) diff --git a/examples/amqp_consumer.c b/examples/amqp_consumer.c index 1557fb1..803e228 100644 --- a/examples/amqp_consumer.c +++ b/examples/amqp_consumer.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include diff --git a/examples/amqp_listen.c b/examples/amqp_listen.c index ba7d80a..3e56008 100644 --- a/examples/amqp_listen.c +++ b/examples/amqp_listen.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include diff --git a/examples/amqp_listenq.c b/examples/amqp_listenq.c index 94d89eb..0fbce51 100644 --- a/examples/amqp_listenq.c +++ b/examples/amqp_listenq.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include diff --git a/tests/test_tables.c b/tests/test_tables.c index 9c8a041..be1994b 100644 --- a/tests/test_tables.c +++ b/tests/test_tables.c @@ -52,7 +52,6 @@ #include #include #include -#include #include -- cgit v1.2.1 From 27235c0046dfc87b4f57c652681df4436fce3e0e Mon Sep 17 00:00:00 2001 From: David Wragg Date: Wed, 28 Jul 2010 01:08:49 +0100 Subject: Fix "const char *" to "void *" conversion warnings Functions returning a heap-allocated string should return a "char *", not a "const char *": Because the result is heap-allocated and becomes the responsibility of the caller, it is certainly modifiable. And the pointer will likely get passed to free(), triggering a conversion warning from gcc. So remove all the relevant consts. --- librabbitmq/amqp.h | 2 +- librabbitmq/amqp_api.c | 2 +- librabbitmq/amqp_private.h | 2 +- librabbitmq/unix/socket.c | 2 +- librabbitmq/windows/socket.c | 2 +- tools/common.c | 4 ++-- tools/common.h | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index 58d042c..7f4593f 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -506,7 +506,7 @@ extern amqp_rpc_reply_t amqp_get_rpc_reply(amqp_connection_state_t state); * The returned string resides on the heap; the caller is responsible * for freeing it. */ -extern const char *amqp_error_string(int err); +extern char *amqp_error_string(int err); #ifdef __cplusplus } diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c index 722bc86..2b1ed54 100644 --- a/librabbitmq/amqp_api.c +++ b/librabbitmq/amqp_api.c @@ -69,7 +69,7 @@ static const char *client_error_strings[ERROR_MAX] = { "connection closed unexpectedly", /* ERROR_CONNECTION_CLOSED */ }; -const char *amqp_error_string(int err) +char *amqp_error_string(int err) { const char *str; int category = (err & ERROR_CATEGORY_MASK); diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h index a9969be..c30663a 100644 --- a/librabbitmq/amqp_private.h +++ b/librabbitmq/amqp_private.h @@ -76,7 +76,7 @@ extern "C" { #define ERROR_CONNECTION_CLOSED 7 #define ERROR_MAX 7 -extern const char *amqp_os_error_string(int err); +extern char *amqp_os_error_string(int err); /* * Connection states: diff --git a/librabbitmq/unix/socket.c b/librabbitmq/unix/socket.c index f4a7195..9d37dfc 100644 --- a/librabbitmq/unix/socket.c +++ b/librabbitmq/unix/socket.c @@ -79,7 +79,7 @@ int amqp_socket_socket(int domain, int type, int proto) return s; } -const char *amqp_os_error_string(int err) +char *amqp_os_error_string(int err) { return strdup(strerror(err)); } diff --git a/librabbitmq/windows/socket.c b/librabbitmq/windows/socket.c index 62a1e50..9c026bd 100644 --- a/librabbitmq/windows/socket.c +++ b/librabbitmq/windows/socket.c @@ -71,7 +71,7 @@ int amqp_socket_init(void) return 0; } -const char *amqp_os_error_string(int err) +char *amqp_os_error_string(int err) { char *msg, *copy; diff --git a/tools/common.c b/tools/common.c index 2a640be..c5bda77 100644 --- a/tools/common.c +++ b/tools/common.c @@ -105,7 +105,7 @@ void die_amqp_error(int err, const char *fmt, ...) exit(1); } -const char *amqp_server_exception_string(amqp_rpc_reply_t r) +char *amqp_server_exception_string(amqp_rpc_reply_t r) { int res; char *s; @@ -140,7 +140,7 @@ const char *amqp_server_exception_string(amqp_rpc_reply_t r) return res >= 0 ? s : NULL; } -const char *amqp_rpc_reply_string(amqp_rpc_reply_t r) +char *amqp_rpc_reply_string(amqp_rpc_reply_t r) { switch (r.reply_type) { case AMQP_RESPONSE_NORMAL: diff --git a/tools/common.h b/tools/common.h index 0caee98..84889d3 100644 --- a/tools/common.h +++ b/tools/common.h @@ -55,8 +55,8 @@ #include #include -extern const char *amqp_server_exception_string(amqp_rpc_reply_t r); -extern const char *amqp_rpc_reply_string(amqp_rpc_reply_t r); +extern char *amqp_server_exception_string(amqp_rpc_reply_t r); +extern char *amqp_rpc_reply_string(amqp_rpc_reply_t r); extern void die(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -- cgit v1.2.1 From eb2d565d5074f9a8a51ebd7234c986d0087d21dc Mon Sep 17 00:00:00 2001 From: David Wragg Date: Wed, 28 Jul 2010 22:48:19 +0100 Subject: Fix typo and improve a few sentences around it. --- README.windows | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.windows b/README.windows index e4ae433..33c8f06 100644 --- a/README.windows +++ b/README.windows @@ -21,13 +21,13 @@ build native Windows applications and DLLs, which do not depend on MinGW/MSYS to run. So to build rabbitmq-c on Windows, you need to download and install -the relevant parts of MinGW/MSYS. This can be a fairly time consuming -process - there are about 20 files to be downloaded and unpacked. To -make it easier, we provide a bash script that automates this process, -in rabbitmq-c/etc/install-mingw.sh. You can run this cygwin, or under -Linux and copy the results over or put them on a shared drive. Some -MinGW packages are .tar.lzma files, so it requires a system with xz -and a tar that supports the -J option, which probably rules out OSX. +the relevant parts of MinGW/MSYS. This can be fairly time consuming - +there are dozens of files to be downloaded and unpacked. To make it +easier, we provide a bash script that automates this process, in +rabbitmq-c/etc/install-mingw.sh. You can run this under cygwin, or +under Linux and copy the results over or put them on a shared drive. +Some MinGW packages are .tar.lzma files, so it requires a system with +the xz compression utility and a tar that supports the -J option. Run install-mingw.sh specifying the destination directory, e.g. -- cgit v1.2.1 From 8edd5fb6db1bd629e295e1932e69bfa3ee301e16 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Wed, 28 Jul 2010 23:03:59 +0100 Subject: We were neglecting to free the constructed command line And fix a tyop in an error message. --- tools/windows/process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/windows/process.c b/tools/windows/process.c index 9a0b893..0a005bd 100644 --- a/tools/windows/process.c +++ b/tools/windows/process.c @@ -69,7 +69,7 @@ void die_windows_error(const char *fmt, ...) NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL)) - msg = "(failed to retrieving Windows error message)"; + msg = "(failed to retrieve Windows error message)"; fprintf(stderr, ": %s\n", msg); exit(1); @@ -170,6 +170,8 @@ void pipeline(const char *const *argv, struct pipeline *pl) NULL, NULL, &start_info, &proc_info)) die_windows_error("CreateProcess"); + free(cmdline); + if (!CloseHandle(proc_info.hThread)) die_windows_error("CloseHandle for thread"); if (!CloseHandle(in_read_handle)) -- cgit v1.2.1 From 03e4053a1bc5c77f16f772170e6acfadf51e12de Mon Sep 17 00:00:00 2001 From: Alexandru Scvortov Date: Wed, 4 Aug 2010 15:44:56 +0100 Subject: updated rabbitmq-c to the latest codegen --- configure.ac | 2 +- librabbitmq/amqp_socket.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8d6c987..be7e695 100644 --- a/configure.ac +++ b/configure.ac @@ -51,7 +51,7 @@ AC_ARG_ENABLE(64-bit, AC_MSG_CHECKING(location of AMQP codegen directory) sibling_codegen_dir="$ac_abs_confdir/../rabbitmq-codegen" AMQP_CODEGEN_DIR=$(test -d "$sibling_codegen_dir" && echo "$sibling_codegen_dir" || echo "$ac_abs_confdir/codegen") -AMQP_SPEC_JSON_PATH="$AMQP_CODEGEN_DIR/amqp-0.9.1.json" +AMQP_SPEC_JSON_PATH="$AMQP_CODEGEN_DIR/amqp-rabbitmq-0.9.1.json" if test -f "$AMQP_SPEC_JSON_PATH" then diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index b7776ea..f940df2 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -480,8 +480,8 @@ amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, amqp_connection_open_t s = (amqp_connection_open_t) { .virtual_host = amqp_cstring_bytes(vhost), - .deprecated_capabilities = {.len = 0, .bytes = NULL}, - .deprecated_insist = 1 + .capabilities = {.len = 0, .bytes = NULL}, + .insist = 1 }; amqp_method_number_t replies[] = { AMQP_CONNECTION_OPEN_OK_METHOD, 0 }; result = amqp_simple_rpc(state, -- cgit v1.2.1 From fb9f632aadd6160fd73973dee758c1d64873f694 Mon Sep 17 00:00:00 2001 From: Alexandru Scvortov Date: Wed, 4 Aug 2010 17:00:54 +0100 Subject: it's called routing_key in the spec --- librabbitmq/amqp.h | 2 +- librabbitmq/amqp_api.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index c10c100..683f13a 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -441,7 +441,7 @@ extern struct amqp_queue_unbind_ok_t_ *amqp_queue_unbind(amqp_connection_state_t amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, - amqp_bytes_t binding_key, + amqp_bytes_t routing_key, amqp_table_t arguments); extern struct amqp_basic_consume_ok_t_ *amqp_basic_consume(amqp_connection_state_t state, diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c index 27fe19a..82f33e1 100644 --- a/librabbitmq/amqp_api.c +++ b/librabbitmq/amqp_api.c @@ -253,13 +253,13 @@ amqp_queue_unbind_ok_t *amqp_queue_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, - amqp_bytes_t binding_key, + amqp_bytes_t routing_key, amqp_table_t arguments) { state->most_recent_api_result = AMQP_SIMPLE_RPC(state, channel, QUEUE, UNBIND, UNBIND_OK, amqp_queue_unbind_t, - 0, queue, exchange, binding_key, arguments); + 0, queue, exchange, routing_key, arguments); return RPC_REPLY(amqp_queue_unbind_ok_t); } -- cgit v1.2.1 From 29288206c95db0ff055eb710492d833a3d44e314 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Thu, 5 Aug 2010 14:45:21 +0100 Subject: Update for recent changes to rabbitmq-codegen --- configure.ac | 10 +--------- librabbitmq/Makefile.am | 8 ++++---- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 7217440..ce72632 100644 --- a/configure.ac +++ b/configure.ac @@ -51,8 +51,7 @@ AC_ARG_ENABLE(64-bit, AC_MSG_CHECKING(location of AMQP codegen directory) sibling_codegen_dir="$ac_abs_confdir/../rabbitmq-codegen" AMQP_CODEGEN_DIR=$(test -d "$sibling_codegen_dir" && echo "$sibling_codegen_dir" || echo "$ac_abs_confdir/codegen") -AMQP_SPEC_JSON_PATH="$AMQP_CODEGEN_DIR/amqp-0.8.json" -AMQP_EXTENSIONS_JSON_PATH="$AMQP_CODEGEN_DIR/rabbitmq-0.8-extensions.json" +AMQP_SPEC_JSON_PATH="$AMQP_CODEGEN_DIR/amqp-rabbitmq-0.8.json" if test -f "$AMQP_SPEC_JSON_PATH" then @@ -61,13 +60,6 @@ else AC_MSG_ERROR(could not find AMQP spec file at "'$AMQP_SPEC_JSON_PATH'") fi -if test -f "$AMQP_EXTENSIONS_JSON_PATH" -then - AC_MSG_RESULT($AMQP_EXTENSIONS_DIR) -else - AC_MSG_ERROR(could not find extensions spec file at "'$AMQP_EXTENSIONS_JSON_PATH'") -fi - AC_MSG_CHECKING(finding a python with simplejson installed) found_python=no checkPython() { diff --git a/librabbitmq/Makefile.am b/librabbitmq/Makefile.am index 203a6fc..35680d0 100644 --- a/librabbitmq/Makefile.am +++ b/librabbitmq/Makefile.am @@ -16,8 +16,8 @@ EXTRA_DIST = \ CODEGEN_PY=$(srcdir)/codegen.py -amqp_framing.h: $(AMQP_SPEC_JSON_PATH) $(AMQP_EXTENSIONS_JSON_PATH) $(CODEGEN_PY) - PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) header $< $(AMQP_EXTENSIONS_JSON_PATH) $@ +amqp_framing.h: $(AMQP_SPEC_JSON_PATH) $(CODEGEN_PY) + PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) header $< $@ -amqp_framing.c: $(AMQP_SPEC_JSON_PATH) $(AMQP_EXTENSIONS_JSON_PATH) $(CODEGEN_PY) - PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) body $< $(AMQP_EXTENSIONS_JSON_PATH) $@ +amqp_framing.c: $(AMQP_SPEC_JSON_PATH) $(CODEGEN_PY) + PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) body $< $@ -- cgit v1.2.1 From 26a00344df14c603c562439e6f1f1d50d0f1d11d Mon Sep 17 00:00:00 2001 From: David Wragg Date: Thu, 5 Aug 2010 18:00:15 +0100 Subject: Remove redundant reference to AMQP_EXTENSIONS_JSON_PATH --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index ce72632..904d4ef 100644 --- a/configure.ac +++ b/configure.ac @@ -85,7 +85,6 @@ fi AC_SUBST(AMQP_CODEGEN_DIR) AC_SUBST(AMQP_SPEC_JSON_PATH) -AC_SUBST(AMQP_EXTENSIONS_JSON_PATH) AC_SUBST(PYTHON) dnl Decide which extra win32 libs we need -- cgit v1.2.1 From 5929e7cc940c2c43ae3b2e37ead5aa2145da05a4 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sat, 7 Aug 2010 19:16:02 +0100 Subject: make distcheck was failing because of a missing $(srcdir) relative-reference --- librabbitmq/Makefile.am | 2 +- tools/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/librabbitmq/Makefile.am b/librabbitmq/Makefile.am index 35680d0..82b9f30 100644 --- a/librabbitmq/Makefile.am +++ b/librabbitmq/Makefile.am @@ -1,6 +1,6 @@ lib_LTLIBRARIES = librabbitmq.la -AM_CFLAGS = -I$(PLATFORM_DIR) +AM_CFLAGS = -I$(srcdir)/$(PLATFORM_DIR) librabbitmq_la_SOURCES = amqp_mem.c amqp_table.c amqp_connection.c amqp_socket.c amqp_debug.c amqp_api.c $(PLATFORM_DIR)/socket.c librabbitmq_la_LDFLAGS = -no-undefined librabbitmq_la_LIBADD = $(EXTRA_LIBS) diff --git a/tools/Makefile.am b/tools/Makefile.am index ef7a9bc..ccd36ca 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS=doc bin_PROGRAMS = amqp-publish amqp-get amqp-consume amqp-declare-queue amqp-delete-queue -AM_CFLAGS = -I$(top_srcdir)/librabbitmq -I$(PLATFORM_DIR) +AM_CFLAGS = -I$(top_srcdir)/librabbitmq -I$(srcdir)/$(PLATFORM_DIR) AM_LDFLAGS = $(top_builddir)/librabbitmq/librabbitmq.la LDADD=$(LIBPOPT) -- cgit v1.2.1 From 0a7540f14ce26b9c1f6fba4996c8096cfdce4890 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Sun, 8 Aug 2010 00:11:43 +0100 Subject: Refine amqp-consume options for 0-9-1 queue declaration semantics --- tools/consume.c | 90 +++++++++++++++++++++------------------------------ tools/doc/consume.xml | 58 +++++++++++++++++---------------- 2 files changed, 67 insertions(+), 81 deletions(-) diff --git a/tools/consume.c b/tools/consume.c index 2117bba..a641708 100644 --- a/tools/consume.c +++ b/tools/consume.c @@ -84,61 +84,45 @@ static char *stringify_bytes(amqp_bytes_t bytes) static amqp_bytes_t setup_queue(amqp_connection_state_t conn, char *queue, char *exchange, - char *exchange_type, char *routing_key) + char *routing_key, int declare) { - amqp_bytes_t queue_bytes; - amqp_queue_declare_ok_t *res; + amqp_bytes_t queue_bytes = cstring_bytes(queue); /* if an exchange name wasn't provided, check that we don't have options that require it. */ - if (!exchange) { - char *opt = NULL; - if (routing_key) - opt = "--routing-key"; - else if (exchange_type) - opt = "--exchange-type"; - - if (opt) { - fprintf(stderr, - "%s option requires an exchange name to be " - "provided with --exchange\n", opt); - exit(1); - } + if (!exchange && routing_key) { + fprintf(stderr, "--routing-key option requires an exchange" + " name to be provided with --exchange\n"); + exit(1); } - /* Declare the queue as auto-delete. If the queue already - exists, this won't have any effect. */ - queue_bytes = cstring_bytes(queue); - res = amqp_queue_declare(conn, 1, queue_bytes, 0, 0, 0, 1, - AMQP_EMPTY_TABLE); - if (!res) - die_rpc(amqp_get_rpc_reply(conn), "queue.declare"); - - if (!queue) { - /* the server should have provided a queue name */ - char *sq; - queue_bytes = amqp_bytes_malloc_dup(res->queue); - sq = stringify_bytes(queue_bytes); - fprintf(stderr, "Server provided queue name: %s\n", sq); - free(sq); - } + if (!queue || exchange || declare) { + /* Declare the queue as auto-delete. */ + amqp_queue_declare_ok_t *res = amqp_queue_declare(conn, 1, + queue_bytes, 0, 0, 1, 1, + AMQP_EMPTY_TABLE); + if (!res) + die_rpc(amqp_get_rpc_reply(conn), "queue.declare"); + + if (!queue) { + /* the server should have provided a queue name */ + char *sq; + queue_bytes = amqp_bytes_malloc_dup(res->queue); + sq = stringify_bytes(queue_bytes); + fprintf(stderr, "Server provided queue name: %s\n", + sq); + free(sq); + } - /* Bind to an exchange if requested */ - if (exchange) { - amqp_bytes_t eb = amqp_cstring_bytes(exchange); - - if (exchange_type) { - /* we should create the exchange */ - if (!amqp_exchange_declare(conn, 1, eb, - amqp_cstring_bytes(exchange_type), - 0, 0, 1, AMQP_EMPTY_TABLE)) - die_rpc(amqp_get_rpc_reply(conn), "exchange.declare"); + /* Bind to an exchange if requested */ + if (exchange) { + amqp_bytes_t eb = amqp_cstring_bytes(exchange); + if (!amqp_queue_bind(conn, 1, queue_bytes, eb, + cstring_bytes(routing_key), + AMQP_EMPTY_TABLE)) + die_rpc(amqp_get_rpc_reply(conn), + "queue.bind"); } - - if (!amqp_queue_bind(conn, 1, queue_bytes, eb, - cstring_bytes(routing_key), - AMQP_EMPTY_TABLE)) - die_rpc(amqp_get_rpc_reply(conn), "queue.bind"); } return queue_bytes; @@ -181,13 +165,13 @@ static void do_consume(amqp_connection_state_t conn, amqp_bytes_t queue, int main(int argc, const char **argv) { poptContext opts; - int no_ack; amqp_connection_state_t conn; const char * const *cmd_argv; char *queue = NULL; char *exchange = NULL; - char *exchange_type = NULL; char *routing_key = NULL; + int declare; + int no_ack; amqp_bytes_t queue_bytes; struct poptOption options[] = { @@ -196,11 +180,10 @@ int main(int argc, const char **argv) "the queue to consume from", "queue"}, {"exchange", 'e', POPT_ARG_STRING, &exchange, 0, "bind the queue to this exchange", "exchange"}, - {"exchange-type", 't', POPT_ARG_STRING, &exchange_type, 0, - "create auto-delete exchange of this type for binding", - "type"}, {"routing-key", 'r', POPT_ARG_STRING, &routing_key, 0, "the routing key to bind with", "routing key"}, + {"declare", 'd', POPT_ARG_NONE, &declare, 0, + "declare an exclusive queue", NULL}, {"no-ack", 'A', POPT_ARG_NONE, &no_ack, 0, "consume in no-ack mode", NULL}, POPT_AUTOHELP @@ -218,8 +201,7 @@ int main(int argc, const char **argv) } conn = make_connection(); - queue_bytes = setup_queue(conn, queue, exchange, exchange_type, - routing_key); + queue_bytes = setup_queue(conn, queue, exchange, routing_key, declare); do_consume(conn, queue_bytes, no_ack, cmd_argv); close_connection(conn); return 0; diff --git a/tools/doc/consume.xml b/tools/doc/consume.xml index 448ade6..16d61ad 100644 --- a/tools/doc/consume.xml +++ b/tools/doc/consume.xml @@ -50,8 +50,7 @@ amqp-consume can consume from an existing queue, or it can create a new queue. It can - optionally bind the queue to an existing exchange, or to a - newly created exchange. + optionally bind the queue to an existing exchange. By default, messages will be consumed with explicit @@ -72,13 +71,16 @@ The name of the queue to consume messages - from. If the specified queue does not exist, - an auto-delete queue is created with the given - name. If this option is omitted, a new - auto-delete queue will be created, with a - unique name assigned to the queue by the AMQP - server; that unique name will be displayed on - stderr. + from. + + + + If the option is + omitted, the AMQP server will assign a unique + name to the queue, and that server-assigned + name will be dixsplayed on stderr; this case + implies that an exclusive queue should be + declared. @@ -87,34 +89,36 @@ =exchange name - The name of the exchange to bind the queue to. - If omitted, binding is not performed. The - specified exchange should already exist unless - the option is - used to request the creation of an exchange. + Specifies that an exclusive queue should + be declared, and bound to the given exchange. + The specified exchange should already exist + unless the + option is used to request the creation of an + exchange. - - =type + + =routing key - This option indicates that an auto-delete - exchange of the specified type should be - created. The name of the exchange should be - given by the - option. + The routing key for binding. If omitted, an + empty routing key is assumed. - - =routing key + + - The routing key for the binding. If omitted, - an empty routing key is assumed. + Forces an exclusive queue to be declared, + even when it otherwise would not. That is, + when a queue name is specified with the + option, but no + binding to an exchange is requested with the + option. @@ -138,7 +142,7 @@ Examples - Consume messages from the queue + Consume messages from an existing queue myqueue, and output the message bodies on standard output via @@ -149,7 +153,7 @@ - Bind a newly created auto-delete queue to an + Bind a new exclusive queue to an exchange myexch, and send each message body to the script -- cgit v1.2.1 From 55a5ffa8b12a5b1de877e820786be814131340e6 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Mon, 9 Aug 2010 17:30:09 +0100 Subject: add missing initializers --- tools/consume.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/consume.c b/tools/consume.c index a641708..943406b 100644 --- a/tools/consume.c +++ b/tools/consume.c @@ -170,8 +170,8 @@ int main(int argc, const char **argv) char *queue = NULL; char *exchange = NULL; char *routing_key = NULL; - int declare; - int no_ack; + int declare = 0; + int no_ack = 0; amqp_bytes_t queue_bytes; struct poptOption options[] = { -- cgit v1.2.1 From 16d14c5473908ac7e61a88a543c64385469cd0ee Mon Sep 17 00:00:00 2001 From: David Wragg Date: Wed, 11 Aug 2010 15:26:38 +0100 Subject: Update MinGW URLs --- etc/install-mingw.sh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/etc/install-mingw.sh b/etc/install-mingw.sh index 891c6fe..af70576 100755 --- a/etc/install-mingw.sh +++ b/etc/install-mingw.sh @@ -23,7 +23,7 @@ done < Date: Mon, 16 Aug 2010 10:54:27 +0100 Subject: remove superfluous code --- librabbitmq/amqp_socket.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index f940df2..13f6376 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -104,17 +104,10 @@ static char *header() { header[1] = 'M'; header[2] = 'Q'; header[3] = 'P'; -#ifndef USE_MODERN_AMQP_PROTOCOL_HEADER - header[4] = 1; - header[5] = 1; - header[6] = AMQP_PROTOCOL_VERSION_MAJOR; - header[7] = AMQP_PROTOCOL_VERSION_MINOR; -#else header[4] = 0; header[5] = AMQP_PROTOCOL_VERSION_MAJOR; header[6] = AMQP_PROTOCOL_VERSION_MINOR; header[7] = AMQP_PROTOCOL_VERSION_REVISION; -#endif return header; } -- cgit v1.2.1 From 10cefe79af380e0402907683a60f93ab9850fdca Mon Sep 17 00:00:00 2001 From: Alexandru Scvortov Date: Mon, 16 Aug 2010 13:35:08 +0100 Subject: removed auto-delete parameter from exchange.declare --- examples/amqp_exchange_declare.c | 2 +- librabbitmq/amqp.h | 1 - librabbitmq/amqp_api.c | 3 +-- tools/consume.c | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/amqp_exchange_declare.c b/examples/amqp_exchange_declare.c index 27bff1a..e77ac52 100644 --- a/examples/amqp_exchange_declare.c +++ b/examples/amqp_exchange_declare.c @@ -89,7 +89,7 @@ int main(int argc, char const * const *argv) { die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange), amqp_cstring_bytes(exchangetype), - 0, 0, 0, AMQP_EMPTY_TABLE); + 0, 0, AMQP_EMPTY_TABLE); die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring exchange"); die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h index 683f13a..40c8292 100644 --- a/librabbitmq/amqp.h +++ b/librabbitmq/amqp.h @@ -412,7 +412,6 @@ extern struct amqp_exchange_declare_ok_t_ *amqp_exchange_declare(amqp_connection amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable, - amqp_boolean_t auto_delete, amqp_table_t arguments); extern struct amqp_queue_declare_ok_t_ *amqp_queue_declare(amqp_connection_state_t state, diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c index 82f33e1..b2793ff 100644 --- a/librabbitmq/amqp_api.c +++ b/librabbitmq/amqp_api.c @@ -196,13 +196,12 @@ amqp_exchange_declare_ok_t *amqp_exchange_declare(amqp_connection_state_t state, amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable, - amqp_boolean_t auto_delete, amqp_table_t arguments) { state->most_recent_api_result = AMQP_SIMPLE_RPC(state, channel, EXCHANGE, DECLARE, DECLARE_OK, amqp_exchange_declare_t, - 0, exchange, type, passive, durable, auto_delete, 0, 0, arguments); + 0, exchange, type, passive, durable, 0, 0, 0, arguments); return RPC_REPLY(amqp_exchange_declare_ok_t); } diff --git a/tools/consume.c b/tools/consume.c index 0d50228..146b0a7 100644 --- a/tools/consume.c +++ b/tools/consume.c @@ -131,7 +131,7 @@ static amqp_bytes_t setup_queue(amqp_connection_state_t conn, /* we should create the exchange */ if (!amqp_exchange_declare(conn, 1, eb, amqp_cstring_bytes(exchange_type), - 0, 0, 1, AMQP_EMPTY_TABLE)) + 0, 0, AMQP_EMPTY_TABLE)) die_rpc(amqp_get_rpc_reply(conn), "exchange.declare"); } -- cgit v1.2.1 From 1b1340ad50e18edc194f26a7156cab44b8a1bba0 Mon Sep 17 00:00:00 2001 From: Alexandru Scvortov Date: Thu, 26 Aug 2010 11:16:40 +0100 Subject: removed references to the 0-9-1 branch in README --- README | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/README b/README index 3d68ad1..6ae88dc 100644 --- a/README +++ b/README @@ -3,22 +3,17 @@ ## Introduction This is a C-language AMQP client library for use with AMQP servers -speaking protocol versions 0-8 and 0-9-1. +speaking protocol versions 0-9-1. - - - -*NB*: This library's source code supports *either* 0-8 *or* 0-9-1, not -both simultaneously. Please check carefully that you have the variant -you require. - Announcements regarding the library are periodically made on the -RabbitMQ mailing list and on LShift's blog. +RabbitMQ mailing list and on the RabbitMQ blog. - - - - - + - ## Retrieving the code @@ -91,25 +86,3 @@ access an AMQP connection or any of its channels from more than one thread, it is entirely responsible for designing and implementing an appropriate locking scheme. It will generally be much simpler to have a connection exclusive to each thread that needs AMQP service. - -### Switching the codebase to the 0-9-1 protocol version - -In current releases, the default (trunk) branch of the mercurial -repository hosting the `rabbitmq-c` code is set up for AMQP 0-8 -support, with AMQP 0-9-1 support living on a separate mercurial -branch. - -NOTE: Protocol versions 0-8 and 0-9-1 are incompatible on the -wire. You cannot use a client library that speaks one protocol version -to communication with a server that speaks the other. - -To switch your checked-out copy of the source code to 0-9-1 -support, - - (cd rabbitmq-codegen; hg up amqp_0_9_1) - (cd rabbitmq-c; hg up amqp_0_9_1) - -before building the code. If you switch branches after having compiled -the code, make sure to rerun `autoreconf`, `configure`, `make clean` -and `make` after switching branches. - -- cgit v1.2.1