aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os.zig
diff options
context:
space:
mode:
authorLeRoyce Pearson <leroycepearson@geemili.xyz>2020-04-02 22:57:02 -0600
committerLeRoyce Pearson <leroycepearson@geemili.xyz>2020-04-02 22:57:02 -0600
commitea6525797d0db83a8560179b317837cb58634049 (patch)
tree48a190000f83ba3303a9a3cae797430303c883b9 /lib/std/os.zig
parente7cf3f92a98cd2bd94d9d94fb361819b6ab89e8d (diff)
downloadzig-ea6525797d0db83a8560179b317837cb58634049.tar.gz
zig-ea6525797d0db83a8560179b317837cb58634049.zip
Use `flock` instead of `fcntl` to lock files
`flock` locks based on the file handle, instead of the process id. This brings the file locking on unix based systems closer to file locking on Windows.
Diffstat (limited to 'lib/std/os.zig')
-rw-r--r--lib/std/os.zig32
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 197857e61f..aa302490d0 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -819,36 +819,28 @@ pub const OpenError = error{
SystemFdQuotaExceeded,
NoDevice,
FileNotFound,
-
/// The path exceeded `MAX_PATH_BYTES` bytes.
NameTooLong,
-
/// Insufficient kernel memory was available, or
/// the named file is a FIFO and per-user hard limit on
/// memory allocation for pipes has been reached.
SystemResources,
-
/// The file is too large to be opened. This error is unreachable
/// for 64-bit targets, as well as when opening directories.
FileTooBig,
-
/// The path refers to directory but the `O_DIRECTORY` flag was not provided.
IsDir,
-
/// A new path cannot be created because the device has no room for the new file.
/// This error is only reachable when the `O_CREAT` flag is provided.
NoSpaceLeft,
-
/// A component used as a directory in the path was not, in fact, a directory, or
/// `O_DIRECTORY` was specified and the path was not a directory.
NotDir,
-
/// The path already exists and the `O_CREAT` and `O_EXCL` flags were provided.
PathAlreadyExists,
DeviceBusy,
-
/// The underlying filesystem does not support file locks
- FileLocksNotSupported
+ FileLocksNotSupported,
} || UnexpectedError;
/// Open and possibly create a file. Keeps trying if it gets interrupted.
@@ -3222,6 +3214,28 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
}
}
+pub const FlockError = error{
+ WouldBlock,
+
+ /// The kernel ran out of memory for allocating file locks
+ SystemResources,
+} || UnexpectedError;
+
+pub fn flock(fd: fd_t, operation: i32) FlockError!usize {
+ while (true) {
+ const rc = system.flock(fd, operation);
+ switch (errno(rc)) {
+ 0 => return @intCast(usize, rc),
+ EBADF => unreachable,
+ EINTR => continue,
+ EINVAL => unreachable, // invalid parameters
+ ENOLCK => return error.SystemResources,
+ EWOULDBLOCK => return error.WouldBlock, // TODO: integrate with async instead of just returning an error
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+}
+
pub const RealPathError = error{
FileNotFound,
AccessDenied,