| ... | ... | @@ -3755,31 +3755,54 @@ pub fn pipe() PipeError![2]fd_t { |
| 3755 | 3755 | } |
| 3756 | 3756 | |
| 3757 | 3757 | pub 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, |
| 3767 | 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 | 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 | 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; |
| 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 | } |
| 3782 | 3803 | } |
| 3804 | |
| 3805 | return fds; |
| 3783 | 3806 | } |
| 3784 | 3807 | |
| 3785 | 3808 | pub const SysCtlError = error{ |