| ... | ... | @@ -666,8 +666,19 @@ pub const Dir = struct { |
| 666 | 666 | const path_w = try os.windows.cStrToPrefixedFileW(sub_path); |
| 667 | 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 | 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 | 682 | @as(u32, os.O_RDWR) |
| 672 | 683 | else if (flags.write) |
| 673 | 684 | @as(u32, os.O_WRONLY) |
| ... | ... | @@ -678,18 +689,14 @@ pub const Dir = struct { |
| 678 | 689 | else |
| 679 | 690 | try os.openatC(self.fd, sub_path, os_flags, 0); |
| 680 | 691 | |
| 681 | | var locked = false; |
| 682 | | if (flags.lock) { |
| 692 | // use fcntl file locking if no lock flag was given |
| 693 | if (flags.lock and lock_flag == 0) { |
| 683 | 694 | // TODO: integrate async I/O |
| 684 | 695 | // mem.zeroes is used here because flock's structure can vary across architectures and systems |
| 685 | 696 | var flock = mem.zeroes(os.Flock); |
| 686 | 697 | flock.l_type = if (flags.write) os.F_WRLCK else os.F_RDLCK; |
| 687 | 698 | flock.l_whence = os.SEEK_SET; |
| 688 | | flock.l_start = 0; |
| 689 | | flock.l_len = 0; |
| 690 | | flock.l_pid = 0; |
| 691 | 699 | try os.fcntl(fd, os.F_SETLKW, &flock); |
| 692 | | locked = true; |
| 693 | 700 | } |
| 694 | 701 | |
| 695 | 702 | return File{ |
| ... | ... | @@ -735,8 +742,15 @@ pub const Dir = struct { |
| 735 | 742 | const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); |
| 736 | 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 | 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 | 754 | (if (flags.truncate) @as(u32, os.O_TRUNC) else 0) | |
| 741 | 755 | (if (flags.read) @as(u32, os.O_RDWR) else os.O_WRONLY) | |
| 742 | 756 | (if (flags.exclusive) @as(u32, os.O_EXCL) else 0); |
| ... | ... | @@ -745,15 +759,12 @@ pub const Dir = struct { |
| 745 | 759 | else |
| 746 | 760 | try os.openatC(self.fd, sub_path_c, os_flags, flags.mode); |
| 747 | 761 | |
| 748 | | if (flags.lock) { |
| 762 | if (flags.lock and lock_flag == 0) { |
| 749 | 763 | // TODO: integrate async I/O |
| 750 | 764 | // mem.zeroes is used here because flock's structure can vary across architectures and systems |
| 751 | 765 | var flock = mem.zeroes(os.Flock); |
| 752 | 766 | flock.l_type = os.F_WRLCK; |
| 753 | 767 | flock.l_whence = os.SEEK_SET; |
| 754 | | flock.l_start = 0; |
| 755 | | flock.l_len = 0; |
| 756 | | flock.l_pid = 0; |
| 757 | 768 | try os.fcntl(fd, os.F_SETLKW, &flock); |
| 758 | 769 | } |
| 759 | 770 | |