78 lines
2.7 KiB
C
78 lines
2.7 KiB
C
// POSIX compatibility support for posix fd.
|
|
|
|
#include <ntlite/syscall.h>
|
|
#include "posix.h"
|
|
#include "posix_fd.h"
|
|
|
|
int errno = 0;
|
|
|
|
// Implements the status To Errno operation.
|
|
int PosixStatusToErrno(uint32_t s) {
|
|
switch (s) {
|
|
case NTLSTATUS_SUCCESS: return 0;
|
|
case NTLSTATUS_NOT_SUPPORTED: return ENOSYS;
|
|
case NTLSTATUS_TIMEOUT: return EAGAIN;
|
|
case NTLSTATUS_WOULD_BLOCK: return EAGAIN;
|
|
case NTLSTATUS_INVALID_PARAMETER: return EINVAL;
|
|
case NTLSTATUS_INVALID_HANDLE: return EBADF;
|
|
case NTLSTATUS_BUFFER_TOO_SMALL: return ERANGE;
|
|
case NTLSTATUS_NO_MEMORY: return ENOMEM;
|
|
case NTLSTATUS_ACCESS_DENIED: return EACCES;
|
|
case NTLSTATUS_NOT_FOUND: return ENOENT;
|
|
case NTLSTATUS_ALREADY_EXISTS: return EEXIST;
|
|
case NTLSTATUS_OBJECT_NAME_COLLISION: return EEXIST;
|
|
case NTLSTATUS_OBJECT_DEAD: return ECONNRESET;
|
|
case NTLSTATUS_QUEUE_FULL: return EAGAIN;
|
|
case NTLSTATUS_QUEUE_EMPTY: return EAGAIN;
|
|
case NTLSTATUS_CANCELLED: return ECANCELED;
|
|
case NTLSTATUS_NO_MORE_FILES: return ENOENT;
|
|
default: return EIO;
|
|
}
|
|
}
|
|
|
|
static FD_ENTRY gFdTable[FD_TABLE_PIDS][FD_MAX];
|
|
|
|
// Implements the fd Init operation.
|
|
__declspec(dllexport) void PosixFdInit(void) {
|
|
uint32_t pid = SysGetCurrentPid();
|
|
uint32_t slot = pid % FD_TABLE_PIDS;
|
|
|
|
// Clear this process's slice (handles inherited state from a previous
|
|
// process that happened to land on the same slot - unlikely but safe).
|
|
for (int i = 0; i < FD_MAX; i++)
|
|
gFdTable[slot][i] = (FD_ENTRY){ FD_FREE, 0, false };
|
|
|
|
gFdTable[slot][0] = (FD_ENTRY){ FD_CONSOLE_R, 0, true };
|
|
gFdTable[slot][1] = (FD_ENTRY){ FD_CONSOLE_W, 0, true };
|
|
gFdTable[slot][2] = (FD_ENTRY){ FD_CONSOLE_W, 0, true };
|
|
}
|
|
|
|
// Implements the fd Alloc operation.
|
|
__declspec(dllexport) int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle) {
|
|
uint32_t slot = pid % FD_TABLE_PIDS;
|
|
for (int fd = 3; fd < FD_MAX; fd++) {
|
|
if (!gFdTable[slot][fd].Used) {
|
|
gFdTable[slot][fd] = (FD_ENTRY){ type, khandle, true };
|
|
return fd;
|
|
}
|
|
}
|
|
errno = EMFILE;
|
|
return -1;
|
|
}
|
|
|
|
// Implements the fd Get operation.
|
|
__declspec(dllexport) FD_ENTRY* FdGet(uint32_t pid, int fd) {
|
|
if (fd < 0 || fd >= FD_MAX) { errno = EBADF; return (FD_ENTRY*)0; }
|
|
uint32_t slot = pid % FD_TABLE_PIDS;
|
|
FD_ENTRY* e = &gFdTable[slot][fd];
|
|
if (!e->Used) { errno = EBADF; return (FD_ENTRY*)0; }
|
|
return e;
|
|
}
|
|
|
|
// Implements the fd Free operation.
|
|
__declspec(dllexport) void FdFree(uint32_t pid, int fd) {
|
|
if (fd < 0 || fd >= FD_MAX) return;
|
|
uint32_t slot = pid % FD_TABLE_PIDS;
|
|
gFdTable[slot][fd] = (FD_ENTRY){ FD_FREE, 0, false };
|
|
}
|