Files
nt-lite/code/user/personalities/posix/posix_dir.c
T

71 lines
2.1 KiB
C

// posix_dir.c - chdir, getcwd, opendir, readdir, closedir
#include <string.h>
#include <ntlite/syscall.h>
#include <stdlib.h>
#include "posix.h"
#include "posix_path.h"
typedef SYS_DIR_ENTRY KDIR_ENTRY;
#define KATTR_DIR 0x10
__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;
}
__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;
}
__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;
}
__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;
}
__declspec(dllexport) int closedir(DIR* d) {
if (!d) { errno = EBADF; return -1; }
SysCloseHandle(d->KHandle);
free(d);
return 0;
}