From 0243647e15a7abc1f4dd567806af5f0c52823fb2 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 25 Aug 2024 21:01:30 -0400 Subject: [PATCH] Add missing `flush` functionality to `os` platforms Platforms: - FreeBSD - Haiku - Linux - NetBSD - OpenBSD --- core/os/os_freebsd.odin | 3 +-- core/os/os_haiku.odin | 6 +++++- core/os/os_linux.odin | 3 +-- core/os/os_netbsd.odin | 6 +++++- core/os/os_openbsd.odin | 6 +++++- core/sys/freebsd/syscalls.odin | 11 +++++++++++ 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index 16dcf2473..affff6910 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -447,8 +447,7 @@ close :: proc(fd: Handle) -> Error { } flush :: proc(fd: Handle) -> Error { - // do nothing - return nil + return cast(_Platform_Error)freebsd.fsync(cast(freebsd.Fd)fd) } // If you read or write more than `INT_MAX` bytes, FreeBSD returns `EINVAL`. diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin index 2371a909e..08bd4f832 100644 --- a/core/os/os_haiku.odin +++ b/core/os/os_haiku.odin @@ -142,6 +142,7 @@ foreign libc { @(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int --- @(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int --- @(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int --- + @(link_name="fsync") _unix_fsync :: proc(fd: Handle) -> c.int --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- @(link_name="sysconf") _sysconf :: proc(name: c.int) -> c.long --- @@ -218,7 +219,10 @@ close :: proc(fd: Handle) -> Error { } flush :: proc(fd: Handle) -> Error { - // do nothing + result := _unix_fsync(fd) + if result == -1 { + return get_last_error() + } return nil } diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 81ff5077a..ba200a308 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -584,8 +584,7 @@ close :: proc(fd: Handle) -> Error { } flush :: proc(fd: Handle) -> Error { - // do nothing - return nil + return _get_errno(unix.sys_fsync(int(fd))) } // If you read or write more than `SSIZE_MAX` bytes, result is implementation defined (probably an error). diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index 130848ab0..d84be41f7 100644 --- a/core/os/os_netbsd.odin +++ b/core/os/os_netbsd.odin @@ -443,6 +443,7 @@ foreign libc { @(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int --- @(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int --- @(link_name="fcntl") _unix_fcntl :: proc(fd: Handle, cmd: c.int, #c_vararg args: ..any) -> c.int --- + @(link_name="fsync") _unix_fsync :: proc(fd: Handle) -> c.int --- @(link_name="dup") _unix_dup :: proc(fd: Handle) -> Handle --- @(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir --- @@ -506,7 +507,10 @@ close :: proc(fd: Handle) -> Error { } flush :: proc(fd: Handle) -> Error { - // do nothing + result := _unix_fsync(fd) + if result == -1 { + return get_last_error() + } return nil } diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index b1b90b89b..d30511d9c 100644 --- a/core/os/os_openbsd.odin +++ b/core/os/os_openbsd.odin @@ -366,6 +366,7 @@ foreign libc { @(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int --- @(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int --- @(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int --- + @(link_name="fsync") _unix_fsync :: proc(fd: Handle) -> c.int --- @(link_name="dup") _unix_dup :: proc(fd: Handle) -> Handle --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- @@ -430,7 +431,10 @@ close :: proc(fd: Handle) -> Error { } flush :: proc(fd: Handle) -> Error { - // do nothing + result := _unix_fsync(fd) + if result == -1 { + return get_last_error() + } return nil } diff --git a/core/sys/freebsd/syscalls.odin b/core/sys/freebsd/syscalls.odin index d1876a5e2..8590df46e 100644 --- a/core/sys/freebsd/syscalls.odin +++ b/core/sys/freebsd/syscalls.odin @@ -22,6 +22,7 @@ SYS_getpid : uintptr : 20 SYS_recvfrom : uintptr : 29 SYS_accept : uintptr : 30 SYS_fcntl : uintptr : 92 +SYS_fsync : uintptr : 95 SYS_socket : uintptr : 97 SYS_connect : uintptr : 98 SYS_bind : uintptr : 104 @@ -200,6 +201,16 @@ accept_nil :: proc "contextless" (s: Fd) -> (Fd, Errno) { accept :: proc { accept_T, accept_nil } +// Synchronize changes to a file. +// +// The fsync() system call appeared in 4.2BSD. +fsync :: proc "contextless" (fd: Fd) -> Errno { + result, _ := intrinsics.syscall_bsd(SYS_fsync, + cast(uintptr)fd) + + return cast(Errno)result +} + // File control. // // The fcntl() system call appeared in 4.2BSD.