major restructuring, prepare for smp
This commit is contained in:
1 parent
b3569a2b90
commit
6bff37746d
229 files changed
+1617
-1489
No files matched your search
@@ -0,0 +1,138 @@
|
||||
// posix_proc.c - posix_spawn, waitpid, getpid
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include "posix.h"
|
||||
#include "posix_path.h"
|
||||
|
||||
|
||||
static SYS_PEB* gProcessPeb = NULL;
|
||||
|
||||
static SYS_PEB* PosixPeb(void) {
|
||||
if (!gProcessPeb) gProcessPeb = SysGetPeb();
|
||||
return gProcessPeb;
|
||||
}
|
||||
|
||||
__declspec(dllexport) const char* posix_get_command_line(void) {
|
||||
SYS_PEB* peb = PosixPeb();
|
||||
if (!peb || peb->Magic != SYS_PEB_MAGIC || !peb->CommandLine.Data) return "";
|
||||
return peb->CommandLine.Data;
|
||||
}
|
||||
|
||||
// pid -> proc handle table (user-mode side, for waitpid)
|
||||
#define PROC_TABLE_SIZE 32
|
||||
typedef struct {
|
||||
pid_t pid;
|
||||
uint32_t handle;
|
||||
bool used;
|
||||
} ProcEntry;
|
||||
|
||||
static ProcEntry gProcTable[PROC_TABLE_SIZE];
|
||||
|
||||
static void ProcTableInsert(pid_t pid, uint32_t handle) {
|
||||
for (int i = 0; i < PROC_TABLE_SIZE; i++) {
|
||||
if (!gProcTable[i].used) {
|
||||
gProcTable[i] = (ProcEntry){ pid, handle, true };
|
||||
return;
|
||||
}
|
||||
}
|
||||
SysCloseHandle(handle);
|
||||
}
|
||||
|
||||
static uint32_t ProcTableFind(pid_t pid) {
|
||||
for (int i = 0; i < PROC_TABLE_SIZE; i++)
|
||||
if (gProcTable[i].used && gProcTable[i].pid == pid)
|
||||
return gProcTable[i].handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ProcTableRemove(pid_t pid) {
|
||||
for (int i = 0; i < PROC_TABLE_SIZE; i++)
|
||||
if (gProcTable[i].used && gProcTable[i].pid == pid)
|
||||
gProcTable[i].used = false;
|
||||
}
|
||||
|
||||
// Build a flat Windows-style cmdline from a NULL-terminated argv array.
|
||||
// Each token that contains a space is wrapped in double-quotes.
|
||||
// argv[0] is included (it becomes the executable token visible to _start).
|
||||
static void BuildCmdline(char* const argv[], char* out, size_t outSize) {
|
||||
size_t pos = 0;
|
||||
for (int i = 0; argv && argv[i]; i++) {
|
||||
if (i > 0 && pos < outSize - 1) out[pos++] = ' ';
|
||||
const char* tok = argv[i];
|
||||
bool needQuote = false;
|
||||
for (const char* c = tok; *c; c++) if (*c == ' ' || *c == '\t') { needQuote = true; break; }
|
||||
if (needQuote && pos < outSize - 1) out[pos++] = '"';
|
||||
for (; *tok && pos < outSize - 2; tok++) {
|
||||
if (*tok == '"') { out[pos++] = '\\'; }
|
||||
out[pos++] = *tok;
|
||||
}
|
||||
if (needQuote && pos < outSize - 1) out[pos++] = '"';
|
||||
}
|
||||
if (pos < outSize) out[pos] = '\0';
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// POSIX API
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
__declspec(dllexport) pid_t getpid(void) {
|
||||
return (pid_t)SysGetCurrentPid();
|
||||
}
|
||||
|
||||
__declspec(dllexport) int posix_spawn(pid_t* pidOut,
|
||||
const char* path,
|
||||
const posix_spawn_file_actions_t* file_actions, // ignored v1
|
||||
const posix_spawnattr_t* attrp, // ignored v1
|
||||
char* const argv[],
|
||||
char* const envp[]) // ignored v1
|
||||
{
|
||||
(void)file_actions; (void)attrp; (void)envp;
|
||||
|
||||
char native[512];
|
||||
PosixTranslatePath(path, native, sizeof(native));
|
||||
|
||||
char cmdline[512];
|
||||
BuildCmdline(argv, cmdline, sizeof(cmdline));
|
||||
// If argv was NULL or empty, fall back to just the path so _start still
|
||||
// gets a meaningful argv[0].
|
||||
if (cmdline[0] == '\0') {
|
||||
size_t len = strlen(path);
|
||||
if (len >= sizeof(cmdline)) len = sizeof(cmdline) - 1;
|
||||
memcpy(cmdline, path, len);
|
||||
cmdline[len] = '\0';
|
||||
}
|
||||
|
||||
uint32_t procHandle;
|
||||
SYS_CREATE_PROCESS_REQUEST req = { SysSvFromCstr(native), SysSvFromCstr(cmdline), &procHandle };
|
||||
uint32_t s = SysCreateProcess(&req);
|
||||
if (s != 0) { errno = ENOENT; return -1; }
|
||||
|
||||
uint32_t kpid = 0;
|
||||
SysGetProcessPid(procHandle, &kpid);
|
||||
ProcTableInsert((pid_t)kpid, procHandle);
|
||||
if (pidOut) *pidOut = (pid_t)kpid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// options: WNOHANG not supported in v1 (always blocks).
|
||||
__declspec(dllexport) pid_t waitpid(pid_t pid, int* status, int options) {
|
||||
(void)options;
|
||||
|
||||
uint32_t handle = ProcTableFind(pid);
|
||||
if (!handle) { errno = ESRCH; return -1; }
|
||||
|
||||
SysWaitForProcess(handle);
|
||||
|
||||
int exitCode = 0;
|
||||
SysGetProcessExitCode(handle, &exitCode);
|
||||
if (status) *status = exitCode << 8; // WEXITSTATUS convention
|
||||
|
||||
SysCloseHandle(handle);
|
||||
ProcTableRemove(pid);
|
||||
return pid;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void exit(int status) {
|
||||
SysExitProcess(status);
|
||||
}
|
||||
Reference in new issue
Block a user