doom is now using the native api, add a PEB + TEB to replace the dummy and the awkward argument passing to processes, all allocations are zeroed because i had enough, small readme changes and dedication.
This commit is contained in:
1 parent
ddb5d5f5d8
commit
f5fd7bdd75
28 files changed
+6334
-5722
No files matched your search
@@ -78,6 +78,8 @@ typedef void* pthread_mutexattr_t;
|
||||
typedef void* posix_spawn_file_actions_t;
|
||||
typedef void* posix_spawnattr_t;
|
||||
|
||||
__declspec(dllexport) const char* posix_get_command_line(void);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// dirent (used by posix_dir.c)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
+28
-8
@@ -22,9 +22,12 @@ static int KsToErrno(uint32_t s) {
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(dllexport) int ClearConsoleScreenBuffer(void* hConsole) {
|
||||
__declspec(dllexport) void clearscreen(void) {
|
||||
SysScreenClear(0x00000000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void clearkeyboard(void) {
|
||||
while (SysKbPoll()) (void)SysKbReadChar();
|
||||
}
|
||||
|
||||
__declspec(dllexport) int open(const char* path, int flags, ...) {
|
||||
@@ -154,14 +157,31 @@ __declspec(dllexport) off_t lseek(int fd, off_t offset, int whence) {
|
||||
FD_ENTRY* e = FdGet(pid, fd);
|
||||
if (!e || e->Type != FD_FILE) { errno = (e ? ESPIPE : EBADF); return -1; }
|
||||
|
||||
uint64_t target;
|
||||
int64_t target = 0;
|
||||
switch (whence) {
|
||||
case SEEK_SET: target = (uint64_t)offset; break;
|
||||
case SEEK_CUR: target = SysGetFilePos(e->KHandle) + (uint64_t)offset; break;
|
||||
case SEEK_END: target = SysGetFileSize(e->KHandle) + (uint64_t)offset; break;
|
||||
default: errno = EINVAL; return -1;
|
||||
case SEEK_SET:
|
||||
target = (int64_t)offset;
|
||||
break;
|
||||
case SEEK_CUR: {
|
||||
uint64_t cur = SysGetFilePos(e->KHandle);
|
||||
if (cur > 0x7FFFFFFFULL) { errno = EINVAL; return -1; }
|
||||
target = (int64_t)cur + (int64_t)offset;
|
||||
break;
|
||||
}
|
||||
case SEEK_END: {
|
||||
uint64_t size = SysGetFileSize(e->KHandle);
|
||||
if (size > 0x7FFFFFFFULL) { errno = EINVAL; return -1; }
|
||||
target = (int64_t)size + (int64_t)offset;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
uint32_t s = SysSeekFile(e->KHandle, target);
|
||||
|
||||
if (target < 0 || target > 0x7FFFFFFFLL) { errno = EINVAL; return -1; }
|
||||
|
||||
uint32_t s = SysSeekFile(e->KHandle, (uint64_t)target);
|
||||
if (s != 0) { errno = KsToErrno(s); return -1; }
|
||||
return (off_t)target;
|
||||
}
|
||||
@@ -5,6 +5,20 @@
|
||||
#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) return "";
|
||||
return peb->CommandLine;
|
||||
}
|
||||
|
||||
// pid -> proc handle table (user-mode side, for waitpid)
|
||||
#define PROC_TABLE_SIZE 32
|
||||
typedef struct {
|
||||
|
||||
+12
-12
@@ -41,7 +41,6 @@ typedef struct {
|
||||
void* (*Fn)(void*);
|
||||
void* Arg;
|
||||
uint32_t Pid; // owner pid, for the retval table
|
||||
uint32_t Tid; // filled in by pthread_create after KeCreateThread returns
|
||||
} PTHREAD_TRAMP;
|
||||
|
||||
static void PthreadTrampoline(uintptr_t raw) {
|
||||
@@ -49,14 +48,19 @@ static void PthreadTrampoline(uintptr_t raw) {
|
||||
void* (*fn)(void*) = tr->Fn;
|
||||
void* arg = tr->Arg;
|
||||
uint32_t pid = tr->Pid;
|
||||
uint32_t tid = tr->Tid;
|
||||
uint32_t tid = SysGetCurrentTid();
|
||||
|
||||
// Create the join slot from inside the new thread. KeCreateThread makes the
|
||||
// thread runnable before the creator regains control, so the old design
|
||||
// raced on tr->Tid and could observe zero/stale memory.
|
||||
PTHREAD_SLOT* slot = PthreadSlotFind(pid, tid);
|
||||
if (!slot) slot = PthreadSlotAlloc(pid, tid);
|
||||
|
||||
SysFree(tr, sizeof(PTHREAD_TRAMP));
|
||||
|
||||
void* retval = fn(arg);
|
||||
|
||||
// Store retval for pthread_join. If the slot isn't there (join was called
|
||||
// before the thread was even created, which shouldn't happen) just drop it.
|
||||
PTHREAD_SLOT* slot = PthreadSlotFind(pid, tid);
|
||||
// Store retval for pthread_join.
|
||||
if (slot) slot->RetVal = retval;
|
||||
|
||||
SysExitThread(0);
|
||||
@@ -77,7 +81,6 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
tr->Fn = fn;
|
||||
tr->Arg = arg;
|
||||
tr->Pid = pid;
|
||||
tr->Tid = 0; // filled below
|
||||
|
||||
uint32_t tid = 0;
|
||||
uint32_t s = SysCreateThread((uint64_t)PthreadTrampoline,
|
||||
@@ -86,12 +89,9 @@ __declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* att
|
||||
SysFree(tr, sizeof(PTHREAD_TRAMP));
|
||||
return EAGAIN;
|
||||
}
|
||||
tr->Tid = tid; // safe: trampoline reads Tid after SysCreateThread returns
|
||||
|
||||
// Reserve a retval slot before the trampoline can exit
|
||||
PthreadSlotAlloc(pid, tid);
|
||||
|
||||
t->Tid = tid;
|
||||
// The trampoline allocates the retval slot itself after it knows its real
|
||||
// TID, avoiding the creator/new-thread race.
|
||||
if (t) t->Tid = tid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user