Browse Source

Better handling of allocators

gingerBill 1 year ago
parent
commit
2ddaae45f3

+ 1 - 1
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)

+ 8 - 5
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 {

+ 11 - 7
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 {

+ 4 - 5
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
 }

+ 2 - 2
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
 }
 

+ 11 - 11
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