2023-07-28 08:53:06 +00:00
|
|
|
|
|
|
|
// See src/tinyrt.h file for the interface this file implements
|
|
|
|
|
|
|
|
static _RT_Status _rt_file_std_handles_init() {
|
|
|
|
_rt_file_stdin.handle = GetStdHandle(STD_INPUT_HANDLE);
|
|
|
|
_rt_file_stdin.flags = _RT_FILE_READ;
|
|
|
|
_rt_file_stdout.handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
_rt_file_stdout.flags = _RT_FILE_WRITE;
|
|
|
|
_rt_file_stderr.handle = GetStdHandle(STD_ERROR_HANDLE);
|
|
|
|
_rt_file_stdout.flags = _RT_FILE_WRITE;
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _RT_Status _rt_file_open(_RT_File *file, char const *name, int _rt_flags) {
|
|
|
|
u32 access = 0;
|
|
|
|
if(_rt_flags & _RT_FILE_READ) access |= GENERIC_READ;
|
|
|
|
if(_rt_flags & _RT_FILE_WRITE) access |= GENERIC_WRITE;
|
|
|
|
u32 share = 0;
|
|
|
|
if((_rt_flags & _RT_FILE_READ) == 0) share |= FILE_SHARE_READ;
|
|
|
|
u32 creation = 0;
|
|
|
|
if(_rt_flags & _RT_FILE_TRUNCATE) {
|
|
|
|
creation = TRUNCATE_EXISTING;
|
|
|
|
}
|
|
|
|
else if(_rt_flags & _RT_FILE_CREATE) {
|
|
|
|
if(_rt_flags & _RT_FILE_EXCLUSIVE) creation = CREATE_ALWAYS;
|
|
|
|
else creation = CREATE_NEW;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(_rt_flags & _RT_FILE_EXCLUSIVE) creation = OPEN_ALWAYS;
|
|
|
|
else creation = OPEN_EXISTING;
|
|
|
|
}
|
|
|
|
HANDLE handle = CreateFileA(name, access, share, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(file == INVALID_HANDLE_VALUE) {
|
|
|
|
// ERROR_FILE_NOT_FOUND
|
|
|
|
// ERROR_PATH_NOT_FOUND
|
|
|
|
// ERROR_ACCESS_DENIED
|
|
|
|
// ERROR_NOT_ENOUGH_MEMORY
|
|
|
|
return _RT_STATUS_FILE_IO_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
file->handle = handle;
|
|
|
|
file->flags = _rt_flags;
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read) {
|
|
|
|
*out_bytes_read = 0;
|
|
|
|
BOOL ok = ReadFile(from->handle, buffer, size, (unsigned long *)out_bytes_read, NULL);
|
|
|
|
if(!ok) {
|
|
|
|
return _RT_STATUS_FILE_IO_ERROR;
|
|
|
|
}
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written) {
|
|
|
|
*out_bytes_written = 0;
|
|
|
|
BOOL ok = WriteFile(to->handle, buffer, size, (unsigned long *)out_bytes_written, NULL);
|
|
|
|
if(!ok) {
|
|
|
|
return _RT_STATUS_FILE_IO_ERROR;
|
|
|
|
}
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _RT_Status _rt_file_close(_RT_File *file) {
|
|
|
|
BOOL ok = CloseHandle(file->handle);
|
|
|
|
if(!ok) {
|
|
|
|
return _RT_STATUS_FILE_BAD_FILE;
|
|
|
|
}
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
2023-07-30 07:45:14 +00:00
|
|
|
_Noreturn static void _rt_program_exit(int code) {
|
2023-07-28 08:53:06 +00:00
|
|
|
ExitProcess(code);
|
|
|
|
__builtin_unreachable();
|
|
|
|
}
|
|
|
|
|
2023-07-28 10:49:56 +00:00
|
|
|
static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 min_size, void **out_addr) {
|
|
|
|
void *addr = VirtualAlloc(optional_desired_addr, min_size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
|
|
|
|
*out_addr = addr;
|
|
|
|
if(addr == NULL) {
|
|
|
|
return _RT_ERROR_GENERIC;
|
|
|
|
}
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static _RT_Status _rt_mem_free(void *addr) {
|
|
|
|
BOOL ok = VirtualFree(addr, 0, MEM_RELEASE);
|
|
|
|
if(!ok) {
|
|
|
|
return _RT_ERROR_GENERIC;
|
|
|
|
}
|
|
|
|
return _RT_STATUS_OK;
|
|
|
|
}
|
|
|
|
|