implement generic I/O async request object to replace file-specific async requests, refactor lwIP network stack to dispatch requests through IRPs with cancellation support, add cancellation polling to lwIP accept and receive operations using LwipSocketWaitRecvNetbuf and LwipSocketWaitAccept, introduce NetSubmitSocketIrp for routing socket operations via device IRPs, track network IRP statistics with SYS_NET_IRP_STATS, add process module lock spinlock and reference counting for process modules, implement dynamic module loading and unloading via user module handles, add POSIX dynamic loader APIs including dlopen, dlsym, dlerror, and dlclose, introduce PosixStart entry point for posix applications, add new native smoke tests for net IRPs.

This commit is contained in:
maksw committed 2026-06-27 10:37:53 +02:00
1 parent ed3d065abd
commit 1f5477cf66
32 files changed
+3713 -551

No files matched your search

+11
View File
@@ -84,6 +84,12 @@ extern int errno; // defined in posix_fd.c; single global in v1
#define MS_ASYNC 0x01
#define MS_INVALIDATE 0x02
// Dynamic loader flags.
#define RTLD_LAZY 0x0001
#define RTLD_NOW 0x0002
#define RTLD_LOCAL 0x0004
#define RTLD_GLOBAL 0x0008
// Scalar types.
typedef int32_t pid_t;
typedef int32_t off_t;
@@ -131,6 +137,11 @@ __declspec(dllexport) void* mmap(void* addr, size_t length, int prot, int flags,
__declspec(dllexport) int munmap(void* addr, size_t length);
__declspec(dllexport) int msync(void* addr, size_t length, int flags);
__declspec(dllexport) void* dlopen(const char* filename, int flags);
__declspec(dllexport) void* dlsym(void* handle, const char* symbol);
__declspec(dllexport) int dlclose(void* handle);
__declspec(dllexport) char* dlerror(void);
// Sockets.
typedef uint16_t sa_family_t;
typedef uint16_t in_port_t;
+118
View File
@@ -0,0 +1,118 @@
// POSIX compatibility support for dynamic module loading.
#include <stdint.h>
#include <string.h>
#include <ntlite/syscall.h>
#include "posix.h"
#include "posix_path.h"
#include "posix_fd.h"
static char gDlError[160];
static int gDlErrorPending;
// Clears the process-local dynamic-loader error string.
static void DlClearError(void) {
gDlError[0] = '\0';
gDlErrorPending = 0;
}
// Stores one process-local dynamic-loader error string.
static void DlSetError(const char* message) {
if (!message) message = "dynamic loader error";
strncpy(gDlError, message, sizeof(gDlError) - 1);
gDlError[sizeof(gDlError) - 1] = '\0';
gDlErrorPending = 1;
}
// Converts one native loader status to errno and a dlerror message.
static void DlSetStatusError(const char* operation, uint32_t status) {
(void)status;
errno = PosixStatusToErrno(status);
DlSetError(operation);
}
// Loads one DLL-like user module through the native module loader.
__declspec(dllexport) void* dlopen(const char* filename, int flags) {
(void)flags;
DlClearError();
if (!filename || !filename[0]) {
errno = EINVAL;
DlSetError("dlopen requires a module path");
return 0;
}
char native[512];
const char* path = PosixTranslatePath(filename, native, sizeof(native));
if (!path || strcmp(path, SYNTH_DEVNULL) == 0 || strcmp(path, SYNTH_DEVZERO) == 0) {
errno = EINVAL;
DlSetError("dlopen path is not a loadable module");
return 0;
}
uint32_t handle = 0;
SYS_LOAD_MODULE_REQUEST req;
memset(&req, 0, sizeof(req));
req.Size = sizeof(req);
req.Path = SysSvFromCstr(path);
req.ModuleHandleOut = &handle;
uint32_t status = SysLoadModule(&req);
if (status != STATUS_SUCCESS || handle == 0) {
DlSetStatusError("dlopen failed", status);
return 0;
}
return (void*)(uintptr_t)handle;
}
// Resolves one named export from a native module handle.
__declspec(dllexport) void* dlsym(void* handle, const char* symbol) {
DlClearError();
if (!handle || !symbol || !symbol[0]) {
errno = EINVAL;
DlSetError("dlsym requires a module handle and symbol name");
return 0;
}
uintptr_t address = 0;
SYS_GET_MODULE_EXPORT_REQUEST req;
memset(&req, 0, sizeof(req));
req.Size = sizeof(req);
req.ModuleHandle = (uint32_t)(uintptr_t)handle;
req.Name = SysSvFromCstr(symbol);
req.AddressOut = &address;
uint32_t status = SysGetModuleExport(&req);
if (status != STATUS_SUCCESS || address == 0) {
DlSetStatusError("dlsym failed", status);
return 0;
}
return (void*)address;
}
// Releases one module handle returned by dlopen.
__declspec(dllexport) int dlclose(void* handle) {
DlClearError();
if (!handle) {
errno = EINVAL;
DlSetError("dlclose requires a module handle");
return -1;
}
uint32_t status = SysUnloadModule((uint32_t)(uintptr_t)handle);
if (status != STATUS_SUCCESS) {
DlSetStatusError("dlclose failed", status);
return -1;
}
return 0;
}
// Returns and clears the most recent dynamic-loader error string.
__declspec(dllexport) char* dlerror(void) {
if (!gDlErrorPending || !gDlError[0]) return 0;
gDlErrorPending = 0;
return gDlError;
}
+1 -1
View File
@@ -24,7 +24,7 @@ typedef struct {
#define FD_MAX 64
#define FD_TABLE_PIDS 32 // circular, indexed by pid % FD_TABLE_PIDS
// Called from _start before main(); sets up fds 0/1/2 for this process.
// Called from PosixStart before main(); sets up fds 0/1/2 for this process.
__declspec(dllexport) void PosixFdInit(void);
// Allocate the lowest free fd >= 3. Returns -1 and sets errno=EMFILE on failure.