Zero-dependency system extension library for Haxe (CPP target) to extend Haxe with system functions that are not available in the standard library.
- Features
- Status Legend
- Roadmap
- Installation
- Target Operating Systems
- Contributions & Bug Reports
- Usage Examples
- Safety & Security Considerations
- Memory Safety & GC Integration
- Development & Hardening
- FIFO (Named Pipes): Create and communicate through local named pipes.
- Unix Domain Sockets: High-performance local bidirectional Inter-Process Communication (IPC).
- Network Functions: DNS resolution, interface listing, unprivileged ping,
setsockoptwrappers, ARP table extraction, and high-precision mass-ping (PingSession). - Shared Memory: Cross-process shared memory segments.
- System Info: RAM, CPU, and Disk diagnostics.
- File System: Native recursive watcher, advisory locking, and memory mapping.
- I/O Optimization: Zero-copy
sendFileandDirectIOsupport. - Process Control: Unified API for CPU affinity, scheduler priority, process tree, forking, and resource limits.
- Signal Handling: Native signal trapping for POSIX and Windows.
- TUI/Console: Low-level terminal control and block writing.
- Secure Random: CSPRNG and UUID v4 support.
- Identity & Credentials: Access to system user and group metadata.
- System Service Integration: Integration with
systemd(sd_notify) and Windows SCM. - Dynamic Symbol Loading: Runtime loading of shared libraries (.dylib, .so, .dll) and symbol resolution.
- FFI Infrastructure: Smart
@:buildmacros for automated proxy generation withString/Boolauto-conversion and automated struct layout mapping. - Native Event Loops: Completion-based (Proactor) engine for high-performance async I/O (kqueue, epoll, IOCP).
- Async File I/O: Non-blocking file operations with native buffer management to minimize GC overhead.
- Advanced Native Buffers: Optimized
RingBuffer,BipBuffer(contiguous), andChunkedBuffer(linked) for high-speed streaming. - Resilient Diagnostics: Native crash interception for Segfaults and Access Violations with minidump generation.
- Symlink Management: Cross-platform symbolic link creation and target resolution.
- Advanced File Diagnostics: 64-bit file stats (bypassing 32-bit limits), FileType discovery, and Permission bitmasks.
- Volume Metadata: Retrieve filesystem type (NTFS/APFS/ext4), labels, and volume serials/UUIDs.
- Process Guard: Ensure child processes terminate if the parent process dies (
exitWithParent). - Modernized Public API: All
cpp.*package types are abstracted away. High-performance memory management usesNativeBufferandhaxe.Int64addresses.
- ✅ Implemented - Feature is complete and working
- 🚧 In Progress - Feature is being developed
- ⏳ Planned - Feature is scheduled for future development
- 💡 Requested - Feature has been requested but not scheduled
- ❌ Not Planned - Feature will not be implemented
- FIFO Implementation (Unix/macOS/Windows) ✅
- Unix Domain Socket Implementation (Unix/macOS/Windows) ✅
- Cross-platform support via Named Pipes (Windows) and AF_UNIX (POSIX) ✅
- Asynchronous/Non-blocking I/O support and Selector mechanism ✅
-
getHostInfo()- DNS resolution (getaddrinfo) ✅ -
getNetworkInterfaces()- Available interfaces (getifaddrs) ✅ -
ping()- ICMP implementation (unprivileged) ✅ -
getArpTable()- Retrieve system ARP table ✅ -
bindToInterface()- Bind socket to specific NIC ✅ -
setSocketOption()- High-levelsetsockoptwrappers ✅ -
PingSession- High-performance mass ping with Kernel Timestamping (POSIX) ✅
- Create and open shared segments (Unix/macOS/Windows) ✅
- Secure private mode support ✅
- Direct memory read/write ✅
- RAM statistics (total, free, used) ✅
- CPU usage percentage ✅
- Disk space stats ✅
-
isRoot()- Check for root/admin privileges ✅ -
fork()- Native process forking with Windows emulation ✅ -
exitWithParent()- Automatic child termination on parent death ✅ -
getFileResourceLimit()- Get open file descriptor limit ✅ -
setFileResourceLimit()- Set open file descriptor limit ✅ -
listProcesses()- List running processes and their stats ✅ -
getProcessTree()- Hierarchical process listing ✅ -
setAffinity()- Pin process to CPU cores ✅ -
setPriority()- Set process scheduling priority ✅
-
Watcher- Native event-driven recursive watching ✅ -
FileLock- Advisory file locking (exclusive/shared) ✅ -
MemoryMap- High-performance file memory mapping ✅ -
sendFile()- Efficient zero-copy file-to-socket transfer ✅ -
setDirectIO()- Bypass OS page cache (O_DIRECT / F_NOCACHE) ✅
-
mlockall()- Lock process memory into RAM ✅ -
trap()- Native signal handling (SIGUSR1, SIGUSR2, etc.) ✅
-
getBytes()- Cryptographically secure random bytes ✅ -
uuid()- Version 4 UUID generation ✅
-
getCurrentUser()- Information about the current user ✅ -
getUser(id)- Polymorphic user lookup by UID or username ✅ -
getGroups()- List system groups ✅
-
NamedSemaphore- Cross-process named semaphores ✅
-
stamp()- Monotonic seconds ✅ -
nanoStamp()- Monotonic nanoseconds ✅
-
setRawMode()- Toggle terminal raw mode ✅ -
getTerminalSize()- Get window dimensions ✅ -
writeBlock()- Fast character block writing ✅ -
useAlternateBuffer()- Switch to alternate screen ✅
-
getXAttr()- Get extended file attribute ✅ -
setXAttr()- Set extended file attribute ✅ -
listXAttrs()- List extended file attributes ✅
-
notify()- systemdsd_notifysupport verified on Linux ✅ -
run()- Initial Windows SCM implementation ✅
-
open()- Load shared libraries (.so, .dylib, .dll) ✅ -
getSymbol()- Resolve function pointers at runtime ✅ - FFI Build Macro - Automate
cpp.Callableproxy generation via@:build✅ - Smart Type Automation - Automatic
StringandBoolconversion for FFI calls ✅ - FFI Struct Mapping - Automated Haxe-to-C struct layout mapping via
@:struct✅
- Completion-based Architecture - Native kqueue/epoll/IOCP support ✅
- Async read/write - True non-blocking operations on sockets and pipes ✅
- Zero-overhead callbacks - Direct native-to-Haxe callback dispatching ✅
- Native Thread Pool (POSIX) - Async file operations on macOS/Linux ✅
- Native Completion (Windows) - Native IOCP support for regular files ✅
- NativeBuffer -
malloc-based memory management outside Haxe GC ✅ - AsyncFile API - High-level completion-driven file API ✅
- RingBuffer - Fixed-size native circular buffer ✅
- BipBuffer - Bipartite contiguous memory buffer ✅
- ChunkedBuffer - Dynamic linked native chunks ✅
- Haxe Integration - Full
haxe.io.Input/Outputcompatibility ✅
- Native Crash Handler - Interception of SIGSEGV, SIGABRT, and Access Violations ✅
- Stack Trace Capture - Text-based backtrace generation for all platforms ✅
- Minidump Generation - Standard
.dmpfiles for Windows ARM64/x64 ✅
- Cross-platform Creation -
symlink(POSIX) andCreateSymbolicLink(Windows) ✅ - Target Resolution -
readlink(POSIX) andGetFinalPathNameByHandle(Windows) ✅
- 64-bit Statistics -
stat64support for files > 2GB viahaxe.Int64✅ - FileType Discovery - Enum-based detection of Sockets, Fifos, Symlinks, etc. ✅
- Permission Management - Unified
chmodusing OR'ed bitmasks ✅
-
io_uring- Kernel-level completion engine for Linux ⏳ - Phase 6: Fibers - Cooperative multitasking and stack-switching ⏳
- Phase 7: Advanced Synchronization - Native Futex and WaitOnAddress ✅
- Tier 4: Hardware & Serial IPC - Unified UART and USB HID access ✅ (Initial Serial Port Implemented)
Note for Linux: Extended attributes (xattr) require a supporting filesystem (e.g., ext4, xfs, btrfs) mounted with
user_xattrsupport. Standard Dockeroverlayfsmay not support theuser.namespace used by this library.
Note for Linux (Network): Unprivileged ping requires the
net.ipv4.ping_group_rangesysctl to be set. To enable for all users:sudo sysctl -w net.ipv4.ping_group_range="0 2147483647".
haxelib git digigun.sys.hx https://github.com/igazine/digigun.sys.hxThis library can be compiled into platform-specific shared libraries for use in other languages (Python, Rust, Node.js, etc.).
# Generate macOS .dylib
haxe test/build-lib-mac.hxml
# Generate Linux .so
haxe test/build-lib-linux.hxml
# Generate Windows .dll
haxe test/build-lib-win-arm.hxmlThe resulting libraries use a stable C-ABI via the DIGIGUN_API export macro and a robust Int64 handle architecture.
The library is primarily designed for desktop and server operating systems, including:
- macOS (Apple Silicon and Intel)
- Linux (including single-board computers like Raspberry Pi)
- Windows (x64 and ARM64)
All features are primarily developed and tested on POSIX-compliant systems (macOS and Linux). While full compatibility with Windows is a core requirement and actively maintained, it serves as a secondary development platform.
Mobile operating systems (such as Android and iOS) might be partially supported depending on the specific module and the underlying kernel features available; however, full compatibility is not guaranteed.
If you encounter any misbehavior, bugs, or platform-specific issues, please open a GitHub issue. Feedback and pull requests are welcome to help improve cross-platform stability.
import digigun.sys.network.PingSession;
var session = new PingSession();
var targets = ["8.8.8.8", "1.1.1.1", "google.com"];
for (host in targets) {
session.send(host);
}
// Non-blocking collection of results
// POSIX targets use Kernel Timestamping to bypass application polling lag.
while (true) {
var replies = session.collect();
for (reply in replies) {
trace('Reply from ${reply.host}: RTT = ${reply.rtt}ms');
}
if (/* all received or timeout */) break;
Sys.sleep(0.01);
}
session.close();import digigun.sys.network.NetworkControl;
import digigun.sys.network.SocketOption;
var sock = new sys.net.Socket();
// Disable Nagle's algorithm
NetworkControl.setSocketOptionBool(sock, SocketOption.IPPROTO_TCP, SocketOption.TCP_NODELAY, true);import digigun.sys.fifo.Fifo;
var fifo = new Fifo();
fifo.create("/tmp/my_pipe", 438); // 438 is 0666 octal
fifo.open("/tmp/my_pipe", true); // open for write
fifo.write(haxe.io.Bytes.ofString("Hello"), 5);
fifo.close();import digigun.sys.fifo.UnixDomainSocket;
import digigun.sys.fifo.Selector;
var server = UnixDomainSocket.create();
server.bind("/tmp/my_socket");
server.listen(5);
server.setBlocking(false);
// Use Selector for non-blocking multiplexing
var ready = Selector.select([server], null, 1.0);
if (ready.read.length > 0) {
var client = server.accept();
// ...
}import digigun.sys.shm.SharedMemory;
import digigun.sys.sync.NamedSemaphore;
var sem = new NamedSemaphore();
if (sem.open("my_mutex", 1)) {
sem.wait();
var shm = new SharedMemory();
if (shm.open("my_buffer", 1024, true)) {
shm.write(0, haxe.io.Bytes.ofString("Shared data"));
shm.close();
}
sem.post();
sem.close();
}import digigun.sys.fs.Watcher;
Watcher.watch("./src", (event) -> {
trace('Change detected: ${event.path} (${event.type})');
});
// To stop watching:
// Watcher.stopAll();import digigun.sys.signal.Signal;
Signal.trap(Signal.USR1, (signo) -> {
trace('Received SIGUSR1 ($signo). Performing hot-reload...');
});Spawn a child process using native fork() on POSIX or optimized emulation on Windows.
import digigun.sys.process.Process;
var pid = Process.fork();
if (pid == 0) {
// In child process
trace('I am the child (PID: ${Process.getId()})');
Sys.exit(0);
} else if (pid > 0) {
// In parent process
trace('I am the parent, spawned child with PID: $pid');
}import digigun.sys.auth.Auth;
var user = Auth.getCurrentUser();
if (user != null) {
trace('Hello, ${user.realname} (${user.username})!');
trace('Home: ${user.homeDir}');
}Define a proxy class with the @:build macro to automatically map native symbols from a dynamic library with smart type conversion.
import digigun.sys.dl.FFI;
@:build(digigun.sys.dl.FFI.build())
class MyNativeLib {
// Automatically resolved from the bound library
@:native("process_get_id")
public static function getPid():Int return 0;
// String and Bool types are automatically converted to/from C-strings/int
@:native("process_echo")
public static function echo(input:String):String return null;
}Automatically map Haxe classes to native C structs for passing complex data to/from dynamic libraries.
import digigun.sys.dl.FFI;
@:build(digigun.sys.dl.FFI.struct())
class NativePoint {
public var x:Int;
public var y:Int;
}
@:build(digigun.sys.dl.FFI.build())
class MyStructLib {
@:native("process_point")
public static function process(p:NativePoint):Void {}
}
// ... usage ...
var p = new NativePoint();
p.x = 10;
p.y = 20;
MyStructLib.process(p); // Passes raw native pointer to C++
trace('Modified by C++: ${p.x}, ${p.y}');Perform non-blocking file operations with zero GC overhead by using native buffers.
import digigun.sys.io.NativeLoop;
import digigun.sys.io.AsyncFile;
import digigun.sys.io.NativeBuffer;
var loop = new NativeLoop();
var file = AsyncFile.open(loop, "large_file.bin", false);
if (file != null) {
// Read 1MB asynchronously
file.read(1024 * 1024, (result, data) -> {
if (result == 0) {
trace('Read ${data.size} bytes into native memory.');
// data.toBytes() to move to Haxe, or use data.address for native work
}
data.free(); // Manually free native memory
file.close();
});
}
// Keep polling the loop to process completions
while (true) {
loop.poll(10);
}Use specialized buffers for zero-copy streaming and contiguous memory access.
import digigun.sys.io.BipBuffer;
var buffer = new BipBuffer(1024 * 1024); // 1MB
// Contiguous write reservation
var res = buffer.reserve(4096);
if (res.address != 0) {
// res.address is the raw memory location
// populate via native FFI or C++
buffer.commit(4096);
}
// Contiguous read access
var info = buffer.getReadPtr();
if (info.address != 0) {
// Process info.len bytes from info.address
buffer.decommit(info.len);
}
// Use with standard Haxe tools
var input = buffer.asInput();
var str = input.readString(10);Enable native crash interception to capture stack traces when a fatal error occurs.
import digigun.sys.rt.RtControl;
// Setup a crash handler that writes to a specific file
// On Windows, this also generates a .dmp file at the same path
RtControl.setupCrashHandler("path/to/crash_report.txt");
// If a native segfault or access violation occurs, a report is generated
// containing the C++/Haxe stack trace.Create and read symbolic links across platforms.
import digigun.sys.fs.Symlink;
// Create a symlink
if (Symlink.create("target_file.txt", "my_link.txt")) {
trace("Link created successfully");
}
// Read a symlink's target
var target = Symlink.read("my_link.txt");
trace('Points to: $target');Retrieve detailed 64-bit statistics and manage permissions via bitmasks.
import digigun.sys.fs.FileDiagnostics;
// Get 64-bit stats
var stats = FileDiagnostics.stat("large_file.iso");
if (stats != null) {
trace('Size: ${stats.size} bytes'); // Native haxe.Int64
trace('Type: ${stats.type.toString()}'); // e.g., RegularFile, Directory, Socket
}
// Manage permissions without octals
FileDiagnostics.chmod("script.sh", OWNER_READ | OWNER_WRITE | OWNER_EXEC);Retrieve detailed metadata about mounted drives and partitions.
import digigun.sys.fs.Volume;
var info = Volume.getInfo("/");
if (info != null) {
trace('FS Type: ${info.fileSystem}'); // e.g., apfs, NTFS, ext4
trace('Total: ${info.totalSpace} bytes');
trace('Free: ${info.freeSpace} bytes');
}Perform low-level packet sniffing and injection. Requires Root/Admin privileges.
import digigun.sys.network.RawSocket;
import digigun.sys.io.NativeBuffer;
var sniffer = RawSocket.create("en0"); // "lo0" for loopback
if (sniffer != null) {
var buf = new NativeBuffer(65536);
var bytes = sniffer.readPacket(buf);
if (bytes > 0) {
trace('Captured packet of $bytes bytes');
}
sniffer.close();
}Users of this library should be aware of the following security implications:
- Unsafe Memory Access: To prevent accidental memory corruption, explicitly dangerous methods that allow dictating arbitrary memory addresses (like
NativeBuffer.fromAddressorMemoryProtection.protectAddress) are guarded. To use these methods, you MUST compile with the flag-D DIGIGUN.SYS.UNSAFE_MEMORY_ACCESS. Library-managed memory (likeSharedMemory.asBuffer()) remains accessible without this flag. - Elevated Privileges: Several system-level functions (e.g., setting CPU affinity, adjusting process priorities, or locking memory into RAM) may require root/administrator privileges depending on the operating system and security policies.
- Inter-Process Communication (IPC): Features such as Shared Memory, Named Semaphores, and Unix Domain Sockets allow data to cross process boundaries. These must be implemented with care to prevent race conditions, unauthorized access, or memory corruption.
- Input Validation: When using system functions that interact with the filesystem or network, always validate inputs to avoid injection-style vulnerabilities or accidental system instability.
Digigun.sys.hx is designed for high-performance systems programming while maintaining Haxe's managed memory expectations.
By default, all native resources (NativeBuffer, RingBuffer, SharedMemory, etc.) integrate with the hxcpp Immix GC.
- Automatic Cleanup: Classes extend
cpp.Finalizable. When the Haxe wrapper is collected, the native C++ destructor is automatically invoked. - Manual Control: Every low-level class provides a
.free()or.destroy()method for deterministic cleanup before the GC runs.
The library maintains a global Atomic Counter (std::atomic<int>) in the C++ layer. Every native malloc, new, or mmap performed by the library increments this counter. This allows the Battlefield test suite to programmatically verify a Zero-Leak State at the end of execution.
For scenarios requiring absolute minimum overhead (e.g., real-time game loops), the GC integration can be compiled out:
- Compile with
-D DIGIGUN.SYS.PURE_ALLOCto removecpp.Finalizableinheritance. - In this mode, the developer assumes 100% responsibility for manual memory deallocation.
The library includes the Battlefield suite (test/Battlefield.hx), a high-pressure stress test designed to detect memory corruption, race conditions, and leaks.
- Volume: ~50,000 assertions per run.
- GC Stress: Explicitly forces Haxe GC sweeps while thousands of native objects are in-flight.
- Cross-Platform: Verified leak-free on macOS (M2), Linux (ARM64), and Windows 11 (ARM64).
This library, its architectural structure, test suite, and development environments were architected by a human. Google Gemini was used throughout the process for code generation and implementation under the human architect's complete control (AI-assisted development).