authorgravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-03-08 20:57:47-06:00
committergravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-03-14 10:12:46-06:00
log9af0590a282e3cf1aa209f4de35402a50effe7a8
tree648fa372cebcbb2b612b9e170a8fdebf28ab2a65
parent3110060351f98ea8de65809379e1bcd9607fb1cb

Add fnctlFlock system call, use it to lock files


5 files changed, 46 insertions(+), 0 deletions(-)

lib/std/fs.zig+14
...@@ -677,6 +677,20 @@ pub const Dir = struct {...@@ -677,6 +677,20 @@ pub const Dir = struct {
677 try std.event.Loop.instance.?.openatZ(self.fd, sub_path, os_flags, 0)677 try std.event.Loop.instance.?.openatZ(self.fd, sub_path, os_flags, 0)
678 else678 else
679 try os.openatC(self.fd, sub_path, os_flags, 0);679 try os.openatC(self.fd, sub_path, os_flags, 0);
680
681 var locked = false;
682 if (flags.lock) {
683 // TODO: integrate async I/O
684 try os.fcntlFlockBlocking(fd, &os.flock{
685 .lock_type = if (flags.write) os.F_WRLCK else os.F_RDLCK,
686 .whence = os.SEEK_SET,
687 .start = 0,
688 .len = 0,
689 .pid = 0,
690 });
691 locked = true;
692 }
693
680 return File{694 return File{
681 .handle = fd,695 .handle = fd,
682 .io_mode = .blocking,696 .io_mode = .blocking,
lib/std/os.zig+8
...@@ -1140,6 +1140,14 @@ pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8)...@@ -1140,6 +1140,14 @@ pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8)
1140 allocator.free(envp_buf);1140 allocator.free(envp_buf);
1141}1141}
11421142
1143/// Attempts to get lock the file, blocking if the file is locked.
1144pub fn fcntlFlockBlocking(fd: fd_t, flock_p: *flock) OpenError!void {
1145 const rc = system.fcntlFlock(fd, F_SETLKW, flock_p);
1146 if (rc < 0) {
1147 std.debug.panic("fcntl error: {}\n", .{rc});
1148 }
1149}
1150
1143/// Get an environment variable.1151/// Get an environment variable.
1144/// See also `getenvZ`.1152/// See also `getenvZ`.
1145pub fn getenv(key: []const u8) ?[]const u8 {1153pub fn getenv(key: []const u8) ?[]const u8 {
lib/std/os/bits/linux/i386.zig+8
...@@ -488,6 +488,14 @@ pub const MMAP2_UNIT = 4096;...@@ -488,6 +488,14 @@ pub const MMAP2_UNIT = 4096;
488pub const VDSO_CGT_SYM = "__vdso_clock_gettime";488pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
489pub const VDSO_CGT_VER = "LINUX_2.6";489pub const VDSO_CGT_VER = "LINUX_2.6";
490490
491pub const flock = extern struct {
492 lock_type: i16,
493 whence: i16,
494 start: off_t,
495 len: off_t,
496 pid: pid_t,
497};
498
491pub const msghdr = extern struct {499pub const msghdr = extern struct {
492 msg_name: ?*sockaddr,500 msg_name: ?*sockaddr,
493 msg_namelen: socklen_t,501 msg_namelen: socklen_t,
lib/std/os/bits/linux/x86_64.zig+12
...@@ -456,6 +456,18 @@ pub const REG_TRAPNO = 20;...@@ -456,6 +456,18 @@ pub const REG_TRAPNO = 20;
456pub const REG_OLDMASK = 21;456pub const REG_OLDMASK = 21;
457pub const REG_CR2 = 22;457pub const REG_CR2 = 22;
458458
459pub const F_RDLCK = 0;
460pub const F_WRLCK = 1;
461pub const F_UNLCK = 2;
462
463pub const flock = extern struct {
464 lock_type: i16,
465 whence: i16,
466 start: off_t,
467 len: off_t,
468 pid: pid_t,
469};
470
459pub const msghdr = extern struct {471pub const msghdr = extern struct {
460 msg_name: ?*sockaddr,472 msg_name: ?*sockaddr,
461 msg_namelen: socklen_t,473 msg_namelen: socklen_t,
lib/std/os/linux.zig+4
...@@ -219,6 +219,10 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -219,6 +219,10 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
219 }219 }
220}220}
221221
222pub fn fcntlFlock(fd: fd_t, cmd: i32, flock_p: *flock) usize {
223 return syscall3(SYS_fcntl, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, cmd)), @ptrToInt(flock_p));
224}
225
222pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize {226pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize {
223 return syscall3(SYS_mprotect, @ptrToInt(address), length, protection);227 return syscall3(SYS_mprotect, @ptrToInt(address), length, protection);
224}228}