mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 04:50:29 +00:00
Fix FreeBSD implementations of read_at and write_at
These procedures must not modify the underlying file pointer.
This commit is contained in:
@@ -6,6 +6,7 @@ foreign import libc "system:c"
|
||||
import "base:runtime"
|
||||
import "core:strings"
|
||||
import "core:c"
|
||||
import "core:sys/freebsd"
|
||||
|
||||
Handle :: distinct i32
|
||||
File_Time :: distinct u64
|
||||
@@ -481,23 +482,27 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) {
|
||||
}
|
||||
|
||||
read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) {
|
||||
curr := seek(fd, offset, SEEK_CUR) or_return
|
||||
n, err = read(fd, data)
|
||||
_, err1 := seek(fd, curr, SEEK_SET)
|
||||
if err1 != nil && err == nil {
|
||||
err = err1
|
||||
if len(data) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return
|
||||
|
||||
to_read := min(uint(len(data)), MAX_RW)
|
||||
|
||||
bytes_read, errno := freebsd.pread(cast(freebsd.Fd)fd, data[:to_read], cast(freebsd.off_t)offset)
|
||||
|
||||
return bytes_read, cast(_Platform_Error)errno
|
||||
}
|
||||
|
||||
write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) {
|
||||
curr := seek(fd, offset, SEEK_CUR) or_return
|
||||
n, err = write(fd, data)
|
||||
_, err1 := seek(fd, curr, SEEK_SET)
|
||||
if err1 != nil && err == nil {
|
||||
err = err1
|
||||
if len(data) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return
|
||||
|
||||
to_write := min(uint(len(data)), MAX_RW)
|
||||
|
||||
bytes_written, errno := freebsd.pwrite(cast(freebsd.Fd)fd, data[:to_write], cast(freebsd.off_t)offset)
|
||||
|
||||
return bytes_written, cast(_Platform_Error)errno
|
||||
}
|
||||
|
||||
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
|
||||
|
||||
@@ -14,6 +14,8 @@ import "core:c"
|
||||
// FreeBSD 15 syscall numbers
|
||||
// See: https://alfonsosiciliano.gitlab.io/posts/2023-08-28-freebsd-15-system-calls.html
|
||||
|
||||
SYS_read : uintptr : 3
|
||||
SYS_write : uintptr : 4
|
||||
SYS_open : uintptr : 5
|
||||
SYS_close : uintptr : 6
|
||||
SYS_getpid : uintptr : 20
|
||||
@@ -29,12 +31,46 @@ SYS_shutdown : uintptr : 134
|
||||
SYS_setsockopt : uintptr : 105
|
||||
SYS_sysctl : uintptr : 202
|
||||
SYS__umtx_op : uintptr : 454
|
||||
SYS_pread : uintptr : 475
|
||||
SYS_pwrite : uintptr : 476
|
||||
SYS_accept4 : uintptr : 541
|
||||
|
||||
//
|
||||
// Odin syscall wrappers
|
||||
//
|
||||
|
||||
// Read input.
|
||||
//
|
||||
// The read() function appeared in Version 1 AT&T UNIX.
|
||||
read :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_read,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf))
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Write output.
|
||||
//
|
||||
// The write() function appeared in Version 1 AT&T UNIX.
|
||||
write :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_pwrite,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf))
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Open or create a file for reading, writing or executing.
|
||||
//
|
||||
// The open() function appeared in Version 1 AT&T UNIX.
|
||||
@@ -469,6 +505,46 @@ _umtx_op :: proc "contextless" (obj: rawptr, op: Userland_Mutex_Operation, val:
|
||||
return cast(Errno)result
|
||||
}
|
||||
|
||||
// Read input without modifying the file pointer.
|
||||
//
|
||||
// The pread() function appeared in AT&T System V Release 4 UNIX.
|
||||
pread :: proc "contextless" (fd: Fd, buf: []u8, offset: off_t) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_pread,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf),
|
||||
cast(uintptr)offset)
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Write output without modifying the file pointer.
|
||||
//
|
||||
// The pwrite() function appeared in AT&T System V Release 4 UNIX.
|
||||
//
|
||||
// BUGS
|
||||
//
|
||||
// The pwrite() system call appends the file without changing the file
|
||||
// offset if O_APPEND is set, contrary to IEEE Std 1003.1-2008 (“POSIX.1”)
|
||||
// where pwrite() writes into offset regardless of whether O_APPEND is set.
|
||||
pwrite :: proc "contextless" (fd: Fd, buf: []u8, offset: off_t) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_pwrite,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf),
|
||||
cast(uintptr)offset)
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Accept a connection on a socket.
|
||||
//
|
||||
// The accept4() system call appeared in FreeBSD 10.0.
|
||||
|
||||
Reference in New Issue
Block a user