net.nim: add support for Unix sockets
This commit is contained in:
parent
8e4b5e10ba
commit
da308be2d7
5 changed files with 57 additions and 2 deletions
6
examples/unix_socket/client.nim
Normal file
6
examples/unix_socket/client.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import net
|
||||||
|
|
||||||
|
let sock = newSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP)
|
||||||
|
|
||||||
|
sock.connectUnix("sock")
|
||||||
|
sock.send("hello\n")
|
||||||
14
examples/unix_socket/server.nim
Normal file
14
examples/unix_socket/server.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import net
|
||||||
|
|
||||||
|
let sock = newSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP)
|
||||||
|
sock.bindUnix("sock")
|
||||||
|
sock.listen()
|
||||||
|
|
||||||
|
while true:
|
||||||
|
var client = new(Socket)
|
||||||
|
sock.accept(client)
|
||||||
|
var output = ""
|
||||||
|
output.setLen 32
|
||||||
|
client.readLine(output)
|
||||||
|
echo "got ", output
|
||||||
|
client.close()
|
||||||
|
|
@ -439,6 +439,14 @@ when hasSpawnH:
|
||||||
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t",
|
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t",
|
||||||
header: "<spawn.h>", final, pure.} = object
|
header: "<spawn.h>", final, pure.} = object
|
||||||
|
|
||||||
|
when defined(linux):
|
||||||
|
# from sys/un.h
|
||||||
|
const Sockaddr_un_path_length* = 108
|
||||||
|
else:
|
||||||
|
# according to http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/un.h.html
|
||||||
|
# this is >=92
|
||||||
|
const Sockaddr_un_path_length* = 92
|
||||||
|
|
||||||
type
|
type
|
||||||
Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint
|
Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint
|
||||||
TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cint
|
TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cint
|
||||||
|
|
@ -448,6 +456,11 @@ type
|
||||||
sa_family*: TSa_Family ## Address family.
|
sa_family*: TSa_Family ## Address family.
|
||||||
sa_data*: array [0..255, char] ## Socket address (variable-length data).
|
sa_data*: array [0..255, char] ## Socket address (variable-length data).
|
||||||
|
|
||||||
|
Sockaddr_un* {.importc: "struct sockaddr_un", header: "<sys/un.h>",
|
||||||
|
pure, final.} = object ## struct sockaddr_un
|
||||||
|
sun_family*: TSa_Family ## Address family.
|
||||||
|
sun_path*: array [0..Sockaddr_un_path_length-1, char] ## Socket path
|
||||||
|
|
||||||
Sockaddr_storage* {.importc: "struct sockaddr_storage",
|
Sockaddr_storage* {.importc: "struct sockaddr_storage",
|
||||||
header: "<sys/socket.h>",
|
header: "<sys/socket.h>",
|
||||||
pure, final.} = object ## struct sockaddr_storage
|
pure, final.} = object ## struct sockaddr_storage
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ else:
|
||||||
import posix
|
import posix
|
||||||
export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL,
|
export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL,
|
||||||
EINTR, EINPROGRESS, ECONNRESET, EPIPE, ENETRESET
|
EINTR, EINPROGRESS, ECONNRESET, EPIPE, ENETRESET
|
||||||
export Sockaddr_storage
|
export Sockaddr_storage, Sockaddr_un, Sockaddr_un_path_length
|
||||||
|
|
||||||
export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen,
|
export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen,
|
||||||
Sockaddr_in6,
|
Sockaddr_in6,
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,9 @@
|
||||||
## This module implements a high-level cross-platform sockets interface.
|
## This module implements a high-level cross-platform sockets interface.
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.}
|
||||||
import nativesockets, os, strutils, unsigned, parseutils, times
|
import nativesockets, os, strutils, parseutils, times
|
||||||
export Port, `$`, `==`
|
export Port, `$`, `==`
|
||||||
|
export Domain, SockType, Protocol
|
||||||
|
|
||||||
const useWinVersion = defined(Windows) or defined(nimdoc)
|
const useWinVersion = defined(Windows) or defined(nimdoc)
|
||||||
|
|
||||||
|
|
@ -582,6 +583,27 @@ proc connect*(socket: Socket, address: string,
|
||||||
let ret = SSLConnect(socket.sslHandle)
|
let ret = SSLConnect(socket.sslHandle)
|
||||||
socketError(socket, ret)
|
socketError(socket, ret)
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
|
proc makeUnixAddr(path: string): Sockaddr_un =
|
||||||
|
result.sun_family = AF_UNIX.toInt
|
||||||
|
if path.len >= Sockaddr_un_path_length:
|
||||||
|
raise newException(ValueError, "socket path too long")
|
||||||
|
copyMem(addr result.sun_path, path.cstring, path.len + 1)
|
||||||
|
|
||||||
|
proc connectUnix*(socket: Socket, path: string) =
|
||||||
|
## Connects to Unix socket on `path`.
|
||||||
|
var socketAddr = makeUnixAddr(path)
|
||||||
|
if socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
|
||||||
|
sizeof(socketAddr).Socklen) != 0'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
|
proc bindUnix*(socket: Socket, path: string) =
|
||||||
|
## Binds Unix socket to `path`.
|
||||||
|
var socketAddr = makeUnixAddr(path)
|
||||||
|
if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
|
||||||
|
sizeof(socketAddr).Socklen) != 0'i32:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
proc handshake*(socket: Socket): bool {.tags: [ReadIOEffect, WriteIOEffect].} =
|
proc handshake*(socket: Socket): bool {.tags: [ReadIOEffect, WriteIOEffect].} =
|
||||||
## This proc needs to be called on a socket after it connects. This is
|
## This proc needs to be called on a socket after it connects. This is
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue