Commit 17fe12c3 authored by Jan Včelák's avatar Jan Včelák 🚀

move generic errors handling from libknot to common

parent 7638cab0
......@@ -102,12 +102,14 @@ libknotcs_la_SOURCES = \
common/base32hex.h \
common/base64.c \
common/base64.h \
common/memdup.h \
common/mempool.c \
common/mempool.h \
common/debug.h \
common/errors.c \
common/errors.h \
common/getline.c \
common/getline.h \
common/memdup.h \
common/mempool.c \
common/mempool.h \
common/log.c \
common/log.h
......@@ -161,8 +163,6 @@ libknot_la_SOURCES = \
libknot/dnssec/sign.h \
libknot/errcode.c \
libknot/errcode.h \
libknot/errors.c \
libknot/errors.h \
libknot/libknot.h \
libknot/mempattern.c \
libknot/mempattern.h \
......
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -12,65 +12,31 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "libknot/errors.h"
#include "libknot/errcode.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 error_table_t *error_lookup_by_id(const error_table_t *table,
int id)
static const error_table_t *lookup_error(const error_table_t *table, int id)
{
while (table->name != 0) {
while (table->name != NULL) {
if (table->id == id) {
return table;
}
table++;
}
return 0;
return NULL;
}
const char *error_to_str(const error_table_t *table, int code)
const char *error_to_str(const error_table_t *table, int id)
{
const error_table_t *msg = error_lookup_by_id(table, code);
if (msg != 0) {
const error_table_t *msg = lookup_error(table, id);
if (msg != NULL) {
return msg->name;
} else {
return "Unknown error.";
}
}
int _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. */
va_end(ap);
return err2code(abs(c));
}
}
va_end(ap);
/* Fallback error code. */
return fallback_value;
}
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -12,66 +12,24 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file errors.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
* @{
*/
*/
#pragma once
#include <errno.h>
/*! \brief Error lookup table. */
/*!
* \brief Error-to-string mapping table.
*/
typedef struct error_table_t {
int id;
const char *name;
} error_table_t;
/*!
* \brief Returns error message for the given error code.
*
* \param table Table of error messages to use.
* \param code Error code.
*
* \return String containing the error message.
*/
const char *error_to_str(const error_table_t *table, int code);
/*!
* \brief Safe errno mapper that automatically appends sentinel value.
* \brief Map error code to error string.
*
* \see _map_errno()
* \param table Lookup table.
* \param id Error to look up.
*
* \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.
* \return Error string, fallback string if not found.
*/
#define map_errno(fallback_value, err...) _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 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 _map_errno(int fallback_value, int arg0, ...);
/*! @} */
const char *error_to_str(const error_table_t *table, int id);
......@@ -27,7 +27,7 @@
#include "common-knot/hattrie/murmurhash3.h"
#include "libknot/dnssec/random.h"
#include "libknot/descriptor.h"
#include "libknot/errors.h"
#include "common/errors.h"
#include "knot/zone/zone.h"
/* Hopscotch defines. */
......
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -12,12 +12,15 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include <stdarg.h>
#include <stdlib.h>
#include "common/errors.h"
#include "libknot/errcode.h"
#include "libknot/errors.h"
const error_table_t knot_error_msgs[] = {
const error_table_t error_messages[] = {
{ KNOT_EOK, "OK" },
/* TSIG errors. */
......@@ -113,5 +116,32 @@ const error_table_t knot_error_msgs[] = {
/* NSEC3 errors. */
{ KNOT_NSEC3_ECOMPUTE_HASH, "Cannot compute NSEC3 hash." },
{ KNOT_ERROR, 0 } /* Terminator */
{ KNOT_ERROR, NULL } /* Terminator */
};
const char *knot_strerror(int code)
{
return error_to_str(error_messages, code);
}
int knot_map_errno_internal(int fallback, 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. */
va_end(ap);
return knot_errno_to_error(abs(c));
}
}
va_end(ap);
/* Fallback error code. */
return KNOT_ERROR;
}
......@@ -28,13 +28,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <errno.h>
#include "libknot/errors.h"
/* errno -> Knot error mapping.
* \note offset is required, otherwise it would interfere with TSIG errors.
*/
#define ERRBASE 100
#define err2code(x) (-(ERRBASE + (x)))
#define KNOT_ERROR_BASE 100
#define knot_errno_to_error(x) (-(KNOT_ERROR_BASE + (x)))
/*! \brief Error codes used in the library. */
enum knot_error {
......@@ -46,17 +45,17 @@ enum knot_error {
KNOT_TSIG_EBADTIME = -18, /*!< TSIG signing time out of range. */
/* Directly mapped error codes. */
KNOT_ENOMEM = err2code(ENOMEM), /*!< Out of memory. */
KNOT_EINVAL = err2code(EINVAL), /*!< Invalid parameter passed. */
KNOT_ENOTSUP = err2code(ENOTSUP), /*!< Parameter not supported. */
KNOT_EBUSY = err2code(EBUSY), /*!< Requested resource is busy. */
KNOT_EAGAIN = err2code(EAGAIN), /*!< OS lacked necessary resources. */
KNOT_EACCES = err2code(EACCES), /*!< Permission is denied. */
KNOT_ECONNREFUSED = err2code(ECONNREFUSED), /*!< Connection is refused. */
KNOT_EISCONN = err2code(EISCONN), /*!< Already connected. */
KNOT_EADDRINUSE = err2code(EADDRINUSE), /*!< Address already in use. */
KNOT_ENOENT = err2code(ENOENT), /*!< Resource not found. */
KNOT_ERANGE = err2code(ERANGE), /*!< Value is out of range. */
KNOT_ENOMEM = knot_errno_to_error(ENOMEM), /*!< Out of memory. */
KNOT_EINVAL = knot_errno_to_error(EINVAL), /*!< Invalid parameter passed. */
KNOT_ENOTSUP = knot_errno_to_error(ENOTSUP), /*!< Parameter not supported. */
KNOT_EBUSY = knot_errno_to_error(EBUSY), /*!< Requested resource is busy. */
KNOT_EAGAIN = knot_errno_to_error(EAGAIN), /*!< OS lacked necessary resources. */
KNOT_EACCES = knot_errno_to_error(EACCES), /*!< Permission is denied. */
KNOT_ECONNREFUSED = knot_errno_to_error(ECONNREFUSED), /*!< Connection is refused. */
KNOT_EISCONN = knot_errno_to_error(EISCONN), /*!< Already connected. */
KNOT_EADDRINUSE = knot_errno_to_error(EADDRINUSE), /*!< Address already in use. */
KNOT_ENOENT = knot_errno_to_error(ENOENT), /*!< Resource not found. */
KNOT_ERANGE = knot_errno_to_error(ERANGE), /*!< Value is out of range. */
/* General errors. */
KNOT_ERROR = -10000, /*!< Failed. */
......@@ -134,9 +133,6 @@ enum knot_error {
KNOT_NSEC3_ECOMPUTE_HASH
};
/*! \brief Table linking error messages to error codes. */
extern const error_table_t knot_error_msgs[];
/*!
* \brief Returns error message for the given error code.
*
......@@ -144,21 +140,25 @@ extern const error_table_t knot_error_msgs[];
*
* \return String containing the error message.
*/
static inline const char *knot_strerror(int code)
{
return error_to_str((const error_table_t*)knot_error_msgs, code);
}
const char *knot_strerror(int code);
/*!
* \brief errno mapper that automatically prepends fallback value.
* \brief Get a POSIX errno mapped to Knot error code.
*
* \internal
*
* \see map_errno()
* \param fallback Falback error code.
* \param arg0... Error codes allowed for lookup, list must be terminated by 0.
*
* \param err POSIX errno.
* \param ... List of handled codes.
* \return Mapped errno or fallback error code.
*/
int knot_map_errno_internal(int fallback, int arg0, ...);
/*!
* \brief Map POSIX errno to Knot error code.
*
* \return Mapped error code.
* KNOT_ERRNO is used as a fallback error, the list is terminated implicitly.
*/
#define knot_map_errno(err...) map_errno(KNOT_ERROR, err);
#define knot_map_errno(errors...) knot_map_errno_internal(KNOT_ERROR, errors, 0)
/*! @} */
......@@ -29,7 +29,6 @@
#include "libknot/consts.h"
#include "libknot/dname.h"
#include "libknot/descriptor.h"
#include "libknot/errors.h"
#include "libknot/errcode.h"
#include "libknot/mempattern.h"
#include "libknot/rrtype/opt.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment