mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-26 05:25:00 -07:00
moved platform depended code from OS layer to linkers IO
This commit is contained in:
+139
-80
@@ -10,15 +10,6 @@ lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t
|
||||
return !os_handle_match(handle, os_handle_zero());
|
||||
}
|
||||
|
||||
shared_function int
|
||||
lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
|
||||
{
|
||||
OS_Handle handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, str8((U8*)path, path_size));
|
||||
Assert(sizeof(handle) <= handle_buffer_max);
|
||||
MemoryCopy(handle_buffer, &handle, sizeof(handle));
|
||||
return !os_handle_match(handle, os_handle_zero());
|
||||
}
|
||||
|
||||
shared_function int
|
||||
lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
|
||||
{
|
||||
@@ -35,14 +26,6 @@ lnk_close_file(void *raw_handle)
|
||||
os_file_close(handle);
|
||||
}
|
||||
|
||||
shared_function int
|
||||
lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size)
|
||||
{
|
||||
OS_Handle handle = *(OS_Handle *)raw_handle;
|
||||
B32 is_renamed = os_rename_file_by_handle(handle, str8((U8*)new_file_path, new_file_path_size));
|
||||
return (int)is_renamed;
|
||||
}
|
||||
|
||||
shared_function uint64_t
|
||||
lnk_size_from_file(void *raw_handle)
|
||||
{
|
||||
@@ -70,6 +53,118 @@ lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal String8List
|
||||
lnk_file_search(Arena *arena, String8List dir_list, String8 file_path)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List match_list; MemoryZeroStruct(&match_list);
|
||||
|
||||
if (os_file_path_exists(file_path)) {
|
||||
String8 str = push_str8_copy(arena, file_path);
|
||||
str8_list_push(arena, &match_list, str);
|
||||
}
|
||||
|
||||
PathStyle file_path_style = path_style_from_str8(file_path);
|
||||
B32 is_relative = file_path_style != PathStyle_WindowsAbsolute &&
|
||||
file_path_style != PathStyle_UnixAbsolute;
|
||||
|
||||
if (is_relative) {
|
||||
for (String8Node *i = dir_list.first; i != 0; i = i->next) {
|
||||
String8List path_list = {0};
|
||||
str8_list_push(scratch.arena, &path_list, i->string);
|
||||
str8_list_push(scratch.arena, &path_list, file_path);
|
||||
String8 path = str8_path_list_join_by_style(scratch.arena, &path_list, PathStyle_SystemAbsolute);
|
||||
B32 file_exists = os_file_path_exists(path);
|
||||
if (file_exists) {
|
||||
B32 is_unique = 1;
|
||||
OS_FileID file_id = os_id_from_file_path(path);
|
||||
for (String8Node *k = match_list.first; k != 0; k = k->next) {
|
||||
OS_FileID test_id = os_id_from_file_path(k->string);
|
||||
int cmp = os_file_id_compare(test_id, file_id) != 0;
|
||||
if (cmp == 0) {
|
||||
is_unique = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_unique) {
|
||||
String8 str = push_str8_copy(arena, path);
|
||||
str8_list_push(arena, &match_list, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
return match_list;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
lnk_file_open_with_rename_permissions(String8 path)
|
||||
{
|
||||
OS_Handle file_handle = os_handle_zero();
|
||||
#if _WIN32
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
|
||||
// open file with permissions to rename
|
||||
String16 path16 = str16_from_8(scratch.arena, path);
|
||||
SECURITY_ATTRIBUTES security_attributes = { sizeof(security_attributes) };
|
||||
HANDLE native_handle = CreateFileW((WCHAR*)path16.str,
|
||||
GENERIC_WRITE|DELETE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
&security_attributes,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
if (native_handle != INVALID_HANDLE_VALUE) {
|
||||
file_handle.u64[0] = (U64)native_handle;
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
#else
|
||||
#error "TODO: file rename"
|
||||
#endif
|
||||
return file_handle;
|
||||
}
|
||||
|
||||
internal B32
|
||||
lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file)
|
||||
{
|
||||
#if _WIN32
|
||||
FILE_DISPOSITION_INFO file_disposition = {0};
|
||||
file_disposition.DeleteFile = (BOOL)delete_file;
|
||||
B32 is_set = SetFileInformationByHandle((HANDLE)handle.u64[0], FileDispositionInfo, &file_disposition, sizeof(file_disposition));
|
||||
#else
|
||||
#error "TODO: file rename"
|
||||
#endif
|
||||
return is_set;
|
||||
}
|
||||
|
||||
internal B32
|
||||
lnk_file_rename(OS_Handle handle, String8 new_name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
#if _WIN32
|
||||
String16 new_name16 = str16_from_8(scratch.arena, new_name);
|
||||
|
||||
U64 file_rename_info_size = sizeof(FILE_RENAME_INFO);
|
||||
U64 buffer_size = file_rename_info_size + sizeof(new_name16.str)*new_name16.size;
|
||||
U8 *buffer = push_array(scratch.arena, U8, buffer_size);
|
||||
|
||||
FILE_RENAME_INFO *rename_info = (FILE_RENAME_INFO *)buffer;
|
||||
rename_info->ReplaceIfExists = 1;
|
||||
rename_info->FileNameLength = new_name16.size * sizeof(new_name16.str[0]);
|
||||
MemoryCopy(rename_info->FileName, new_name16.str, new_name16.size * sizeof(new_name16.str[0]));
|
||||
|
||||
B32 is_renamed = SetFileInformationByHandle((HANDLE)handle.u64[0], FileRenameInfo, buffer, buffer_size);
|
||||
#else
|
||||
#error "TODO: file rename"
|
||||
#endif
|
||||
scratch_end(scratch);
|
||||
return is_renamed;
|
||||
}
|
||||
|
||||
internal void
|
||||
lnk_log_read(String8 path, U64 size)
|
||||
{
|
||||
@@ -184,38 +279,48 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da
|
||||
{
|
||||
ProfBeginV("Write %M to %S", data.total_size, path);
|
||||
|
||||
U64 bytes_written = 0;
|
||||
|
||||
B32 open_with_rename = (temp_path.size > 0);
|
||||
OS_Handle file_handle = {0};
|
||||
String8 open_file_path = {0};
|
||||
if (open_with_rename) {
|
||||
lnk_open_file_write_rename((char*)temp_path.str, temp_path.size, &file_handle, sizeof(file_handle));
|
||||
file_handle = lnk_file_open_with_rename_permissions(temp_path);
|
||||
open_file_path = temp_path;
|
||||
|
||||
// mark file to be deleted on exit, so we don't leave corrupted files on disk
|
||||
if (!lnk_file_set_delete_on_close(file_handle, 1)) {
|
||||
lnk_error(LNK_Error_IO, "failed to update file disposition on %S", open_file_path);
|
||||
}
|
||||
} else {
|
||||
lnk_open_file_write((char*)path.str, path.size, &file_handle, sizeof(file_handle));
|
||||
open_file_path = path;
|
||||
}
|
||||
|
||||
if (!os_handle_match(file_handle, os_handle_zero())) {
|
||||
// try to reserve up front file size
|
||||
if (!os_file_reserve_size(file_handle, data.total_size)) {
|
||||
lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", path, data.total_size);
|
||||
lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", open_file_path, data.total_size);
|
||||
}
|
||||
|
||||
// write data nodes
|
||||
{
|
||||
for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) {
|
||||
U64 write_size = lnk_write_file(&file_handle, bytes_written, data_n->string.str, data_n->string.size);
|
||||
if (write_size != data_n->string.size) {
|
||||
break;
|
||||
}
|
||||
bytes_written += data_n->string.size;
|
||||
U64 bytes_written = 0;
|
||||
for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) {
|
||||
U64 write_size = lnk_write_file(&file_handle, bytes_written, data_n->string.str, data_n->string.size);
|
||||
if (write_size != data_n->string.size) {
|
||||
break;
|
||||
}
|
||||
bytes_written += data_n->string.size;
|
||||
}
|
||||
|
||||
B32 is_write_complete = (bytes_written == data.total_size);
|
||||
|
||||
if (is_write_complete) {
|
||||
// rename file to original name
|
||||
// rename temp file
|
||||
if (open_with_rename) {
|
||||
if (lnk_rename_file(&file_handle, (char*)path.str, path.size)) {
|
||||
// all writes succeeded, remove delete on exit flag
|
||||
if (!lnk_file_set_delete_on_close(file_handle, 0)) {
|
||||
lnk_error(LNK_Error_IO, "failed to update file disposition on %S", open_file_path);
|
||||
}
|
||||
|
||||
if (lnk_file_rename(file_handle, path)) {
|
||||
lnk_log(LNK_Log_IO_Write, "Renamed %S -> %S", temp_path, path);
|
||||
} else {
|
||||
lnk_error(LNK_Error_IO, "failed to rename %S -> %S", temp_path, path);
|
||||
@@ -223,6 +328,9 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da
|
||||
}
|
||||
}
|
||||
|
||||
// clean up file handle
|
||||
lnk_close_file(&file_handle);
|
||||
|
||||
// log write
|
||||
if (is_write_complete) {
|
||||
if (lnk_get_log_status(LNK_Log_IO_Write)) {
|
||||
@@ -231,9 +339,6 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da
|
||||
} else {
|
||||
lnk_error(LNK_Error_IO, "incomplete write, %M written, expected %M, file %S", bytes_written, data.total_size, path);
|
||||
}
|
||||
|
||||
// clean up handle
|
||||
lnk_close_file(&file_handle);
|
||||
} else {
|
||||
lnk_error(LNK_Error_NoAccess, "don't have access to write to %S", path);
|
||||
}
|
||||
@@ -251,50 +356,4 @@ lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data)
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
internal String8List
|
||||
lnk_file_search(Arena *arena, String8List dir_list, String8 file_path)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List match_list; MemoryZeroStruct(&match_list);
|
||||
|
||||
if (os_file_path_exists(file_path)) {
|
||||
String8 str = push_str8_copy(arena, file_path);
|
||||
str8_list_push(arena, &match_list, str);
|
||||
}
|
||||
|
||||
PathStyle file_path_style = path_style_from_str8(file_path);
|
||||
B32 is_relative = file_path_style != PathStyle_WindowsAbsolute &&
|
||||
file_path_style != PathStyle_UnixAbsolute;
|
||||
|
||||
if (is_relative) {
|
||||
for (String8Node *i = dir_list.first; i != 0; i = i->next) {
|
||||
String8List path_list = {0};
|
||||
str8_list_push(scratch.arena, &path_list, i->string);
|
||||
str8_list_push(scratch.arena, &path_list, file_path);
|
||||
String8 path = str8_path_list_join_by_style(scratch.arena, &path_list, PathStyle_SystemAbsolute);
|
||||
B32 file_exists = os_file_path_exists(path);
|
||||
if (file_exists) {
|
||||
B32 is_unique = 1;
|
||||
OS_FileID file_id = os_id_from_file_path(path);
|
||||
for (String8Node *k = match_list.first; k != 0; k = k->next) {
|
||||
OS_FileID test_id = os_id_from_file_path(k->string);
|
||||
int cmp = os_file_id_compare(test_id, file_id) != 0;
|
||||
if (cmp == 0) {
|
||||
is_unique = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_unique) {
|
||||
String8 str = push_str8_copy(arena, path);
|
||||
str8_list_push(arena, &match_list, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
return match_list;
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -17,20 +17,23 @@ typedef struct
|
||||
|
||||
shared_function int lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max);
|
||||
shared_function int lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max);
|
||||
shared_function int lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max);
|
||||
shared_function void lnk_close_file(void *raw_handle);
|
||||
shared_function int lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size);
|
||||
shared_function uint64_t lnk_size_from_file(void *raw_handle);
|
||||
shared_function uint64_t lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max);
|
||||
shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path);
|
||||
|
||||
internal OS_Handle lnk_file_open_with_rename_permissions(String8 path);
|
||||
internal B32 lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file);
|
||||
internal B32 lnk_file_rename(OS_Handle handle, String8 new_name);
|
||||
|
||||
internal String8 lnk_read_data_from_file_path(Arena *arena, String8 path);
|
||||
internal String8Array lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, String8Array path_arr);
|
||||
|
||||
internal void lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List list);
|
||||
internal void lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data);
|
||||
|
||||
internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path);
|
||||
|
||||
|
||||
@@ -151,16 +151,6 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_rename_file(String8 orig_name, String8 new_name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, orig_name);
|
||||
B32 is_renamed = os_rename_file_by_handle(file, new_name);
|
||||
os_file_close(file);
|
||||
return is_renamed;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launcher Helpers
|
||||
|
||||
|
||||
@@ -44,8 +44,7 @@ enum
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
OS_AccessFlag_ShareDelete = (1<<6),
|
||||
OS_AccessFlag_Inherited = (1<<7),
|
||||
OS_AccessFlag_Inherited = (1<<6),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -207,7 +206,6 @@ internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data);
|
||||
internal B32 os_file_set_times(OS_Handle file, DateTime time);
|
||||
internal FileProperties os_properties_from_file(OS_Handle file);
|
||||
internal OS_FileID os_id_from_file(OS_Handle file);
|
||||
internal B32 os_rename_file_by_handle(OS_Handle file, String8 new_name);
|
||||
internal B32 os_rename_file(String8 orig_name, String8 new_name);
|
||||
internal B32 os_file_reserve_size(OS_Handle file, U64 size);
|
||||
internal B32 os_delete_file_at_path(String8 path);
|
||||
|
||||
@@ -326,7 +326,6 @@ os_file_open(OS_AccessFlags flags, String8 path)
|
||||
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
|
||||
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
|
||||
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;}
|
||||
if(flags & OS_AccessFlag_ShareDelete) {share_mode |= FILE_SHARE_DELETE; access_flags |= DELETE;}
|
||||
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
|
||||
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; }
|
||||
if(flags & OS_AccessFlag_Inherited)
|
||||
@@ -470,30 +469,6 @@ os_id_from_file(OS_Handle file)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_rename_file_by_handle(OS_Handle file, String8 new_name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
|
||||
HANDLE handle = (HANDLE)file.u64[0];
|
||||
|
||||
String16 new_name16 = str16_from_8(scratch.arena, new_name);
|
||||
|
||||
U64 file_rename_info_size = sizeof(FILE_RENAME_INFO);
|
||||
U64 buffer_size = file_rename_info_size + sizeof(WCHAR)*new_name16.size;
|
||||
U8 *buffer = push_array(scratch.arena, U8, buffer_size);
|
||||
|
||||
FILE_RENAME_INFO *rename_info = (FILE_RENAME_INFO *)buffer;
|
||||
rename_info->ReplaceIfExists = 1;
|
||||
rename_info->FileNameLength = new_name16.size * sizeof(new_name16.str[0]);
|
||||
MemoryCopy(rename_info->FileName, new_name16.str, new_name16.size * sizeof(new_name16.str[0]));
|
||||
|
||||
BOOL is_renamed = SetFileInformationByHandle(handle, FileRenameInfo, buffer, buffer_size);
|
||||
|
||||
scratch_end(scratch);
|
||||
return is_renamed;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_file_reserve_size(OS_Handle file, U64 size)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user