about summary refs log tree commit diff stats
path: root/src/io/serversocket.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-12-14 20:38:30 +0100
committerbptato <nincsnevem662@gmail.com>2023-12-14 20:38:30 +0100
commit600058a19e58aee247ca90b9eb2a8271b458b2d4 (patch)
tree5f9d07d7236ff7bb67555c04cb65a12b4d1d32fa /src/io/serversocket.nim
parent2f902aeaee8ffa6ceb54876af8f73f56f7840004 (diff)
downloadchawan-600058a19e58aee247ca90b9eb2a8271b458b2d4.tar.gz
socketstream, serversocket: portable bindUnix
reimplementing it portably in Nim seems incredibly annoying, so we
just use C
Diffstat (limited to 'src/io/serversocket.nim')
-rw-r--r--src/io/serversocket.nim25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/io/serversocket.nim b/src/io/serversocket.nim
index 61b633a9..c83af974 100644
--- a/src/io/serversocket.nim
+++ b/src/io/serversocket.nim
@@ -1,6 +1,6 @@
-import nativesockets
-import net
-import os
+import std/nativesockets
+import std/net
+import std/os
 when defined(posix):
   import posix
 
@@ -13,15 +13,22 @@ const SocketPathPrefix = "cha_sock_"
 proc getSocketPath*(pid: Pid): string =
   SocketDirectory / SocketPathPrefix & $pid
 
+# The way stdlib does bindUnix is utterly broken at least on FreeBSD.
+# It seems that just writing it in C is the easiest solution.
+{.compile: "bind_unix.c".}
+proc bind_unix_from_c(fd: cint, path: cstring, pathlen: cint): cint {.importc.}
+
 proc initServerSocket*(buffered = true, blocking = true): ServerSocket =
   createDir(SocketDirectory)
-  result.sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP, buffered)
+  let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP, buffered)
   if not blocking:
-    result.sock.getFd().setBlocking(false)
-  result.path = getSocketPath(getpid())
-  discard unlink(cstring(result.path))
-  bindUnix(result.sock, result.path)
-  listen(result.sock)
+    sock.getFd().setBlocking(false)
+  let path = getSocketPath(getpid())
+  discard unlink(cstring(path))
+  if bind_unix_from_c(cint(sock.getFd()), cstring(path), cint(path.len)) != 0:
+    raiseOSError(osLastError())
+  listen(sock)
+  return ServerSocket(sock: sock, path: path)
 
 proc close*(ssock: ServerSocket) =
   close(ssock.sock)