// POSIX compatibility support for posix dir. #include #include #include #include "posix.h" #include "posix_path.h" typedef SYS_DIR_ENTRY KDIR_ENTRY; #define KATTR_DIR 0x10 // Implements the chdir operation. __declspec(dllexport) int chdir(const char* path) { char native[512]; PosixTranslatePath(path, native, sizeof(native)); SYS_PATH_REQUEST req = { SysSvFromCstr(native) }; uint32_t s = SysSetCwd(&req); if (s != 0) { errno = ENOENT; return -1; } return 0; } // Implements the getcwd operation. __declspec(dllexport) char* getcwd(char* buf, size_t size) { if (!buf || size == 0) { errno = EINVAL; return (char*)0; } char native[512]; size_t nativeLen = 0; SYS_GET_CWD_REQUEST req = { native, sizeof(native) - 1, &nativeLen }; uint32_t s = SysGetCwd(&req); if (s == 0) native[nativeLen] = '\0'; if (s != 0) { errno = ERANGE; return (char*)0; } NativeToPosix(native, buf, size); return buf; } // Implements the opendir operation. __declspec(dllexport) DIR* opendir(const char* path) { char native[512]; PosixTranslatePath(path, native, sizeof(native)); uint32_t kh; SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(native), &kh }; uint32_t s = SysOpenDir(&req); if (s != 0) { errno = ENOENT; return (DIR*)0; } // Allocate DIR on the kernel heap (malloc) so it outlives the stack. DIR* d = (DIR*)malloc(sizeof(DIR)); if (!d) { SysCloseHandle(kh); errno = ENOMEM; return (DIR*)0; } d->KHandle = kh; d->Valid = false; return d; } // Implements the readdir operation. __declspec(dllexport) struct dirent* readdir(DIR* d) { if (!d) { errno = EBADF; return (struct dirent*)0; } KDIR_ENTRY ke; uint32_t s = SysReadDir(d->KHandle, &ke); if (s != 0) return (struct dirent*)0; // end of directory or error size_t len = strlen(ke.Name); if (len > NAME_MAX) len = NAME_MAX; memcpy(d->Current.d_name, ke.Name, len); d->Current.d_name[len] = '\0'; d->Current.d_type = (ke.Attr & KATTR_DIR) ? DT_DIR : DT_REG; d->Valid = true; return &d->Current; } // Implements the closedir operation. __declspec(dllexport) int closedir(DIR* d) { if (!d) { errno = EBADF; return -1; } SysCloseHandle(d->KHandle); free(d); return 0; }