From a636b59cb58caf86dacd9814116bb459075b4cae Mon Sep 17 00:00:00 2001 From: LeRoyce Pearson Date: Tue, 10 Mar 2020 18:54:05 -0600 Subject: [PATCH] Add `lock` option to CreateFlags --- lib/std/fs.zig | 20 +++++++++++++++++++- lib/std/fs/file.zig | 6 ++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 44dbcf45fa..a57f9e5c49 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -744,6 +744,19 @@ pub const Dir = struct { try std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, os_flags, flags.mode) else try os.openatC(self.fd, sub_path_c, os_flags, flags.mode); + + if (flags.lock) { + // TODO: integrate async I/O + // mem.zeroes is used here because flock's structure can vary across architectures and systems + var flock = mem.zeroes(os.Flock); + flock.l_type = os.F_WRLCK; + flock.l_whence = os.SEEK_SET; + flock.l_start = 0; + flock.l_len = 0; + flock.l_pid = 0; + try os.fcntlFlock(fd, .SetLockBlocking, &flock); + } + return File{ .handle = fd, .io_mode = .blocking }; } @@ -759,7 +772,12 @@ pub const Dir = struct { @as(u32, w.FILE_OVERWRITE_IF) else @as(u32, w.FILE_OPEN_IF); - return self.openFileWindows(sub_path_w, access_mask, null, creation); + + const share_access = if (flags.lock) + @as(os.windows.ULONG, w.FILE_SHARE_DELETE) + else + null; + return self.openFileWindows(sub_path_w, access_mask, share_access, creation); } /// Deprecated; call `openFile` directly. diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index e892fc3b8f..ee12432496 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -69,6 +69,12 @@ pub const File = struct { /// `error.FileAlreadyExists` to be returned. exclusive: bool = false, + /// Prevent other files from accessing this file while this process has it is open. + /// + /// Note that the lock is only advisory on Linux. This means that a process that does not + /// respect the locking API can still read and write to the file, despite the lock. + lock: bool = false, + /// For POSIX systems this is the file system mode the file will /// be created with. mode: Mode = default_mode,