From ea4c864d4b74b7297268debfaf043dd1e4243619 Mon Sep 17 00:00:00 2001 From: Jooris Hadeler <115401775+jooris-hadeler@users.noreply.github.com> Date: Fri, 7 Feb 2025 21:00:54 +0100 Subject: [PATCH] Add `Socket.peek` to allow peeking at the receiving queue. (#1933) * Add `Socket.peek` to allow peeking at the receiving queue. This uses the `MSG_PEEK` flag to peek at the beginning of the receiving queue without removing data from said queue. --- lib/std/net/os/darwin.c3 | 1 + lib/std/net/os/linux.c3 | 2 ++ lib/std/net/os/win32.c3 | 2 ++ lib/std/net/socket.c3 | 10 ++++++++++ 4 files changed, 15 insertions(+) diff --git a/lib/std/net/os/darwin.c3 b/lib/std/net/os/darwin.c3 index ac6550115..9b74fb24b 100644 --- a/lib/std/net/os/darwin.c3 +++ b/lib/std/net/os/darwin.c3 @@ -94,3 +94,4 @@ const CShort POLLATTRIB = 0x0400; // file attributes may have changed const CShort POLLNLINK = 0x0800; // (un)link/rename may have happened const CShort POLLWRITE = 0x1000; // file's contents may have changed +const CInt MSG_PEEK = 0x0002; \ No newline at end of file diff --git a/lib/std/net/os/linux.c3 b/lib/std/net/os/linux.c3 index e82ca9eef..fb800ffbb 100644 --- a/lib/std/net/os/linux.c3 +++ b/lib/std/net/os/linux.c3 @@ -88,3 +88,5 @@ const CUShort POLLREMOVE = 0x1000; const CUShort POLLRDHUP = 0x2000; const CUShort POLLFREE = 0x4000; const CUShort POLL_BUSY_LOOP = 0x8000; + +const CInt MSG_PEEK = 0x0002; \ No newline at end of file diff --git a/lib/std/net/os/win32.c3 b/lib/std/net/os/win32.c3 index 826c9a8db..062be2825 100644 --- a/lib/std/net/os/win32.c3 +++ b/lib/std/net/os/win32.c3 @@ -101,3 +101,5 @@ const CUShort POLLRDNORM = win32::POLLRDNORM; const CUShort POLLRDBAND = win32::POLLRDBAND; const CUShort POLLWRNORM = win32::POLLWRNORM; const CUShort POLLWRBAND = win32::POLLWRBAND; + +const int MSG_PEEK = 0x0002; \ No newline at end of file diff --git a/lib/std/net/socket.c3 b/lib/std/net/socket.c3 index d1fce6a4b..1eef49722 100644 --- a/lib/std/net/socket.c3 +++ b/lib/std/net/socket.c3 @@ -156,6 +156,16 @@ fn void! Socket.close(&self) @inline @dynamic self.sock.close()!; } +fn usz! Socket.peek(&self, char[] bytes) @dynamic +{ + $if env::WIN32: + isz n = libc::recv(self.sock, bytes.ptr, (int)bytes.len, os::MSG_PEEK); + $else + isz n = libc::recv(self.sock, bytes.ptr, bytes.len, os::MSG_PEEK); + $endif + if (n < 0) return os::socket_error()?; + return (usz)n; +} enum SocketShutdownHow : (inline CInt native_value) {