mirror of
https://gitee.com/openharmony/third_party_libnl
synced 2025-02-11 13:45:27 +00:00
lib/socket: add nl_socket_set_fd() function
This is based on the patch by sagil@infinidat.com, but heavily modified. Add a function nl_socket_set_fd(), I renamed it from nl_connect_fd(). Now nl_connect() and nl_socket_set_fd() are implemented independently as they share little code. But they have similar functionality: to initialize a libnl socket and set it's file descriptor. A user who wants libnl to setup the socket can continue to use nl_connect(). A user with special requirements should setup the socket entirely. That includes calling socket() (with or without SOCK_CLOEXEC), bind(), setting buffer size. For the same reason I dropped nl_create_fd(). It didn't do much more then calling socket() -- which the user can do directly. https://github.com/thom311/libnl/pull/68 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
commit
2d61e89037
@ -60,6 +60,7 @@ extern void nl_socket_disable_auto_ack(struct nl_sock *);
|
||||
extern void nl_socket_enable_auto_ack(struct nl_sock *);
|
||||
|
||||
extern int nl_socket_get_fd(const struct nl_sock *);
|
||||
extern int nl_socket_set_fd(struct nl_sock *sk, int protocol, int fd);
|
||||
extern int nl_socket_set_nonblocking(const struct nl_sock *);
|
||||
extern void nl_socket_enable_msg_peek(struct nl_sock *);
|
||||
extern void nl_socket_disable_msg_peek(struct nl_sock *);
|
||||
|
9
lib/nl.c
9
lib/nl.c
@ -86,8 +86,13 @@
|
||||
* This capability is indicated by
|
||||
* `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`.
|
||||
*
|
||||
* @note nl_connect() creates and sets the file descriptor. You can setup the file
|
||||
* descriptor yourself by creating and binding it, and then calling
|
||||
* nl_socket_set_fd(). The result will be the same.
|
||||
*
|
||||
* @see nl_socket_alloc()
|
||||
* @see nl_close()
|
||||
* @see nl_socket_set_fd()
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*
|
||||
@ -105,8 +110,8 @@ int nl_connect(struct nl_sock *sk, int protocol)
|
||||
flags |= SOCK_CLOEXEC;
|
||||
#endif
|
||||
|
||||
if (sk->s_fd != -1)
|
||||
return -NLE_BAD_SOCK;
|
||||
if (sk->s_fd != -1)
|
||||
return -NLE_BAD_SOCK;
|
||||
|
||||
sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
|
||||
if (sk->s_fd < 0) {
|
||||
|
62
lib/socket.c
62
lib/socket.c
@ -572,6 +572,68 @@ int nl_socket_get_fd(const struct nl_sock *sk)
|
||||
return sk->s_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the socket file descriptor externally which initializes the
|
||||
* socket similar to nl_connect().
|
||||
*
|
||||
* @arg sk Netlink socket (required)
|
||||
* @arg protocol Netlink protocol to use (required)
|
||||
* @arg fd Socket file descriptor to use (required)
|
||||
*
|
||||
* Set the socket file descriptor. @fd must be valid and bind'ed.
|
||||
*
|
||||
* This is an alternative to nl_connect(). nl_connect() creates, binds and
|
||||
* sets the socket. With this function you can set the socket to an externally
|
||||
* created file descriptor.
|
||||
*
|
||||
* @see nl_connect()
|
||||
*
|
||||
* @return 0 on success or a negative error code. On error, @fd is not closed but
|
||||
* possibly unusable.
|
||||
*
|
||||
* @retval -NLE_BAD_SOCK Netlink socket is already connected
|
||||
* @retval -NLE_INVAL Socket is not connected
|
||||
*/
|
||||
int nl_socket_set_fd(struct nl_sock *sk, int protocol, int fd)
|
||||
{
|
||||
int err = 0;
|
||||
socklen_t addrlen;
|
||||
char buf[64];
|
||||
struct sockaddr_nl local = { 0 };
|
||||
|
||||
if (sk->s_fd != -1)
|
||||
return -NLE_BAD_SOCK;
|
||||
if (fd < 0)
|
||||
return -NLE_INVAL;
|
||||
|
||||
addrlen = sizeof(local);
|
||||
err = getsockname(fd, (struct sockaddr *) &local,
|
||||
&addrlen);
|
||||
if (err < 0) {
|
||||
NL_DBG(4, "nl_socket_set_fd(%p): getsockname() failed with %d (%s)\n",
|
||||
sk, errno, strerror_r(errno, buf, sizeof(buf)));
|
||||
return -nl_syserr2nlerr(errno);
|
||||
}
|
||||
|
||||
if (addrlen != sizeof(local))
|
||||
return -NLE_NOADDR;
|
||||
|
||||
if (local.nl_family != AF_NETLINK)
|
||||
return -NLE_AF_NOSUPPORT;
|
||||
|
||||
if (sk->s_local.nl_pid != local.nl_pid) {
|
||||
/* the port id differs. The socket is using a port id not managed by
|
||||
* libnl, hence reset the local port id to release a possibly generated
|
||||
* port. */
|
||||
nl_socket_set_local_port (sk, local.nl_pid);
|
||||
}
|
||||
sk->s_local = local;
|
||||
sk->s_fd = fd;
|
||||
sk->s_proto = protocol;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file descriptor of socket to non-blocking state
|
||||
* @arg sk Netlink socket.
|
||||
|
@ -328,4 +328,5 @@ libnl_3_2_26 {
|
||||
global:
|
||||
nl_cache_pickup_checkdup;
|
||||
nl_pickup_keep_syserr;
|
||||
nl_socket_set_fd;
|
||||
} libnl_3;
|
||||
|
Loading…
x
Reference in New Issue
Block a user