authorgravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-03-23 20:59:09-06:00
committergravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-03-23 20:59:09-06:00
log5b278fb60615751bef5e521a613e8798d783dd26
treeae5c48297e431e11904154847bb094e4ad038574
parent613956cc47c2513cdd27d57e5eb2fa36a368c21b

Use locking open flags if they are defined


1 files changed, 23 insertions(+), 12 deletions(-)

lib/std/fs.zig+23-12
...@@ -666,8 +666,19 @@ pub const Dir = struct {...@@ -666,8 +666,19 @@ pub const Dir = struct {
666 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);666 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
667 return self.openFileW(&path_w, flags);667 return self.openFileW(&path_w, flags);
668 }668 }
669
670 // Use the O_ locking flags if the os supports them
671 const lock_flag: u32 = lock_flag: {
672 if (!flags.lock) break :lock_flag 0;
673 if (flags.write) {
674 break :lock_flag if (@hasDecl(os, "O_EXLOCK")) os.O_EXLOCK else 0;
675 } else {
676 break :lock_flag if (@hasDecl(os, "O_SHLOCK")) os.O_SHLOCK else 0;
677 }
678 };
679
669 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;680 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
670 const os_flags = O_LARGEFILE | os.O_CLOEXEC | if (flags.write and flags.read)681 const os_flags = lock_flag | O_LARGEFILE | os.O_CLOEXEC | if (flags.write and flags.read)
671 @as(u32, os.O_RDWR)682 @as(u32, os.O_RDWR)
672 else if (flags.write)683 else if (flags.write)
673 @as(u32, os.O_WRONLY)684 @as(u32, os.O_WRONLY)
...@@ -678,18 +689,14 @@ pub const Dir = struct {...@@ -678,18 +689,14 @@ pub const Dir = struct {
678 else689 else
679 try os.openatC(self.fd, sub_path, os_flags, 0);690 try os.openatC(self.fd, sub_path, os_flags, 0);
680691
681 var locked = false;692 // use fcntl file locking if no lock flag was given
682 if (flags.lock) {693 if (flags.lock and lock_flag == 0) {
683 // TODO: integrate async I/O694 // TODO: integrate async I/O
684 // mem.zeroes is used here because flock's structure can vary across architectures and systems695 // mem.zeroes is used here because flock's structure can vary across architectures and systems
685 var flock = mem.zeroes(os.Flock);696 var flock = mem.zeroes(os.Flock);
686 flock.l_type = if (flags.write) os.F_WRLCK else os.F_RDLCK;697 flock.l_type = if (flags.write) os.F_WRLCK else os.F_RDLCK;
687 flock.l_whence = os.SEEK_SET;698 flock.l_whence = os.SEEK_SET;
688 flock.l_start = 0;
689 flock.l_len = 0;
690 flock.l_pid = 0;
691 try os.fcntl(fd, os.F_SETLKW, &flock);699 try os.fcntl(fd, os.F_SETLKW, &flock);
692 locked = true;
693 }700 }
694701
695 return File{702 return File{
...@@ -735,8 +742,15 @@ pub const Dir = struct {...@@ -735,8 +742,15 @@ pub const Dir = struct {
735 const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);742 const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
736 return self.createFileW(&path_w, flags);743 return self.createFileW(&path_w, flags);
737 }744 }
745
746 // Use the O_ locking flags if the os supports them
747 const lock_flag: u32 = lock_flag: {
748 if (!flags.lock) break :lock_flag 0;
749 break :lock_flag if (@hasDecl(os, "O_EXLOCK")) os.O_EXLOCK else 0;
750 };
751
738 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;752 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
739 const os_flags = O_LARGEFILE | os.O_CREAT | os.O_CLOEXEC |753 const os_flags = lock_flag | O_LARGEFILE | os.O_CREAT | os.O_CLOEXEC |
740 (if (flags.truncate) @as(u32, os.O_TRUNC) else 0) |754 (if (flags.truncate) @as(u32, os.O_TRUNC) else 0) |
741 (if (flags.read) @as(u32, os.O_RDWR) else os.O_WRONLY) |755 (if (flags.read) @as(u32, os.O_RDWR) else os.O_WRONLY) |
742 (if (flags.exclusive) @as(u32, os.O_EXCL) else 0);756 (if (flags.exclusive) @as(u32, os.O_EXCL) else 0);
...@@ -745,15 +759,12 @@ pub const Dir = struct {...@@ -745,15 +759,12 @@ pub const Dir = struct {
745 else759 else
746 try os.openatC(self.fd, sub_path_c, os_flags, flags.mode);760 try os.openatC(self.fd, sub_path_c, os_flags, flags.mode);
747761
748 if (flags.lock) {762 if (flags.lock and lock_flag == 0) {
749 // TODO: integrate async I/O763 // TODO: integrate async I/O
750 // mem.zeroes is used here because flock's structure can vary across architectures and systems764 // mem.zeroes is used here because flock's structure can vary across architectures and systems
751 var flock = mem.zeroes(os.Flock);765 var flock = mem.zeroes(os.Flock);
752 flock.l_type = os.F_WRLCK;766 flock.l_type = os.F_WRLCK;
753 flock.l_whence = os.SEEK_SET;767 flock.l_whence = os.SEEK_SET;
754 flock.l_start = 0;
755 flock.l_len = 0;
756 flock.l_pid = 0;
757 try os.fcntl(fd, os.F_SETLKW, &flock);768 try os.fcntl(fd, os.F_SETLKW, &flock);
758 }769 }
759770