diff --git a/Knot.files b/Knot.files index da54c8ee3721f0170ef9c9864f337b58e0f8099d..b744f70657fc532eef3a636a3941e4268839ef43 100644 --- a/Knot.files +++ b/Knot.files @@ -23,6 +23,8 @@ src/common/base32hex.h src/common/base32hex.c src/common/evqueue.c src/common/evqueue.h +src/common/errors.h +src/common/errors.c src/dnslib/dnslib-common.h src/dnslib/dname.h src/dnslib/dname.c diff --git a/src/Makefile.am b/src/Makefile.am index 13293fcc299e7c436efe7175e1425dcbaa0a3d6c..587cc40f9ae35e5e9985edfa67b57005608c5259 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,6 +93,8 @@ libknot_la_SOURCES = \ common/base32hex.h \ common/evqueue.h \ common/evqueue.c \ + common/errors.h \ + common/errors.c \ knot/stat/gatherer.c \ knot/stat/stat.c \ knot/stat/gatherer.h \ diff --git a/src/common/errors.c b/src/common/errors.c new file mode 100644 index 0000000000000000000000000000000000000000..672c71029a5f66766759f3c07432d5cc295f3006 --- /dev/null +++ b/src/common/errors.c @@ -0,0 +1,58 @@ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "common/errors.h" + +/*! + * \brief Looks up the given id in the lookup table. + * + * \param table Lookup table. + * \param id ID to look up. + * + * \return Item in the lookup table with the given id or NULL if no such is + * present. + */ +static const _knot_error_table_t *error_lookup_by_id( + const _knot_error_table_t *table, int id) +{ + while (table->name != 0) { + if (table->id == id) { + return table; + } + table++; + } + + return 0; +} + +const char *_knot_strerror(_knot_error_table_t *table, int errno) +{ + const _knot_error_table_t *msg = error_lookup_by_id(table, errno); + if (msg != 0) { + return msg->name; + } else { + return "Unknown error."; + } +} + +int __knot_map_errno(int fallback_value, int arg0, ...) +{ + /* Iterate all variable-length arguments. */ + va_list ap; + va_start(ap, arg0); + + /* KNOT_ERROR serves as a sentinel. */ + for (int c = arg0; c != 0; c = va_arg(ap, int)) { + + /* Error code matches with mapped. */ + if (c == errno) { + /* Return negative value of the code. */ + return -abs(c); + } + } + va_end(ap); + + /* Fallback error code. */ + return fallback_value; +} diff --git a/src/common/errors.h b/src/common/errors.h new file mode 100644 index 0000000000000000000000000000000000000000..9f91b456a0654f454dfa36f3846cc82f45372def --- /dev/null +++ b/src/common/errors.h @@ -0,0 +1,65 @@ +/*! + * \file error.h + * + * \author Lubos Slovak <lubos.slovak@nic.cz> + * \author Marek Vavrusa <marek.vavrusa@nic.cz> + * + * \brief Error codes and function for getting error message. + * + * \addtogroup common_lib + * @{ + */ + +#ifndef _KNOT_COMMON_ERROR_H_ +#define _KNOT_COMMON_ERROR_H_ + +#include <errno.h> + +/*! \brief Error lookup table. */ +typedef struct error_table_t { + int id; + const char *name; +} _knot_error_table_t; + +/*! + * \brief Returns error message for the given error code. + * + * \param errno Error code. + * + * \return String containing the error message. + */ +const char *_knot_strerror(_knot_error_table_t *table, int errno); + +/*! + * \brief Safe errno mapper that automatically appends sentinel value. + * + * \see _knot_map_errno() + * + * \param fallback_value Fallback error value (used if the code could not be + * mapped. + * \param err POSIX errno. + * \param ... List of handled codes. + * + * \return Mapped error code. + */ +#define _knot_map_errno(fallback_value, err...) \ + __knot_map_errno(fallback_value, err, 0); + +/*! + * \brief Returns a mapped POSIX errcode. + * + * \warning Last error must be 0, it serves as a sentinel value. + * Use knot_map_errno() instead. + * + * \param fallback_value Fallback error value (used if the code could not be + * mapped. + * \param arg0 First mandatory argument. + * \param ... List of handled codes. + * + * \return Mapped error code. + */ +int __knot_map_errno(int fallback_value, int arg0, ...); + +#endif /* _KNOT_COMMON_ERROR_H_ */ + +/*! @} */ diff --git a/src/knot/other/error.c b/src/knot/other/error.c index 8085512998160ce29f08373244055e108033dc27..acbc207cff03d979f09d2619222ee62d5e6401e6 100644 --- a/src/knot/other/error.c +++ b/src/knot/other/error.c @@ -3,36 +3,10 @@ #include <stdlib.h> #include "knot/other/error.h" - -/*! \brief Error lookup table. */ -typedef struct error_table_t { - knot_error_t id; - const char *name; -} error_table_t; - -/*! - * \brief Looks up the given id in the lookup table. - * - * \param table Lookup table. - * \param id ID to look up. - * - * \return Item in the lookup table with the given id or NULL if no such is - * present. - */ -const error_table_t *error_lookup_by_id(const error_table_t *table, int id) -{ - while (table->name != 0) { - if (table->id == id) { - return table; - } - table++; - } - - return 0; -} +#include "common/errors.h" /*! \brief Table linking error messages to error codes. */ -static const error_table_t knot_error_msgs[] = { +const _knot_error_table_t knot_error_msgs[] = { /* Mapped errors. */ {KNOT_EOK, "OK"}, @@ -57,36 +31,3 @@ static const error_table_t knot_error_msgs[] = { {KNOT_ENOIPV6, "IPv6 support disabled."}, {KNOT_ERROR, 0} }; - -const char *knot_strerror(int errno) -{ - const error_table_t *msg = error_lookup_by_id(knot_error_msgs, - errno); - if (msg != 0) { - return msg->name; - } else { - return "Unknown error."; - } -} - -int _knot_map_errno(int arg0, ...) -{ - /* Iterate all variable-length arguments. */ - va_list ap; - va_start(ap, arg0); - - /* KNOT_ERROR serves as a sentinel. */ - for (int c = arg0; c != KNOT_ERROR; c = va_arg(ap, int)) { - - /* Error code matches with mapped. */ - if (c == errno) { - /* Return negative value of the code. */ - return -abs(c); - } - } - va_end(ap); - - /* Fallback error code. */ - return KNOT_ERROR; -} - diff --git a/src/knot/other/error.h b/src/knot/other/error.h index 084dfd56c018c34f071840a330a35d21709b84f6..375efce51bf4581e94fd5077354a8f5ceac84293 100644 --- a/src/knot/other/error.h +++ b/src/knot/other/error.h @@ -12,15 +12,18 @@ #ifndef _KNOT_ERROR_H_ #define _KNOT_ERROR_H_ + #include <errno.h> +#include "common/errors.h" + /*! * \brief Error codes used in the server. * * Some viable errors are directly mapped * to libc errno codes. */ -typedef enum knot_error_t { +enum knot_error_t { /* Directly mapped error codes. */ KNOT_EOK = 0, @@ -42,8 +45,12 @@ typedef enum knot_error_t { KNOT_EZONEINVAL, /*!< \brief Invalid zone file. */ KNOT_ENOTRUNNING, /*!< \brief Resource is not running. */ KNOT_EPARSEFAIL, /*!< \brief Parser fail. */ - KNOT_ENOIPV6 /*! \brief No IPv6 support. */ -} knot_error_t; + KNOT_ENOIPV6, /*! \brief No IPv6 support. */ + + KNOT_ERROR_COUNT = 19 +}; + +const _knot_error_table_t knot_error_msgs[KNOT_ERROR_COUNT]; /*! * \brief Returns error message for the given error code. @@ -52,29 +59,34 @@ typedef enum knot_error_t { * * \return String containing the error message. */ -const char *knot_strerror(int errno); +inline const char *knot_strerror(int errno) +{ + return _knot_strerror(&knot_error_msgs, errno); +} /*! - * \brief Safe errno mapper that automatically appends sentinel value. - * \see knot_map_errno_f + * \brief errno mapper that automatically prepends fallback value. + * + * \see _knot_map_errno() * * \param err POSIX errno. * \param ... List of handled codes. - * \return Mapped error code. - */ -#define knot_map_errno(err...) _knot_map_errno(err, KNOT_ERROR); - -/*! - * \brief Returns a mapped POSIX errcode. * - * \warning Last error must be KNOT_ERROR, it serves as a fallback and - * a sentinel value as well. Use knot_map_errno() instead. - * - * \param arg0 First mandatory argument. - * \param ... List of handled codes. * \return Mapped error code. */ -int _knot_map_errno(int arg0, ...); +#define knot_map_errno(err...) _knot_map_errno(KNOT_ERROR, err); + +///*! +// * \brief Returns a mapped POSIX errcode. +// * +// * \warning Last error must be KNOT_ERROR, it serves as a fallback and +// * a sentinel value as well. Use knot_map_errno() instead. +// * +// * \param arg0 First mandatory argument. +// * \param ... List of handled codes. +// * \return Mapped error code. +// */ +//int _knot_map_errno(int arg0, ...); #endif /* _KNOT_ERROR_H_ */