From: Thomas Haller Date: Wed, 26 Nov 2014 17:13:37 +0000 (+0100) Subject: nl: add function nl_pickup_keep_syserr() X-Git-Tag: libnl3_2_26rc1~24^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b023fd441c3fd96aad2acca31d2702b1aa1f21e;p=libnl 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 Signed-off-by: Thomas Haller --- diff --git a/include/netlink/netlink.h b/include/netlink/netlink.h index 61656b3..f8f2082 100644 --- a/include/netlink/netlink.h +++ b/include/netlink/netlink.h @@ -87,6 +87,11 @@ extern int nl_pickup(struct nl_sock *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **); +extern 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); /* Netlink Family Translations */ extern char * nl_nlfamily2str(int, char *, size_t); extern int nl_str2nlfamily(const char *); 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 */ /** @@ -1117,6 +1125,24 @@ int nl_pickup(struct nl_sock *sk, int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *, 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; @@ -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)