rework error to use a struct error_desc, and move ERR_SOCK/ERR_GNUTLS definitions to sock.h/sock_gnutls.h. error_desc definitions are still in error.c, though :(
--- a/src/error.c Tue Mar 10 02:51:44 2009 +0200
+++ b/src/error.c Tue Mar 10 03:27:04 2009 +0200
@@ -1,70 +1,127 @@
#include "error.h"
+// for the error_desc tables
+#include "sock.h"
+#include "sock_gnutls.h"
+
#include <string.h>
#include <stdio.h>
-#include <netdb.h>
-#include <gnutls/gnutls.h>
+struct error_desc _core_error_desc[] = {
+ { ERR_CALLOC, "calloc", ERR_EXTRA_NONE },
+ { ERR_GETADDRINFO, "getaddrinfo", ERR_EXTRA_GAI },
+ { ERR_GETADDRINFO_EMPTY, "getaddrinfo: no results", ERR_EXTRA_NONE },
+ { ERR_EVENT_NEW, "event_new", ERR_EXTRA_NONE },
+ { ERR_EVENT_ADD, "event_add", ERR_EXTRA_NONE },
+ { ERR_EVSQL_NEW_PQ, "evsql_new_pq", ERR_EXTRA_NONE },
+};
-/*
- * Helper macros
+struct error_desc _sock_error_desc[] = {
+ { ERR_SOCKET, "socket", ERR_EXTRA_ERRNO },
+ { ERR_CONNECT, "connect", ERR_EXTRA_ERRNO },
+ { ERR_READ, "read", ERR_EXTRA_ERRNO },
+ { ERR_READ_EOF, "read: EOF", ERR_EXTRA_NONE },
+ { ERR_WRITE, "write", ERR_EXTRA_ERRNO },
+ { ERR_WRITE_EOF, "write: EOF", ERR_EXTRA_NONE },
+ { ERR_FCNTL, "fcntl", ERR_EXTRA_ERRNO },
+ { ERR_CLOSE, "close", ERR_EXTRA_ERRNO },
+ { _ERR_INVALID, NULL, 0 }
+};
+
+struct error_desc _sock_gnutls_error_desc[] = {
+ { ERR_GNUTLS_CERT_ALLOC_CRED, "gnutls_certificate_allocate_credentials", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_GLOBAL_INIT, "gnutls_global_init", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_SET_DEFAULT_PRIORITY,"gnutls_set_default_priority", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_CRED_SET, "gnutls_credentials_set", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_HANDSHAKE, "gnutls_handshake", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_RECORD_SEND, "gnutls_record_send", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_RECORD_RECV, "gnutls_record_recv", ERR_EXTRA_GNUTLS },
+ { ERR_GNUTLS_RECORD_GET_DIRECTION,"gnutls_record_get_direction", ERR_EXTRA_GNUTLS },
+ { _ERR_INVALID, NULL, 0 }
+};
+
+/**
+ * Array of error_desc tables
*/
-#define ERROR_NAME(code, name) case code: return name
+static struct error_desc* _desc_tables[] = {
+ _core_error_desc,
+ _sock_error_desc,
+ _sock_gnutls_error_desc,
+ NULL
+};
+
+/**
+ * Look up the error_desc for the given error code
+ */
+static const struct error_desc* error_lookup_desc (err_t code)
+{
+ struct error_desc **desc_table, *desc = NULL;
+
+ // iterate over each defined error_desc array
+ for (desc_table = _desc_tables; desc_table; desc_table++) {
+ for (desc = *desc_table; desc->code && desc->name; desc++) {
+ // compare code
+ if (desc->code == code)
+ // found
+ return desc;
+ }
+ }
+
+ // not found
+ return NULL;
+}
const char *error_name (err_t code)
{
- switch (code) {
- ERROR_NAME( ERR_CALLOC, "calloc" );
- ERROR_NAME( ERR_GETADDRINFO, "getaddrinfo" );
- ERROR_NAME( ERR_GETADDRINFO_EMPTY, "getaddrinfo: no results" );
- ERROR_NAME( ERR_SOCKET, "socket" );
- ERROR_NAME( ERR_CONNECT, "connect" );
- ERROR_NAME( ERR_READ, "read" );
- ERROR_NAME( ERR_READ_EOF, "read: EOF" );
- ERROR_NAME( ERR_WRITE, "write" );
- ERROR_NAME( ERR_FCNTL, "fcntl" );
- ERROR_NAME( ERR_GNUTLS_CERT_ALLOC_CRED, "gnutls_certificate_allocate_credentials" );
- ERROR_NAME( ERR_GNUTLS_GLOBAL_INIT, "gnutls_global_init" );
- ERROR_NAME( ERR_GNUTLS_INIT, "gnutls_init" );
- ERROR_NAME( ERR_GNUTLS_SET_DEFAULT_PRIORITY, "gnutls_set_default_priority" );
- ERROR_NAME( ERR_GNUTLS_CRED_SET, "gnutls_credentials_set" );
- ERROR_NAME( ERR_GNUTLS_HANDSHAKE, "gnutls_handshake" );
- default: return "[unknown]";
- }
+ const struct error_desc *desc;
+
+ // do we have an error_desc for it?
+ if ((desc = error_lookup_desc(code)))
+ return desc->name;
+ else
+ // unknown
+ return "[unknown]";
}
const char *error_msg (const struct error_info *err)
{
static char msg[ERROR_MSG_MAXLEN];
-
- // intrepret .extra
- switch (err->code & _ERR_EXTRA_MASK) {
- case ERR_EXTRA_NONE:
- // no additional info
- snprintf(msg, ERROR_MSG_MAXLEN, "%s", error_name(err->code));
- break;
-
- case ERR_EXTRA_ERRNO:
- // strerror
- snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), strerror(err->extra));
- break;
-
- case ERR_EXTRA_GAI:
- // gai_strerror
- snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), gai_strerror(err->extra));
- break;
-
- case ERR_EXTRA_GNUTLS:
- // gnutls_strerror
- snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), gnutls_strerror(err->extra));
- break;
-
- default:
- // ???
- snprintf(msg, ERROR_MSG_MAXLEN, "%s(%#.8x): %#.8x", error_name(err->code), err->code, err->extra);
- break;
- }
+ const struct error_desc *desc;
+
+ // do we have an error_desc for it?
+ if ((desc = error_lookup_desc(err->code)) == NULL)
+ // ???
+ snprintf(msg, ERROR_MSG_MAXLEN, "[%#.8x]: %#.8x", err->code, err->extra);
+
+ else
+ // intrepret .extra
+ switch (desc->extra_type) {
+ case ERR_EXTRA_NONE:
+ // no additional info
+ snprintf(msg, ERROR_MSG_MAXLEN, "%s", desc->name);
+ break;
+
+ case ERR_EXTRA_ERRNO:
+ // strerror
+ snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, strerror(err->extra));
+ break;
+
+ case ERR_EXTRA_GAI:
+ // gai_strerror
+ snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gai_strerror(err->extra));
+ break;
+
+ case ERR_EXTRA_GNUTLS:
+ // gnutls_strerror
+ snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra));
+ break;
+
+ default:
+ // ???
+ snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra);
+ break;
+ }
// return static pointer
return msg;
--- a/src/error.h Tue Mar 10 02:51:44 2009 +0200
+++ b/src/error.h Tue Mar 10 03:27:04 2009 +0200
@@ -12,75 +12,74 @@
*/
typedef unsigned int err_t;
-/*
- * Bitmask of error_info.extra meanings
+/**
+ * Ways to interpret error_info.extra
*/
enum error_extra_types {
- // bit offset of ERR_EXTRA_* mask in error_code
- _ERR_EXTRA_OFFSET = 3 * 8,
-
- // mask of bits used for the error_extra_types value
- _ERR_EXTRA_MASK = 0xff << _ERR_EXTRA_OFFSET,
+ ERR_EXTRA_NONE = 0,
- ERR_EXTRA_NONE = 0x00 << _ERR_EXTRA_OFFSET,
- ERR_EXTRA_ERRNO = 0x01 << _ERR_EXTRA_OFFSET,
- ERR_EXTRA_GAI = 0x02 << _ERR_EXTRA_OFFSET,
- ERR_EXTRA_GNUTLS = 0x03 << _ERR_EXTRA_OFFSET,
-
+ /** libc errno, using strerror() */
+ ERR_EXTRA_ERRNO,
+
+ /** libc resolver, using gai_strerror() */
+ ERR_EXTRA_GAI,
+
+ /** gnutls, using gnutls_strerror() */
+ ERR_EXTRA_GNUTLS,
};
-
-#define _ERROR_CODE(name, code, extra) name = (code | ERR_EXTRA_ ## extra)
-/*
+/**
* List of defined error codes, organized mostly by function name
*/
enum error_code {
- /* Core functions */
- _ERROR_CODE( ERR_CALLOC, 0x000100, NONE ),
+ _ERR_INVALID = 0x000000,
- /* Network resolver errors */
- _ERROR_CODE( ERR_GETADDRINFO, 0x000200, GAI ),
- _ERROR_CODE( ERR_GETADDRINFO_EMPTY, 0x000201, NONE ),
-
- /* Low-level network errors */
- _ERROR_CODE( ERR_SOCKET, 0x000301, ERRNO ),
- _ERROR_CODE( ERR_CONNECT, 0x000302, ERRNO ),
-
- /* Low-level IO errors */
- _ERROR_CODE( ERR_READ, 0x000401, ERRNO ),
- _ERROR_CODE( ERR_READ_EOF, 0x000402, NONE ),
- _ERROR_CODE( ERR_WRITE, 0x000403, ERRNO ),
- _ERROR_CODE( ERR_WRITE_EOF, 0x000404, NONE ),
- _ERROR_CODE( ERR_FCNTL, 0x000405, ERRNO ),
- _ERROR_CODE( ERR_CLOSE, 0x000406, ERRNO ),
+ /** stdlib.h functions */
+ _ERR_STDLIB = 0x000100,
+ ERR_CALLOC,
+
+ /** DNS resolver */
+ _ERR_RESOLVER = 0x000200,
+ ERR_GETADDRINFO,
+ ERR_GETADDRINFO_EMPTY,
+
+ /** @see enum sock_error_code*/
+ _ERR_SOCK = 0x000300,
- /* GnuTLS errors */
- _ERROR_CODE( ERR_GNUTLS_CERT_ALLOC_CRED, 0x010101, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_GLOBAL_INIT, 0x010102, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_INIT, 0x010103, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_SET_DEFAULT_PRIORITY, 0x010104, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_CRED_SET, 0x010105, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_HANDSHAKE, 0x010106, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_RECORD_SEND, 0x010107, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_RECORD_RECV, 0x010108, GNUTLS ),
- _ERROR_CODE( ERR_GNUTLS_RECORD_GET_DIRECTION, 0x010109, GNUTLS ),
+ /** @see enum sock_gnutls_error_code */
+ _ERR_GNUTLS = 0x000400,
- /* Libevent errors */
- _ERROR_CODE( ERR_EVENT_NEW, 0x010201, NONE ),
- _ERROR_CODE( ERR_EVENT_ADD, 0x010202, NONE ),
+ /** Libevent errors */
+ _ERR_LIBEVENT = 0x000500,
+ ERR_EVENT_NEW,
+ ERR_EVENT_ADD,
- /* Evsql errors */
- _ERROR_CODE( ERR_EVSQL_NEW_PQ, 0x010301, NONE ),
+ /** Evsql errors */
+ _ERR_EVSQL = 0x000600,
+ ERR_EVSQL_NEW_PQ,
- /* irc_line errors */
- _ERROR_CODE( ERR_LINE_TOO_LONG, 0x100101, NONE ),
- _ERROR_CODE( ERR_LINE_INVALID_TOKEN, 0x100102, NONE ),
+ /** irc_line errors */
+ _ERR_IRC_LINE = 0x000700,
+ ERR_LINE_TOO_LONG,
+ ERR_LINE_INVALID_TOKEN,
/** irc_conn errors */
- _ERROR_CODE( ERR_IRC_CONN_REGISTER_STATE, 0x100201, NONE ),
-
- // mask of bits used for the error_code value
- _ERROR_CODE_MASK = 0xffffff,
+ _ERR_IRC_CONN = 0x000800,
+ ERR_IRC_CONN_REGISTER_STATE,
+};
+
+/**
+ * Table of error descriptions
+ */
+struct error_desc {
+ /** The flat error code */
+ err_t code;
+
+ /** The short name */
+ const char *name;
+
+ /** How to interpret .extra */
+ enum error_extra_types extra_type;
};
/*
--- a/src/sock.h Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock.h Tue Mar 10 03:27:04 2009 +0200
@@ -24,6 +24,34 @@
void (*on_write)(struct sock_stream *sock, void *arg);
};
+enum sock_error_code {
+ _ERR_SOCK_BEGIN = _ERR_SOCK,
+
+ /** socket() error */
+ ERR_SOCKET,
+
+ /** connect() error */
+ ERR_CONNECT,
+
+ /** read() error */
+ ERR_READ,
+
+ /** EOF on read() */
+ ERR_READ_EOF,
+
+ /** write() error */
+ ERR_WRITE,
+
+ /** EOF on write() */
+ ERR_WRITE_EOF,
+
+ /** Error on fcntl() */
+ ERR_FCNTL,
+
+ /** Lingering error on close() */
+ ERR_CLOSE,
+};
+
/*
* Initialize the socket module's global state. Call this before calling any other sock_* functions.
*
--- a/src/sock_gnutls.h Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock_gnutls.h Tue Mar 10 03:27:04 2009 +0200
@@ -1,8 +1,10 @@
#ifndef SOCK_GNUTLS_H
#define SOCK_GNUTLS_H
-/*
- * A sock_stream implementation using GnuTLS
+/**
+ * @file
+ *
+ * A sock_stream implementation using GnuTLS for SSL
*/
#include "sock_internal.h"
@@ -10,6 +12,23 @@
#include <gnutls/gnutls.h>
+/**
+ * GnuTLS library error codes
+ */
+enum sock_gnutls_error_code {
+ _ERR_GNUTLS_BEGIN = _ERR_GNUTLS,
+
+ ERR_GNUTLS_CERT_ALLOC_CRED,
+ ERR_GNUTLS_GLOBAL_INIT,
+ ERR_GNUTLS_INIT,
+ ERR_GNUTLS_SET_DEFAULT_PRIORITY,
+ ERR_GNUTLS_CRED_SET,
+ ERR_GNUTLS_HANDSHAKE,
+ ERR_GNUTLS_RECORD_SEND,
+ ERR_GNUTLS_RECORD_RECV,
+ ERR_GNUTLS_RECORD_GET_DIRECTION,
+};
+
/*
* Additional gnutls configuration for client sockets.
*
--- a/src/sock_tcp.c Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock_tcp.c Tue Mar 10 03:27:04 2009 +0200
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
-#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
--- a/src/sock_tcp.h Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock_tcp.h Tue Mar 10 03:27:04 2009 +0200
@@ -7,6 +7,7 @@
* TCP implementation of sock_stream interface.
*/
#include "sock_internal.h"
+#include <netdb.h>
/**
* Contains the base sock_stream struct, and the file descriptor