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>
This commit is contained in:
parent
16d16b9a76
commit
8b023fd441
2 changed files with 36 additions and 0 deletions
|
@ -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 *);
|
||||
|
|
31
lib/nl.c
31
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)
|
||||
|
|
Loading…
Add table
Reference in a new issue