authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-01-18 13:24:06+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-01-18 14:52:35+01:00
log9d18df142c2b1583fcf0d59982b571699a63223e
treee728f42a2f7b21482267847141638b62fc3e1833
parent81183365852e7f871500a3f71810ae3b468f0027

std: Fixed pipe2 fallback

Use both F_SETFD and F_SETFL depending on what flag we're setting. Closes #7760

1 files changed, 42 insertions(+), 19 deletions(-)

lib/std/os.zig+42-19
...@@ -3755,31 +3755,54 @@ pub fn pipe() PipeError![2]fd_t {...@@ -3755,31 +3755,54 @@ pub fn pipe() PipeError![2]fd_t {
3755}3755}
37563756
3757pub fn pipe2(flags: u32) PipeError![2]fd_t {3757pub fn pipe2(flags: u32) PipeError![2]fd_t {
3758 if (comptime std.Target.current.isDarwin()) {3758 if (@hasDecl(system, "pipe2")) {
3759 var fds: [2]fd_t = try pipe();3759 var fds: [2]fd_t = undefined;
3760 if (flags == 0) return fds;3760 switch (errno(system.pipe2(&fds, flags))) {
3761 errdefer {3761 0 => return fds,
3762 close(fds[0]);
3763 close(fds[1]);
3764 }
3765 for (fds) |fd| switch (errno(system.fcntl(fd, F_SETFL, flags))) {
3766 0 => {},
3767 EINVAL => unreachable, // Invalid flags3762 EINVAL => unreachable, // Invalid flags
3768 EBADF => unreachable, // Always a race condition3763 EFAULT => unreachable, // Invalid fds pointer
3764 ENFILE => return error.SystemFdQuotaExceeded,
3765 EMFILE => return error.ProcessFdQuotaExceeded,
3769 else => |err| return unexpectedErrno(err),3766 else => |err| return unexpectedErrno(err),
3770 };3767 }
3768 }
3769
3770 var fds: [2]fd_t = try pipe();
3771 errdefer {
3772 close(fds[0]);
3773 close(fds[1]);
3774 }
3775
3776 if (flags == 0)
3771 return fds;3777 return fds;
3778
3779 // O_CLOEXEC is special, it's a file descriptor flag and must be set using
3780 // F_SETFD.
3781 if (flags & O_CLOEXEC != 0) {
3782 for (fds) |fd| {
3783 switch (errno(system.fcntl(fd, F_SETFD, FD_CLOEXEC))) {
3784 0 => {},
3785 EINVAL => unreachable, // Invalid flags
3786 EBADF => unreachable, // Always a race condition
3787 else => |err| return unexpectedErrno(err),
3788 }
3789 }
3772 }3790 }
37733791
3774 var fds: [2]fd_t = undefined;3792 const new_flags = flags & ~@as(u32, O_CLOEXEC);
3775 switch (errno(system.pipe2(&fds, flags))) {3793 // Set every other flag affecting the file status using F_SETFL.
3776 0 => return fds,3794 if (new_flags != 0) {
3777 EINVAL => unreachable, // Invalid flags3795 for (fds) |fd| {
3778 EFAULT => unreachable, // Invalid fds pointer3796 switch (errno(system.fcntl(fd, F_SETFL, new_flags))) {
3779 ENFILE => return error.SystemFdQuotaExceeded,3797 0 => {},
3780 EMFILE => return error.ProcessFdQuotaExceeded,3798 EINVAL => unreachable, // Invalid flags
3781 else => |err| return unexpectedErrno(err),3799 EBADF => unreachable, // Always a race condition
3800 else => |err| return unexpectedErrno(err),
3801 }
3802 }
3782 }3803 }
3804
3805 return fds;
3783}3806}
37843807
3785pub const SysCtlError = error{3808pub const SysCtlError = error{