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 {
37553755}
37563756
37573757pub fn pipe2(flags: u32) PipeError![2]fd_t {
3758 if (comptime std.Target.current.isDarwin()) {
3759 var fds: [2]fd_t = try pipe();
3760 if (flags == 0) return fds;
3761 errdefer {
3762 close(fds[0]);
3763 close(fds[1]);
3764 }
3765 for (fds) |fd| switch (errno(system.fcntl(fd, F_SETFL, flags))) {
3766 0 => {},
3758 if (@hasDecl(system, "pipe2")) {
3759 var fds: [2]fd_t = undefined;
3760 switch (errno(system.pipe2(&fds, flags))) {
3761 0 => return fds,
37673762 EINVAL => unreachable, // Invalid flags
3768 EBADF => unreachable, // Always a race condition
3763 EFAULT => unreachable, // Invalid fds pointer
3764 ENFILE => return error.SystemFdQuotaExceeded,
3765 EMFILE => return error.ProcessFdQuotaExceeded,
37693766 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)
37713777 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 }
37723790 }
37733791
3774 var fds: [2]fd_t = undefined;
3775 switch (errno(system.pipe2(&fds, flags))) {
3776 0 => return fds,
3777 EINVAL => unreachable, // Invalid flags
3778 EFAULT => unreachable, // Invalid fds pointer
3779 ENFILE => return error.SystemFdQuotaExceeded,
3780 EMFILE => return error.ProcessFdQuotaExceeded,
3781 else => |err| return unexpectedErrno(err),
3792 const new_flags = flags & ~@as(u32, O_CLOEXEC);
3793 // Set every other flag affecting the file status using F_SETFL.
3794 if (new_flags != 0) {
3795 for (fds) |fd| {
3796 switch (errno(system.fcntl(fd, F_SETFL, new_flags))) {
3797 0 => {},
3798 EINVAL => unreachable, // Invalid flags
3799 EBADF => unreachable, // Always a race condition
3800 else => |err| return unexpectedErrno(err),
3801 }
3802 }
37823803 }
3804
3805 return fds;
37833806}
37843807
37853808pub const SysCtlError = error{