commit d5b65805dcde0bb432b7b4b129c5ab9db81aee36
parent a0fdca9f8135c0f7e3f1d266385af10b31f04660
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 11 Apr 2021 09:26:29 -0400
os::streamfd: add unwrap parameter
Diffstat:
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/net/+linux/util.ha b/net/+linux/util.ha
@@ -58,7 +58,7 @@ fn from_native(addr: rt::sockaddr) (ip::addr | unix::addr) = {
// Returns the remote address for a given connection, or void if none is
// available.
export fn peeraddr(stream: *io::stream) ((ip::addr, u16) | void) = {
- let fd = match (os::streamfd(stream)) {
+ let fd = match (os::streamfd(stream, true)) {
fd: int => fd,
void => return,
};
diff --git a/os/+linux/fdstream.ha b/os/+linux/fdstream.ha
@@ -48,13 +48,21 @@ fn is_fdstream(s: *io::stream) bool = {
// Returns the file descriptor for a given [io::stream]. If there is no fd
// associated with this stream, void is returned.
-export fn streamfd(s: *io::stream) (int | void) = {
- for (!is_fdstream(s)) {
+//
+// If 'unwrap' is true, the stream will be unwrapped until an fdstream is found.
+// Note that many stream wrappers (such as [io::tee]) provide important
+// functionality, and using the file descriptor directly will circumvent that
+// functionality. Use with caution.
+export fn streamfd(s: *io::stream, unwrap: bool) (int | void) = {
+ for (unwrap && !is_fdstream(s)) {
s = match (io::source(s)) {
errors::unsupported => return,
s: *io::stream => s,
};
};
+ if (!is_fdstream(s)) {
+ return;
+ };
let stream = s: *fd_stream;
return stream.fd;
};