Skip to content

Commit 50021d3

Browse files
committed
Move flags to recvmsg function in netlink
netlink_multicast used 3 calls to fcntl in order to set O_NONBLOCK on socket. It is possible to pass MSG_DONTWAIT flag just to recvmsg function, without setting it permanently on socket. Save few kernel calls and use recvmsg flags. It is supported since kernel 2.2, should be fine for any device still receiving updates.
1 parent 010694d commit 50021d3

File tree

1 file changed

+6
-13
lines changed

1 file changed

+6
-13
lines changed

src/netlink.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ char *netlink_init(void)
106106
return NULL;
107107
}
108108

109-
static ssize_t netlink_recv(void)
109+
static ssize_t netlink_recv(int flags)
110110
{
111111
struct msghdr msg;
112112
struct sockaddr_nl nladdr;
@@ -122,7 +122,8 @@ static ssize_t netlink_recv(void)
122122
msg.msg_iovlen = 1;
123123
msg.msg_flags = 0;
124124

125-
while ((rc = recvmsg(daemon->netlinkfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
125+
while ((rc = recvmsg(daemon->netlinkfd, &msg, flags | MSG_PEEK | MSG_TRUNC)) == -1 &&
126+
errno == EINTR);
126127

127128
/* make buffer big enough */
128129
if (rc != -1 && (msg.msg_flags & MSG_TRUNC))
@@ -139,7 +140,7 @@ static ssize_t netlink_recv(void)
139140

140141
/* read it for real */
141142
msg.msg_flags = 0;
142-
while ((rc = recvmsg(daemon->netlinkfd, &msg, 0)) == -1 && errno == EINTR);
143+
while ((rc = recvmsg(daemon->netlinkfd, &msg, flags)) == -1 && errno == EINTR);
143144

144145
/* Make sure this is from the kernel */
145146
if (rc == -1 || nladdr.nl_pid == 0)
@@ -201,7 +202,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
201202

202203
while (1)
203204
{
204-
if ((len = netlink_recv()) == -1)
205+
if ((len = netlink_recv(0)) == -1)
205206
{
206207
if (errno == ENOBUFS)
207208
{
@@ -353,20 +354,12 @@ void netlink_multicast(void)
353354
{
354355
ssize_t len;
355356
struct nlmsghdr *h;
356-
int flags;
357357
unsigned state = 0;
358358

359359
/* don't risk blocking reading netlink messages here. */
360-
if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
361-
fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
362-
return;
363-
364-
while ((len = netlink_recv()) != -1)
360+
while ((len = netlink_recv(MSG_DONTWAIT)) != -1)
365361
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
366362
state = nl_async(h, state);
367-
368-
/* restore non-blocking status */
369-
fcntl(daemon->netlinkfd, F_SETFL, flags);
370363
}
371364

372365
static unsigned nl_async(struct nlmsghdr *h, unsigned state)

0 commit comments

Comments
 (0)