// posix_io.c - open, read, write, close, lseek #include #include #include #include "posix.h" #include "posix_fd.h" #include "posix_path.h" // KSTATUS -> errno static int KsToErrno(uint32_t s) { switch (s) { case 0x0000: return 0; // STATUS_SUCCESS case 0x0022: return ENOENT; // STATUS_NOT_FOUND case 0x0021: return EACCES; // STATUS_ACCESS_DENIED case 0x0020: return ENOMEM; // STATUS_NO_MEMORY case 0x0023: return EEXIST; // STATUS_ALREADY_EXISTS case 0x0010: return EINVAL; // STATUS_INVALID_PARAMETER case 0x0012: return ERANGE; // STATUS_BUFFER_TOO_SMALL case 0x0002: return ENOSYS; // STATUS_NOT_SUPPORTED case 0x0031: return EAGAIN; // STATUS_QUEUE_FULL default: return EIO; } } __declspec(dllexport) int ClearConsoleScreenBuffer(void* hConsole) { SysScreenClear(0x00000000); return 1; } __declspec(dllexport) int open(const char* path, int flags, ...) { char native[512]; const char* p = PosixTranslatePath(path, native, sizeof(native)); uint32_t pid = SysGetCurrentPid(); FD_TYPE type = FD_FILE; // Synthetic devices if (strcmp(p, SYNTH_DEVNULL) == 0) { int fd = FdAlloc(pid, FD_DEVNULL, 0); return fd; } if (strcmp(p, SYNTH_DEVZERO) == 0) { int fd = FdAlloc(pid, FD_DEVZERO, 0); return fd; } uint32_t kh = 0; uint32_t s; if (flags & O_WRONLY) { s = SysCreateFile(p, &kh); } else { s = SysOpenFile(p, &kh); } if (s != 0) { errno = KsToErrno(s); return -1; } if ((flags & O_TRUNC) && (flags & O_WRONLY)) SysTruncateFile(kh, 0); int fd = FdAlloc(pid, type, kh); if (fd < 0) { SysCloseHandle(kh); // FdAlloc already set errno return -1; } return fd; } __declspec(dllexport) ssize_t read(int fd, void* buf, size_t count) { if (count == 0) return 0; uint32_t pid = SysGetCurrentPid(); FD_ENTRY* e = FdGet(pid, fd); if (!e) return -1; switch (e->Type) { case FD_CONSOLE_R: { // Read up to count chars from keyboard, blocking per char. char* dst = (char*)buf; for (size_t i = 0; i < count; i++) { dst[i] = SysKbReadChar(); if (dst[i] == '\n' || dst[i] == '\r') return (ssize_t)(i + 1); } return (ssize_t)count; } case FD_DEVNULL: return 0; case FD_DEVZERO: memset(buf, 0, count); return (ssize_t)count; case FD_FILE: { size_t got = 0; uint32_t s = SysReadFile(e->KHandle, buf, count, &got); if (s != 0 && got == 0) { errno = KsToErrno(s); return -1; } return (ssize_t)got; } default: errno = EBADF; return -1; } } __declspec(dllexport) ssize_t write(int fd, const void* buf, size_t count) { if (count == 0) return 0; uint32_t pid = SysGetCurrentPid(); FD_ENTRY* e = FdGet(pid, fd); if (!e) return -1; switch (e->Type) { case FD_CONSOLE_W: SysWriteConsole((const char*)buf, count); return (ssize_t)count; case FD_DEVNULL: case FD_DEVZERO: return (ssize_t)count; case FD_FILE: { size_t written = 0; uint32_t s = SysWriteFile(e->KHandle, buf, count, &written); if (s != 0 && written == 0) { errno = KsToErrno(s); return -1; } return (ssize_t)written; } default: errno = EBADF; return -1; } } __declspec(dllexport) int close(int fd) { uint32_t pid = SysGetCurrentPid(); FD_ENTRY* e = FdGet(pid, fd); if (!e) return -1; if (e->Type == FD_FILE) SysCloseHandle(e->KHandle); FdFree(pid, fd); return 0; } __declspec(dllexport) int unlink(const char* path) { if (!path) { errno = EINVAL; return -1; } char native[512]; const char* p = PosixTranslatePath(path, native, sizeof(native)); if (strcmp(p, SYNTH_DEVNULL) == 0 || strcmp(p, SYNTH_DEVZERO) == 0) { errno = EINVAL; return -1; } uint32_t s = SysDeleteFile(p); if (s != 0) { errno = KsToErrno(s); return -1; } return 0; } __declspec(dllexport) off_t lseek(int fd, off_t offset, int whence) { uint32_t pid = SysGetCurrentPid(); FD_ENTRY* e = FdGet(pid, fd); if (!e || e->Type != FD_FILE) { errno = (e ? ESPIPE : EBADF); return -1; } uint64_t target; 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; } uint32_t s = SysSeekFile(e->KHandle, target); if (s != 0) { errno = KsToErrno(s); return -1; } return (off_t)target; }