summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-04-15 12:01:39 +0200
committerTom Gundersen <teg@jklm.no>2014-04-19 16:47:52 +0200
commit6fc518838cd717f2f8258f8a0cca37797c187a06 (patch)
tree61aabc8cda26e3625ec1ec142ee473e250579f15
parent2f20a8ebdb5aed3146f366360762d8963efe8d82 (diff)
downloadsystemd-6fc518838cd717f2f8258f8a0cca37797c187a06.tar.gz
sd-rtnl: message - make room for all pending messages, not just the first
Also, don't actually read any of the message when peeking, just get its length.
-rw-r--r--src/libsystemd/sd-rtnl/rtnl-message.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 1afba8f0bb..47dcd4a782 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1080,26 +1080,23 @@ int socket_read_message(sd_rtnl *rtnl) {
assert(rtnl);
assert(rtnl->rbuffer);
+ assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
- iov.iov_base = rtnl->rbuffer;
- iov.iov_len = rtnl->rbuffer_allocated;
-
- /* peek at the pending message header to get the message size */
- r = recvmsg(rtnl->fd, &msg, MSG_PEEK);
+ /* read nothing, just get the pending message size */
+ r = recvmsg(rtnl->fd, &msg, MSG_PEEK | MSG_TRUNC);
if (r < 0)
/* no data */
return (errno == EAGAIN) ? 0 : -errno;
else if (r == 0)
/* connection was closed by the kernel */
return -ECONNRESET;
- else if ((size_t)r < sizeof(struct nlmsghdr))
- return -EIO;
+ else
+ len = (size_t)r;
/* make room for the pending message */
if (!greedy_realloc((void **)&rtnl->rbuffer,
&rtnl->rbuffer_allocated,
- rtnl->rbuffer->nlmsg_len,
- sizeof(uint8_t)))
+ len, sizeof(uint8_t)))
return -ENOMEM;
iov.iov_base = rtnl->rbuffer;