mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-14 14:30:36 +01:00
glib-aux: add nm_fd_next_datagram_size() helper
This commit is contained in:
parent
4b35168193
commit
f7bc47a26f
2 changed files with 42 additions and 0 deletions
|
|
@ -12,6 +12,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "nm-str-buf.h"
|
||||
#include "nm-shared-utils.h"
|
||||
|
|
@ -496,6 +497,45 @@ nm_utils_fd_read(int fd, NMStrBuf *out_string)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Taken from systemd's next_datagram_size_fd(). */
|
||||
gssize
|
||||
nm_fd_next_datagram_size(int fd)
|
||||
{
|
||||
gssize l;
|
||||
int k;
|
||||
|
||||
/* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will
|
||||
* actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
|
||||
* do. This difference is actually of major importance as we need to be sure that the size returned here
|
||||
* actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of
|
||||
* the wrong size. */
|
||||
|
||||
l = recv(fd, NULL, 0, MSG_PEEK | MSG_TRUNC);
|
||||
if (l < 0) {
|
||||
if (NM_IN_SET(errno, EOPNOTSUPP, EFAULT))
|
||||
goto fallback;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
if (l == 0)
|
||||
goto fallback;
|
||||
|
||||
return l;
|
||||
|
||||
fallback:
|
||||
k = 0;
|
||||
|
||||
/* Some sockets (AF_PACKET) do not support null-sized recv() with MSG_TRUNC set, let's fall back to FIONREAD
|
||||
* for them. Checksums don't matter for raw sockets anyway, hence this should be fine. */
|
||||
|
||||
if (ioctl(fd, FIONREAD, &k) < 0)
|
||||
return -errno;
|
||||
|
||||
return (gssize) k;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
GSubprocess *subprocess;
|
||||
GSource *timeout_source;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ struct _NMStrBuf;
|
|||
|
||||
gssize nm_utils_fd_read(int fd, struct _NMStrBuf *out_string);
|
||||
|
||||
gssize nm_fd_next_datagram_size(int fd);
|
||||
|
||||
struct stat;
|
||||
|
||||
int nm_utils_file_stat(const char *filename, struct stat *out_st);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue