From 2095935c2488d1a46c7dd0c9d2325e41715b8ad9 Mon Sep 17 00:00:00 2001 From: rc_05 Date: Fri, 24 May 2024 23:03:55 +0200 Subject: First commit --- src/unix/UnixSocket.cpp.hx | 150 +++++++++++++++++++++++++++++++++++++++++++++ src/unix/UnixSocket.hx | 8 +++ 2 files changed, 158 insertions(+) create mode 100644 src/unix/UnixSocket.cpp.hx create mode 100644 src/unix/UnixSocket.hx (limited to 'src/unix') diff --git a/src/unix/UnixSocket.cpp.hx b/src/unix/UnixSocket.cpp.hx new file mode 100644 index 0000000..32a57d2 --- /dev/null +++ b/src/unix/UnixSocket.cpp.hx @@ -0,0 +1,150 @@ +package unix; + +import cpp.RawPointer; +import cpp.Stdlib; +import cpp.UInt8; +import externs.Socket.SockAddr; +import externs.Socket.SockAddrUnix; +import externs.Socket; +import haxe.io.Bytes; + +/** + Unix socket for local interprocess communication. + + All the functions except for [readBytes](#readBytes) and [writeBytes](#writeBytes) must be called for the + server socket. +**/ +class UnixSocket { + var nativeAddr:SockAddrUnix; + var nativeBuffer:RawPointer; + var nativeBufferLength = 0; + + /** + Socket file path. + **/ + public var path(default, null):String; + + /** + File descriptor associated with the socket. + **/ + public var fileDescriptor(default, null):Int; + + /** + Configures the socket to work as a UNIX socket. + **/ + function configure() { + // Configure the socket to work as a UNIX one and set it up. + nativeAddr = untyped __cpp__("{}"); + untyped __cpp__("nativeAddr.sun_family = AF_UNIX"); + for (i in 0...path.length) { + untyped __cpp__("nativeAddr.sun_path[{0}] = {1}", i, path.charCodeAt(i)); + } + #if debug + trace('Configured socket with path $path and file descriptor $fileDescriptor'); + #end + } + + /** + Creates a new unconnected socket with a `path`. + **/ + public function new(path:String) { + // Trim the string so that it's always 107 characters long. + this.path = path.substr(0, 108); + nativeBufferLength = 1024; + nativeBuffer = cast Stdlib.nativeMalloc(nativeBufferLength); + + configure(); + } + + /** + Initializes the unconnected socket. + **/ + public function init() { + fileDescriptor = Socket.socket(untyped __cpp__("AF_UNIX"), untyped __cpp__("SOCK_STREAM"), 0); + } + + /** + Closes the socket. + **/ + @:native("closeSocket") + public function close() { + Stdlib.nativeFree(cast nativeBuffer); + Socket.close(fileDescriptor); + #if debug + trace('Succesfully closed socket with $path and file descriptor $fileDescriptor'); + #end + } + + /** + Binds the socket to the configured path. + **/ + @:native("bindSocket") + public function bind() { + Socket.bind(fileDescriptor, untyped __cpp__("(const sockaddr *) &nativeAddr"), untyped __cpp__("sizeof(nativeAddr)")); + } + + /** + Instructs the socket to start listening to incoming connections while + allowing for a maximum of `numMaxConnections` connections. + **/ + @:native("listenSocket") + public function listen(numMaxConnections:Int) { + Socket.listen(fileDescriptor, numMaxConnections); + } + + /** + Accepts a client's connection and returns the client's socket. + **/ + @:native("acceptSocket") + public function accept():UnixSocket { + var clientFileDescriptor = Socket.accept(fileDescriptor, untyped __cpp__("(sockaddr *) &nativeAddr"), untyped __cpp__("NULL")); + var clientSocket = new UnixSocket(path); + + return clientSocket; + } + + /** + Connects to the socket. + **/ + @:native("connectSocket") + public function connect() { + Socket.connect(fileDescriptor, untyped __cpp__("(const sockaddr *) &nativeAddr"), untyped __cpp__("sizeof(nativeAddr)")); + } + + /** + Reads `n` bytes from the socket. + **/ + public function readBytes(n:Int):Bytes { + var bytes = Bytes.alloc(n); + + if (n > nativeBufferLength) { + nativeBufferLength *= 2; + nativeBuffer = cast Stdlib.nativeRealloc(cast nativeBuffer, nativeBufferLength); + } + + Socket.read(fileDescriptor, cast nativeBuffer, n); + + for (i in 0...n) { + var byte = nativeBuffer[i]; + bytes.set(i, byte); + } + + return bytes; + } + + /** + Writes `bytes` to the socket. + **/ + public function writeBytes(bytes:Bytes) { + if (bytes.length > nativeBufferLength) { + nativeBufferLength *= 2; + nativeBuffer = cast Stdlib.nativeRealloc(cast nativeBuffer, nativeBufferLength); + } + + for (i in 0...bytes.length) { + nativeBuffer[i] = bytes.get(i); + } + + Socket.write(fileDescriptor, cast nativeBuffer, bytes.length); + } +} diff --git a/src/unix/UnixSocket.hx b/src/unix/UnixSocket.hx new file mode 100644 index 0000000..1e5cea2 --- /dev/null +++ b/src/unix/UnixSocket.hx @@ -0,0 +1,8 @@ +package unix; + +/* + This is a dummy file. + + See UnixSocket..hx for the actual implementation for each target. +*/ +class UnixSocket {} -- cgit v1.2.3