authorgravatar for jens.goldberg@gmail.comAransentin <jens.goldberg@gmail.com> 2020-09-02 22:16:40+00:00
committergravatar for jens.goldberg@gmail.comAransentin <jens.goldberg@gmail.com> 2020-09-02 22:16:40+00:00
log25f666330480a2391d1c06e1beab8d517a096e99
tree042cc969a5f6ffc9bdcc822f0b634414b7448727
parent12ce6eb8f65e6de5920c713cf2767e4b8ba0f1d3

Add the sync functions


3 files changed, 86 insertions(+), 0 deletions(-)

lib/std/os.zig+68
......@@ -5328,3 +5328,71 @@ pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {
53285328 else => |err| return std.os.unexpectedErrno(err),
53295329 }
53305330}
5331
5332pub const SyncError = error{
5333 InputOutput,
5334 NoSpaceLeft,
5335 DiskQuota,
5336 AccessDenied,
5337} || UnexpectedError;
5338
5339/// Write all pending file contents and metadata modifications to all filesystems.
5340pub fn sync() void {
5341 system.sync();
5342}
5343
5344/// Write all pending file contents and metadata modifications to the filesystem which contains the specified file.
5345pub fn syncfs(fd: fd_t) SyncError!void {
5346 const rc = system.syncfs(fd);
5347 switch (errno(rc)) {
5348 0 => return,
5349 EBADF, EINVAL, EROFS => unreachable,
5350 EIO => return error.InputOutput,
5351 ENOSPC => return error.NoSpaceLeft,
5352 EDQUOT => return error.DiskQuota,
5353 else => |err| return std.os.unexpectedErrno(err),
5354 }
5355}
5356
5357/// Write all pending file contents and metadata modifications for the specified file descriptor to the underlying filesystem.
5358pub fn fsync(fd: fd_t) SyncError!void {
5359 if (std.Target.current.os.tag == .windows) {
5360 if (windows.kernel32.FlushFileBuffers(fd) != 0)
5361 return;
5362 switch (windows.kernel32.GetLastError()) {
5363 .SUCCESS => return,
5364 .INVALID_HANDLE => unreachable,
5365 .ACCESS_DENIED => return error.AccessDenied, // a sync was performed but the system couldn't update the access time
5366 .UNEXP_NET_ERR => return error.InputOutput,
5367 else => return error.InputOutput,
5368 }
5369 }
5370 const rc = system.fsync(fd);
5371 switch (errno(rc)) {
5372 0 => return,
5373 EBADF, EINVAL, EROFS => unreachable,
5374 EIO => return error.InputOutput,
5375 ENOSPC => return error.NoSpaceLeft,
5376 EDQUOT => return error.DiskQuota,
5377 else => |err| return std.os.unexpectedErrno(err),
5378 }
5379}
5380
5381/// Write all pending file contents for the specified file descriptor to the underlying filesystem, but not necessarily the metadata.
5382pub fn fdatasync(fd: fd_t) SyncError!void {
5383 if (std.Target.current.os.tag == .windows) {
5384 return fsync(fd) catch |err| switch (err) {
5385 SyncError.AccessDenied => return, // fdatasync doesn't promise that the access time was synced
5386 else => return err,
5387 };
5388 }
5389 const rc = system.fdatasync(fd);
5390 switch (errno(rc)) {
5391 0 => return,
5392 EBADF, EINVAL, EROFS => unreachable,
5393 EIO => return error.InputOutput,
5394 ENOSPC => return error.NoSpaceLeft,
5395 EDQUOT => return error.DiskQuota,
5396 else => |err| return std.os.unexpectedErrno(err),
5397 }
5398}
lib/std/os/linux.zig+16
......@@ -1226,6 +1226,22 @@ pub fn bpf(cmd: BPF.Cmd, attr: *BPF.Attr, size: u32) usize {
12261226 return syscall3(.bpf, @enumToInt(cmd), @ptrToInt(attr), size);
12271227}
12281228
1229pub fn sync() void {
1230 _ = syscall0(.sync);
1231}
1232
1233pub fn syncfs(fd: fd_t) usize {
1234 return syscall1(.syncfs, @bitCast(usize, @as(isize, fd)));
1235}
1236
1237pub fn fsync(fd: fd_t) usize {
1238 return syscall1(.fsync, @bitCast(usize, @as(isize, fd)));
1239}
1240
1241pub fn fdatasync(fd: fd_t) usize {
1242 return syscall1(.fdatasync, @bitCast(usize, @as(isize, fd)));
1243}
1244
12291245test "" {
12301246 if (builtin.os.tag == .linux) {
12311247 _ = @import("linux/test.zig");
lib/std/os/windows/kernel32.zig+2
......@@ -287,3 +287,5 @@ pub extern "kernel32" fn K32GetWsChangesEx(hProcess: HANDLE, lpWatchInfoEx: PPSA
287287pub extern "kernel32" fn K32InitializeProcessForWsWatch(hProcess: HANDLE) callconv(.Stdcall) BOOL;
288288pub extern "kernel32" fn K32QueryWorkingSet(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(.Stdcall) BOOL;
289289pub extern "kernel32" fn K32QueryWorkingSetEx(hProcess: HANDLE, pv: PVOID, cb: DWORD) callconv(.Stdcall) BOOL;
290
291pub extern "kernel32" fn FlushFileBuffers(hFile: HANDLE) callconv(.Stdcall) BOOL;