summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2013-06-13 13:58:58 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2013-06-13 16:40:37 -0700
commit4d9f3abcc30bc628dd872d83233de8744136547d (patch)
treebc1873175e2cc7dffe5f82334109092d006680fe
parent0218bb262b9323f431ed84f5c1d1eb1c5bdb1c8b (diff)
downloadrabbitmq-c-4d9f3abcc30bc628dd872d83233de8744136547d.tar.gz
Change amqp_error_string() to ret static strings
This is an API/ABI break.
-rw-r--r--examples/utils.c4
-rw-r--r--librabbitmq/amqp.h5
-rw-r--r--librabbitmq/amqp_api.c92
-rw-r--r--tools/common.c24
-rw-r--r--tools/common.h4
5 files changed, 86 insertions, 43 deletions
diff --git a/examples/utils.c b/examples/utils.c
index 4b00470..5d4a1f9 100644
--- a/examples/utils.c
+++ b/examples/utils.c
@@ -59,9 +59,7 @@ void die(const char *fmt, ...)
void die_on_error(int x, char const *context)
{
if (x < 0) {
- char *errstr = amqp_error_string(-x);
- fprintf(stderr, "%s: %s\n", context, errstr);
- free(errstr);
+ fprintf(stderr, "%s: %s\n", context, amqp_error_string(x));
exit(1);
}
}
diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h
index 0388bd1..2a0bf19 100644
--- a/librabbitmq/amqp.h
+++ b/librabbitmq/amqp.h
@@ -588,11 +588,10 @@ AMQP_CALL amqp_data_in_buffer(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.
+ * Error string is statically allocated. (API changed in v0.4.0)
*/
AMQP_PUBLIC_FUNCTION
-char *
+const char *
AMQP_CALL amqp_error_string(int err);
AMQP_PUBLIC_FUNCTION
diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c
index cab0f4b..9f65c4c 100644
--- a/librabbitmq/amqp_api.c
+++ b/librabbitmq/amqp_api.c
@@ -46,34 +46,84 @@
#include <stdlib.h>
#include <string.h>
-static const char *client_error_strings[] = {
- "operation completed successfully", /* AMQP_STATUS_OK */
- "could not allocate memory", /* AMQP_STATUS_NO_MEMORY */
- "received bad AMQP data", /* AMQP_STATUS_BAD_AQMP_DATA */
- "unknown AMQP class id", /* AMQP_STATUS_UNKNOWN_CLASS */
- "unknown AMQP method id", /* AMQP_STATUS_UNKNOWN_METHOD */
- "hostname lookup failed", /* AMQP_STATUS_GETHOSTBYNAME_FAILED */
- "incompatible AMQP version", /* AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION */
- "connection closed unexpectedly", /* AMQP_STATUS_CONNECTION_CLOSED */
- "could not parse AMQP URL", /* AMQP_STATUS_BAD_AMQP_URL */
- "a socket error occurred", /* AMQP_STATUS_SOCKET_ERROR */
- "a SSL error occurred" /* AMQP_STATUS_SSL_ERROR */
+#define ERROR_MASK (0x00FF)
+#define ERROR_CATEGORY_MASK (0xFF00)
+
+enum error_category_enum_ {
+ EC_base = 0,
+ EC_tcp = 1,
+ EC_ssl = 2
+};
+
+static const char *base_error_strings[] = {
+ "operation completed successfully", /* AMQP_STATUS_OK 0x0 */
+ "could not allocate memory", /* AMQP_STATUS_NO_MEMORY -0x0001 */
+ "invalid AMQP data", /* AMQP_STATUS_BAD_AQMP_DATA -0x0002 */
+ "unknown AMQP class id", /* AMQP_STATUS_UNKNOWN_CLASS -0x0003 */
+ "unknown AMQP method id", /* AMQP_STATUS_UNKNOWN_METHOD -0x0004 */
+ "hostname lookup failed", /* AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED -0x0005 */
+ "incompatible AMQP version", /* AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION -0x0006 */
+ "connection closed unexpectedly", /* AMQP_STATUS_CONNECTION_CLOSED -0x0007 */
+ "could not parse AMQP URL", /* AMQP_STATUS_BAD_AMQP_URL -0x0008 */
+ "a socket error occurred", /* AMQP_STATUS_SOCKET_ERROR -0x0009 */
+ "invalid parameter", /* AMQP_STATUS_INVALID_PARAMETER -0x000A */
+ "table too large for buffer", /* AMQP_STATUS_TABLE_TOO_BIG -0x000B */
+ "unexpected method received" /* AMQP_STATUS_WRONG_METHOD -0x000C */
+};
+
+static const char *tcp_error_strings[] = {
+ "a socket error occurred", /* AMQP_STATUS_TCP_ERROR -0x0100 */
+ "socket library initialization failed" /* AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR -0x0101 */
+};
+
+static const char *ssl_error_strings[] = {
+ "a SSL error occurred", /* AMQP_STATUS_SSL_ERROR -0x0200 */
+ "SSL hostname verification failed", /* AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED -0x0201 */
+ "SSL peer cert verification failed", /* AMQP_STATUS_SSL_PEER_VERIFY_FAILED -0x0202 */
+ "SSL handshake failed" /* AMQP_STATUS_SSL_CONNECTION_FAILED -0x0203 */
};
-char *amqp_error_string(int err)
+static const char *unknown_error_string = "(unknown error)";
+
+const char *amqp_error_string(int code)
{
- const char *str;
- const int max_error_index = sizeof(client_error_strings) / sizeof(char *);
+ const char *error_string;
+ size_t category = (((-code) & ERROR_CATEGORY_MASK) >> 16);
+ size_t error = (-code) & ERROR_MASK;
+
+ switch (category) {
+ case EC_base:
+ if (error < (sizeof(base_error_strings) / sizeof(char *))) {
+ error_string = base_error_strings[error];
+ } else {
+ error_string = unknown_error_string;
+ }
+ break;
+
+ case EC_tcp:
+ if (error < (sizeof(tcp_error_strings) / sizeof(char *))) {
+ error_string = tcp_error_strings[error];
+ } else {
+ error_string = unknown_error_string;
+ }
+ break;
+
+ case EC_ssl:
+ if (error < (sizeof(ssl_error_strings) / sizeof(char *))) {
+ error_string = ssl_error_strings[error];
+ } else {
+ error_string = unknown_error_string;
+ }
- err = -err;
+ break;
+
+ default:
+ error_string = unknown_error_string;
+ break;
- if (err < 0 || err > max_error_index) {
- str = "an unknown error occurred";
- } else {
- str = client_error_strings[err];
}
- return strdup(str);
+ return error_string;
}
void amqp_abort(const char *fmt, ...)
diff --git a/tools/common.c b/tools/common.c
index 0c61d16..b556988 100644
--- a/tools/common.c
+++ b/tools/common.c
@@ -83,7 +83,6 @@ 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;
@@ -92,21 +91,20 @@ void die_amqp_error(int err, const char *fmt, ...)
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
- fprintf(stderr, ": %s\n", errstr = amqp_error_string(-err));
- free(errstr);
+ fprintf(stderr, ": %s\n", amqp_error_string(err));
exit(1);
}
-char *amqp_server_exception_string(amqp_rpc_reply_t r)
+const char *amqp_server_exception_string(amqp_rpc_reply_t r)
{
int res;
- char *s;
+ static char s[512];
switch (r.reply.id) {
case AMQP_CONNECTION_CLOSE_METHOD: {
amqp_connection_close_t *m
= (amqp_connection_close_t *)r.reply.decoded;
- res = asprintf(&s, "server connection error %d, message: %.*s",
+ res = snprintf(s, sizeof(s), "server connection error %d, message: %.*s",
m->reply_code,
(int)m->reply_text.len,
(char *)m->reply_text.bytes);
@@ -116,7 +114,7 @@ char *amqp_server_exception_string(amqp_rpc_reply_t r)
case AMQP_CHANNEL_CLOSE_METHOD: {
amqp_channel_close_t *m
= (amqp_channel_close_t *)r.reply.decoded;
- res = asprintf(&s, "server channel error %d, message: %.*s",
+ res = snprintf(s, sizeof(s), "server channel error %d, message: %.*s",
m->reply_code,
(int)m->reply_text.len,
(char *)m->reply_text.bytes);
@@ -124,7 +122,7 @@ char *amqp_server_exception_string(amqp_rpc_reply_t r)
}
default:
- res = asprintf(&s, "unknown server error, method id 0x%08X",
+ res = snprintf(s, sizeof(s), "unknown server error, method id 0x%08X",
r.reply.id);
break;
}
@@ -132,14 +130,14 @@ 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)
{
switch (r.reply_type) {
case AMQP_RESPONSE_NORMAL:
- return strdup("normal response");
+ return "normal response";
case AMQP_RESPONSE_NONE:
- return strdup("missing RPC reply type");
+ return "missing RPC reply type";
case AMQP_RESPONSE_LIBRARY_EXCEPTION:
return amqp_error_string(r.library_error);
@@ -155,7 +153,6 @@ 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;
@@ -164,8 +161,7 @@ void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...)
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
- fprintf(stderr, ": %s\n", errstr = amqp_rpc_reply_string(r));
- free(errstr);
+ fprintf(stderr, ": %s\n", amqp_rpc_reply_string(r));
exit(1);
}
diff --git a/tools/common.h b/tools/common.h
index cc186ec..7d01966 100644
--- a/tools/common.h
+++ b/tools/common.h
@@ -41,8 +41,8 @@
#include <amqp.h>
#include <amqp_framing.h>
-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)));