// POSIX compatibility support for posix fd. #include #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 }; }