From 122179980c8bec764a2bb4afeb01c049c12af2d9 Mon Sep 17 00:00:00 2001 From: rexim Date: Thu, 6 Feb 2025 12:27:04 +0700 Subject: [PATCH] Introduce Socket.shutdown() --- lib/std/libc/os/posix.c3 | 5 +++++ lib/std/libc/os/win32.c3 | 7 ++++++- lib/std/net/socket.c3 | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/std/libc/os/posix.c3 b/lib/std/libc/os/posix.c3 index c3fecc2f1..7ca9a89d1 100644 --- a/lib/std/libc/os/posix.c3 +++ b/lib/std/libc/os/posix.c3 @@ -1,5 +1,10 @@ module libc @if(env::POSIX); +const CInt SHUT_RD = 0; +const CInt SHUT_WR = 1; +const CInt SHUT_RDWR = 2; +extern fn CInt shutdown(Fd sockfd, CInt how); + extern fn isz recv(Fd socket, void *buffer, usz length, CInt flags); extern fn isz send(Fd socket, void *buffer, usz length, CInt flags); diff --git a/lib/std/libc/os/win32.c3 b/lib/std/libc/os/win32.c3 index 583de4907..baaa4659d 100644 --- a/lib/std/libc/os/win32.c3 +++ b/lib/std/libc/os/win32.c3 @@ -24,6 +24,11 @@ extern fn CInt _wremove(WString); extern fn int recv(Win32_SOCKET s, void* buf, int len, int flags); extern fn int send(Win32_SOCKET s, void* buf, int len, int flags); +const CInt SD_RECEIVE = 0; +const CInt SD_SEND = 1; +const CInt SD_BOTH = 2; +extern fn CInt shutdown(Win32_SOCKET s, CInt how); + struct SystemInfo { union { @@ -51,4 +56,4 @@ macro Tm* localtime_r(Time_t* timer, Tm* buf) => _localtime64_s(buf, timer); macro CInt setjmp(JmpBuf* buffer) => _setjmp(buffer, null); macro Tm* gmtime_r(Time_t* timer, Tm* buf) => _gmtime64_s(buf, timer); macro isz read(Fd fd, void* buffer, usz buffer_size) => _read(fd, buffer, (CUInt)buffer_size); -macro isz write(Fd fd, void* buffer, usz count) => _write(fd, buffer, (CUInt)count); \ No newline at end of file +macro isz write(Fd fd, void* buffer, usz count) => _write(fd, buffer, (CUInt)count); diff --git a/lib/std/net/socket.c3 b/lib/std/net/socket.c3 index bb6458792..eb4298bdf 100644 --- a/lib/std/net/socket.c3 +++ b/lib/std/net/socket.c3 @@ -155,3 +155,36 @@ fn void! Socket.close(&self) @inline @dynamic { self.sock.close()!; } + +enum SocketShutdownHow +{ + RECEIVE, + SEND, + BOTH, +} + +fn CInt SocketShutdownHow.os_value(self) +{ + $switch + $case env::WIN32: + switch (self) { + case RECEIVE: return libc::SD_RECEIVE; + case SEND: return libc::SD_SEND; + case BOTH: return libc::SD_BOTH; + } + $case env::POSIX: + switch (self) { + case RECEIVE: return libc::SHUT_RD; + case SEND: return libc::SHUT_WR; + case BOTH: return libc::SHUT_RDWR; + } + $default: $error("Unsupported environment"); + $endswitch +} + +fn void! Socket.shutdown(&self, SocketShutdownHow how) +{ + if (libc::shutdown(self.sock, how.os_value()) < 0) { + return os::socket_error()?; + } +}