aboutsummaryrefslogtreecommitdiff
path: root/core/os
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-07-24 13:47:22 +0100
committergingerBill <bill@gingerbill.org>2024-07-24 13:47:22 +0100
commit2ddaae45f39c8d8fc3a0fc2bbe5705b8299edc85 (patch)
tree7b16bd1da3eabd5a3318c6db17ccf2d5b424a1a2 /core/os
parent6d2487a69215f8d018e7be830e838c6cb94c15ce (diff)
Better handling of allocators
Diffstat (limited to 'core/os')
-rw-r--r--core/os/os2/file.odin2
-rw-r--r--core/os/os2/file_linux.odin13
-rw-r--r--core/os/os2/file_windows.odin18
-rw-r--r--core/os/os2/path_linux.odin9
-rw-r--r--core/os/os2/pipe_linux.odin4
-rw-r--r--core/os/os2/stat_linux.odin22
6 files changed, 37 insertions, 31 deletions
diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin
index 8692ecf01..52fd02478 100644
--- a/core/os/os2/file.odin
+++ b/core/os/os2/file.odin
@@ -106,7 +106,7 @@ open :: proc(name: string, flags := File_Flags{.Read}, perm := 0o777) -> (^File,
@(require_results)
new_file :: proc(handle: uintptr, name: string) -> ^File {
- return _new_file(handle, name)
+ return _new_file(handle, name) or_else panic("Out of memory")
}
@(require_results)
diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin
index cf643b31a..d2a7483ca 100644
--- a/core/os/os2/file_linux.odin
+++ b/core/os/os2/file_linux.odin
@@ -88,21 +88,24 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err
return nil, _get_platform_error(errno)
}
- return _new_file(uintptr(fd), name), nil
+ return _new_file(uintptr(fd), name)
}
-_new_file :: proc(fd: uintptr, _: string = "") -> ^File {
- impl := new(File_Impl, file_allocator())
+_new_file :: proc(fd: uintptr, _: string = "") -> (f: ^File, err: Error) {
+ impl := new(File_Impl, file_allocator()) or_return
+ defer if err != nil {
+ free(impl, file_allocator())
+ }
impl.file.impl = impl
impl.fd = linux.Fd(fd)
impl.allocator = file_allocator()
- impl.name = _get_full_path(impl.fd, impl.allocator)
+ impl.name = _get_full_path(impl.fd, file_allocator()) or_return
impl.file.stream = {
data = impl,
procedure = _file_stream_proc,
}
impl.file.fstat = _fstat
- return &impl.file
+ return &impl.file, nil
}
_destroy :: proc(f: ^File_Impl) -> Error {
diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin
index 3c18d0546..39a3e7867 100644
--- a/core/os/os2/file_windows.odin
+++ b/core/os/os2/file_windows.odin
@@ -126,20 +126,24 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u
_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) {
flags := flags if flags != nil else {.Read}
handle := _open_internal(name, flags, perm) or_return
- return _new_file(handle, name), nil
+ return _new_file(handle, name)
}
-_new_file :: proc(handle: uintptr, name: string) -> ^File {
+_new_file :: proc(handle: uintptr, name: string) -> (f: ^File, err: Error) {
if handle == INVALID_HANDLE {
- return nil
+ return
}
- impl := new(File_Impl, file_allocator())
+ impl := new(File_Impl, file_allocator()) or_return
+ defer if err != nil {
+ free(impl, file_allocator())
+ }
+
impl.file.impl = impl
impl.allocator = file_allocator()
impl.fd = rawptr(handle)
- impl.name, _ = clone_string(name, impl.allocator)
- impl.wname, _ = win32_utf8_to_wstring(name, impl.allocator)
+ impl.name = clone_string(name, impl.allocator) or_return
+ impl.wname = win32_utf8_to_wstring(name, impl.allocator) or_return
handle := _handle(&impl.file)
kind := File_Impl_Kind.File
@@ -157,7 +161,7 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File {
}
impl.file.fstat = _fstat
- return &impl.file
+ return &impl.file, nil
}
_fd :: proc(f: ^File) -> uintptr {
diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin
index 1634c79c8..be60f9b86 100644
--- a/core/os/os2/path_linux.odin
+++ b/core/os/os2/path_linux.odin
@@ -188,7 +188,7 @@ _set_working_directory :: proc(dir: string) -> Error {
return _get_platform_error(linux.chdir(dir_cstr))
}
-_get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> string {
+_get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fullpath: string, err: Error) {
PROC_FD_PATH :: "/proc/self/fd/"
buf: [32]u8
@@ -196,10 +196,9 @@ _get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> string {
strconv.itoa(buf[len(PROC_FD_PATH):], int(fd))
- fullpath: string
- err: Error
if fullpath, err = _read_link_cstr(cstring(&buf[0]), allocator); err != nil || fullpath[0] != '/' {
- return ""
+ delete(fullpath, allocator)
+ fullpath = ""
}
- return fullpath
+ return
}
diff --git a/core/os/os2/pipe_linux.odin b/core/os/os2/pipe_linux.odin
index 8835cc30f..c3fecfb9e 100644
--- a/core/os/os2/pipe_linux.odin
+++ b/core/os/os2/pipe_linux.odin
@@ -10,8 +10,8 @@ _pipe :: proc() -> (r, w: ^File, err: Error) {
return nil, nil,_get_platform_error(errno)
}
- r = _new_file(uintptr(fds[0]))
- w = _new_file(uintptr(fds[1]))
+ r = _new_file(uintptr(fds[0])) or_return
+ w = _new_file(uintptr(fds[1])) or_return
return
}
diff --git a/core/os/os2/stat_linux.odin b/core/os/os2/stat_linux.odin
index 39a364c9a..eb31e2200 100644
--- a/core/os/os2/stat_linux.odin
+++ b/core/os/os2/stat_linux.odin
@@ -11,7 +11,7 @@ _fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) {
return _fstat_internal(impl.fd, allocator)
}
-_fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (File_Info, Error) {
+_fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File_Info, err: Error) {
s: linux.Stat
errno := linux.fstat(fd, &s)
if errno != .NONE {
@@ -30,20 +30,20 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (File_Inf
mode := int(0o7777 & transmute(u32)s.mode)
// TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time
- fi := File_Info {
- fullpath = _get_full_path(fd, allocator),
- name = "",
- inode = u64(s.ino),
- size = i64(s.size),
- mode = mode,
- type = type,
+ fi = File_Info {
+ fullpath = _get_full_path(fd, allocator) or_return,
+ name = "",
+ inode = u64(s.ino),
+ size = i64(s.size),
+ mode = mode,
+ type = type,
modification_time = time.Time {i64(s.mtime.time_sec) * i64(time.Second) + i64(s.mtime.time_nsec)},
- access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)},
- creation_time = time.Time{i64(s.ctime.time_sec) * i64(time.Second) + i64(s.ctime.time_nsec)}, // regular stat does not provide this
+ access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)},
+ creation_time = time.Time{i64(s.ctime.time_sec) * i64(time.Second) + i64(s.ctime.time_nsec)}, // regular stat does not provide this
}
fi.creation_time = fi.modification_time
fi.name = filepath.base(fi.fullpath)
- return fi, nil
+ return
}
// NOTE: _stat and _lstat are using _fstat to avoid a race condition when populating fullpath