Merge branch 'master' into allocator-mode-alloc-non-zeroed

This commit is contained in:
gingerBill
2022-11-03 12:47:11 +00:00
93 changed files with 3803 additions and 2576 deletions
+1 -4
View File
@@ -2,7 +2,6 @@ package os
import win32 "core:sys/windows"
import "core:strings"
import "core:time"
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
@@ -41,9 +40,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
// fi.mode |= file_type_mode(h);
}
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
windows_set_file_info_times(&fi, d)
fi.is_dir = fi.mode & File_Mode_Dir != 0
return
+4 -2
View File
@@ -162,7 +162,8 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
total_read: int
length := len(data)
to_read := min(win32.DWORD(length), MAX_RW)
// NOTE(Jeroen): `length` can't be casted to win32.DWORD here because it'll overflow if > 4 GiB and return 0 if exactly that.
to_read := min(i64(length), MAX_RW)
e: win32.BOOL
if is_console {
@@ -172,7 +173,8 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
return int(total_read), err
}
} else {
e = win32.ReadFile(handle, &data[total_read], to_read, &single_read_length, nil)
// NOTE(Jeroen): So we cast it here *after* we've ensured that `to_read` is at most MAX_RW (1 GiB)
e = win32.ReadFile(handle, &data[total_read], win32.DWORD(to_read), &single_read_length, nil)
}
if single_read_length <= 0 || !e {
err := Errno(win32.GetLastError())
+1 -1
View File
@@ -130,7 +130,7 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File {
f := new(File, _file_allocator())
f.impl.allocator = _file_allocator()
f.impl.fd = rawptr(fd)
f.impl.fd = rawptr(handle)
f.impl.name = strings.clone(name, f.impl.allocator)
f.impl.wname = win32.utf8_to_wstring(name, f.impl.allocator)
+32 -11
View File
@@ -369,27 +369,48 @@ close :: proc(fd: Handle) -> bool {
return _unix_close(fd) == 0
}
@(private)
MAX_RW :: 0x7fffffff // The limit on Darwin is max(i32), trying to read/write more than that fails.
write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
assert(fd != -1)
if len(data) == 0 {
return 0, 0
bytes_total := len(data)
bytes_written_total := 0
for bytes_written_total < bytes_total {
bytes_to_write := min(bytes_total - bytes_written_total, MAX_RW)
slice := data[bytes_written_total:bytes_written_total + bytes_to_write]
bytes_written := _unix_write(fd, raw_data(slice), bytes_to_write)
if bytes_written == -1 {
return bytes_written_total, 1
}
bytes_written_total += bytes_written
}
bytes_written := _unix_write(fd, raw_data(data), len(data))
if bytes_written == -1 {
return 0, 1
}
return bytes_written, 0
return bytes_written_total, 0
}
read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
assert(fd != -1)
bytes_read := _unix_read(fd, raw_data(data), len(data))
if bytes_read == -1 {
return 0, 1
bytes_total := len(data)
bytes_read_total := 0
for bytes_read_total < bytes_total {
bytes_to_read := min(bytes_total - bytes_read_total, MAX_RW)
slice := data[bytes_read_total:bytes_read_total + bytes_to_read]
bytes_read := _unix_read(fd, raw_data(slice), bytes_to_read)
if bytes_read == -1 {
return bytes_read_total, 1
}
if bytes_read == 0 {
break
}
bytes_read_total += bytes_read
}
return bytes_read, 0
return bytes_read_total, 0
}
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
+32 -3
View File
@@ -24,7 +24,7 @@ O_CLOEXEC :: 0x80000
stdin: Handle = 0
stdout: Handle = 1
stderr: Handle = 2
current_dir: Handle = 3
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
iovs := wasi.ciovec_t(data)
@@ -47,7 +47,36 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
return int(n), Errno(err)
}
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
return 0, -1
oflags: wasi.oflags_t
if mode & O_CREATE == O_CREATE {
oflags += {.CREATE}
}
if mode & O_EXCL == O_EXCL {
oflags += {.EXCL}
}
if mode & O_TRUNC == O_TRUNC {
oflags += {.TRUNC}
}
rights: wasi.rights_t = {.FD_SEEK, .FD_FILESTAT_GET}
switch mode & (O_RDONLY|O_WRONLY|O_RDWR) {
case O_RDONLY: rights += {.FD_READ}
case O_WRONLY: rights += {.FD_WRITE}
case O_RDWR: rights += {.FD_READ, .FD_WRITE}
}
fdflags: wasi.fdflags_t
if mode & O_APPEND == O_APPEND {
fdflags += {.APPEND}
}
if mode & O_NONBLOCK == O_NONBLOCK {
fdflags += {.NONBLOCK}
}
if mode & O_SYNC == O_SYNC {
fdflags += {.SYNC}
}
fd, err := wasi.path_open(wasi.fd_t(current_dir),{.SYMLINK_FOLLOW},path,oflags,rights,{},fdflags)
return Handle(fd), Errno(err)
}
close :: proc(fd: Handle) -> Errno {
err := wasi.fd_close(wasi.fd_t(fd))
@@ -96,4 +125,4 @@ heap_free :: proc(ptr: rawptr) {
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
wasi.proc_exit(wasi.exitcode_t(code))
}
}
+10 -10
View File
@@ -228,6 +228,13 @@ file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HAN
return
}
@(private)
windows_set_file_info_times :: proc(fi: ^File_Info, d: ^$T) {
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
}
@(private)
file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Errno) {
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
@@ -235,9 +242,7 @@ file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_
fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
fi.is_dir = fi.mode & File_Mode_Dir != 0
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
windows_set_file_info_times(&fi, d)
fi.fullpath, e = full_path_from_name(name)
fi.name = basename(fi.fullpath)
@@ -252,9 +257,7 @@ file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string)
fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
fi.is_dir = fi.mode & File_Mode_Dir != 0
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
windows_set_file_info_times(&fi, d)
fi.fullpath, e = full_path_from_name(name)
fi.name = basename(fi.fullpath)
@@ -290,10 +293,7 @@ file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HAN
fi.mode |= file_mode_from_file_attributes(ti.FileAttributes, h, ti.ReparseTag)
fi.is_dir = fi.mode & File_Mode_Dir != 0
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
windows_set_file_info_times(&fi, &d)
return fi, ERROR_NONE
}