Thread-safe error handling
In order for the interface to become more thread safe, the error
handling was revised to no longer depend on a static errno and
error string buffer.
This patch converts all error paths to return a libnl specific
error code which can be translated to a error message using
nl_geterror(int error). The functions nl_error() and
nl_get_errno() are therefore obsolete.
This change required various sets of function prototypes to be
changed in order to return an error code, the most prominent
are:
struct nl_cache *foo_alloc_cache(...);
changed to:
int foo_alloc_cache(..., struct nl_cache **);
struct nl_msg *foo_build_request(...);
changed to:
int foo_build_request(..., struct nl_msg **);
struct foo *foo_parse(...);
changed to:
int foo_parse(..., struct foo **);
This pretty much only leaves trivial allocation functions to
still return a pointer object which can still return NULL to
signal out of memory.
This change is a serious API and ABI breaker, sorry!
diff --git a/lib/msg.c b/lib/msg.c
index c5cb7b4..ad6f5a1 100644
--- a/lib/msg.c
+++ b/lib/msg.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
/**
@@ -320,7 +320,7 @@
int maxtype, struct nla_policy *policy)
{
if (!nlmsg_valid_hdr(nlh, hdrlen))
- return nl_errno(EINVAL);
+ return -NLE_MSG_TOOSHORT;
return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
nlmsg_attrlen(nlh, hdrlen), policy);
@@ -351,7 +351,7 @@
struct nla_policy *policy)
{
if (!nlmsg_valid_hdr(nlh, hdrlen))
- return nl_errno(EINVAL);
+ return -NLE_MSG_TOOSHORT;
return nla_validate(nlmsg_attrdata(nlh, hdrlen),
nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
@@ -387,7 +387,6 @@
return nm;
errout:
free(nm);
- nl_errno(ENOMEM);
return NULL;
}
@@ -519,10 +518,8 @@
tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len;
- if ((tlen + nlmsg_len) > n->nm_size) {
- nl_errno(ENOBUFS);
+ if ((tlen + nlmsg_len) > n->nm_size)
return NULL;
- }
buf += nlmsg_len;
n->nm_nlh->nlmsg_len += tlen;
@@ -554,7 +551,7 @@
tmp = nlmsg_reserve(n, len, pad);
if (tmp == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
memcpy(tmp, data, len);
NL_DBG(2, "msg %p: Appended %zu bytes with padding %d\n", n, len, pad);
@@ -581,11 +578,11 @@
void *tmp;
if (newlen <= n->nm_size)
- return nl_errno(EINVAL);
+ return -NLE_INVAL;
tmp = realloc(n->nm_nlh, newlen);
if (tmp == NULL)
- return nl_errno(ENOMEM);
+ return -NLE_NOMEM;
n->nm_nlh = tmp;
n->nm_size = newlen;
@@ -823,8 +820,7 @@
ops = nl_cache_ops_associate(nlmsg_get_proto(msg),
nlmsg_hdr(msg)->nlmsg_type);
if (ops == NULL)
- return nl_error(ENOENT, "Unknown message type %d",
- nlmsg_hdr(msg)->nlmsg_type);
+ return -NLE_MSGTYPE_NOSUPPORT;
p.pp_arg = &x;
return nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p);