summaryrefslogtreecommitdiffstats
path: root/lib/nl.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-11-26 17:13:37 (GMT)
committerThomas Haller <thaller@redhat.com>2014-11-27 09:24:03 (GMT)
commit8b023fd441c3fd96aad2acca31d2702b1aa1f21e (patch)
tree9f6a82b965ea735a6a4ece3a54434cf865e70eb0 /lib/nl.c
parent16d16b9a76db9411bf8c019db39e7e66d6114a8f (diff)
downloadlibnl-8b023fd441c3fd96aad2acca31d2702b1aa1f21e.zip
libnl-8b023fd441c3fd96aad2acca31d2702b1aa1f21e.tar.gz
libnl-8b023fd441c3fd96aad2acca31d2702b1aa1f21e.tar.bz2
nl: add function nl_pickup_keep_syserr()
nl_pickup() converts error codes from netlink into nl error codes using nl_syserr2nlerr(). The latter function mangles different error codes to the same nl error code. Add a new function, that returns both the nl error code and the original error code. Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/nl.c')
-rw-r--r--lib/nl.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/nl.c b/lib/nl.c
index 798262e..fade848 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -1077,6 +1077,7 @@ struct pickup_param
int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
struct nlmsghdr *, struct nl_parser_param *);
struct nl_object *result;
+ int *syserror;
};
static int __store_answer(struct nl_object *obj, struct nl_parser_param *p)
@@ -1103,6 +1104,13 @@ static int __pickup_answer(struct nl_msg *msg, void *arg)
return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
}
+static int __pickup_answer_syserr(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
+{
+ *(((struct pickup_param *) arg)->syserror) = nlerr->error;
+
+ return -nl_syserr2nlerr(nlerr->error);
+}
+
/** @endcond */
/**
@@ -1118,6 +1126,24 @@ int nl_pickup(struct nl_sock *sk,
struct nlmsghdr *, struct nl_parser_param *),
struct nl_object **result)
{
+ return nl_pickup_keep_syserr(sk, parser, result, NULL);
+}
+
+/**
+ * Pickup netlink answer, parse is and return object with preserving system error
+ * @arg sk Netlink socket
+ * @arg parser Parser function to parse answer
+ * @arg result Result pointer to return parsed object
+ * @arg syserr Result pointer for the system error in case of failure
+ *
+ * @return 0 on success or a negative error code.
+ */
+int nl_pickup_keep_syserr(struct nl_sock *sk,
+ int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
+ struct nlmsghdr *, struct nl_parser_param *),
+ struct nl_object **result,
+ int *syserror)
+{
struct nl_cb *cb;
int err;
struct pickup_param pp = {
@@ -1129,6 +1155,11 @@ int nl_pickup(struct nl_sock *sk,
return -NLE_NOMEM;
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);
+ if (syserror) {
+ *syserror = 0;
+ pp.syserror = syserror;
+ nl_cb_err(cb, NL_CB_CUSTOM, __pickup_answer_syserr, &pp);
+ }
err = nl_recvmsgs(sk, cb);
if (err < 0)