| ... | @@ -3755,31 +3755,54 @@ pub fn pipe() PipeError![2]fd_t { | ... | @@ -3755,31 +3755,54 @@ pub fn pipe() PipeError![2]fd_t { |
| 3755 | } | 3755 | } |
| 3756 | | 3756 | |
| 3757 | pub fn pipe2(flags: u32) PipeError![2]fd_t { | 3757 | pub 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 flags | 3762 | 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, |
| 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 | } |
| 3773 | | 3791 | |
| 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 flags | 3795 | for (fds) |fd| { |
| 3778 | EFAULT => unreachable, // Invalid fds pointer | 3796 | 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 | } |
| 3784 | | 3807 | |
| 3785 | pub const SysCtlError = error{ | 3808 | pub const SysCtlError = error{ |