mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-31 02:12:04 +00:00
Better handling of allocators
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user