diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-01-18 11:49:42 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-18 11:49:42 -0800 |
| commit | 0353c9601a7a72cf453738818d0fba4e980512ba (patch) | |
| tree | 833e668796e537ddb51bbd59df2612068ffbe9e3 | |
| parent | c3dadfa95b01d140460eb3d3d47d13859302f298 (diff) | |
| parent | 6418f9ae91e2444da0743ea0fb0c81fc07ea86a9 (diff) | |
| download | zig-0353c9601a7a72cf453738818d0fba4e980512ba.tar.gz zig-0353c9601a7a72cf453738818d0fba4e980512ba.zip | |
Merge pull request #7814 from LemonBoy/fix-7760
std: Fixed pipe2 fallback
| -rw-r--r-- | lib/std/c.zig | 1 | ||||
| -rw-r--r-- | lib/std/c/dragonfly.zig | 1 | ||||
| -rw-r--r-- | lib/std/c/freebsd.zig | 1 | ||||
| -rw-r--r-- | lib/std/c/linux.zig | 1 | ||||
| -rw-r--r-- | lib/std/c/netbsd.zig | 1 | ||||
| -rw-r--r-- | lib/std/c/openbsd.zig | 1 | ||||
| -rw-r--r-- | lib/std/os.zig | 61 |
7 files changed, 47 insertions, 20 deletions
diff --git a/lib/std/c.zig b/lib/std/c.zig index 1e86bfbd8c..6b389c23ef 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -108,7 +108,6 @@ pub extern "c" fn fork() c_int; pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int; pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int; pub extern "c" fn pipe(fds: *[2]fd_t) c_int; -pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int; pub extern "c" fn mkdirat(dirfd: fd_t, path: [*:0]const u8, mode: u32) c_int; pub extern "c" fn symlink(existing: [*:0]const u8, new: [*:0]const u8) c_int; diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig index b57aa3c795..4e6650094b 100644 --- a/lib/std/c/dragonfly.zig +++ b/lib/std/c/dragonfly.zig @@ -13,6 +13,7 @@ pub fn _errno() *c_int { pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; +pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int; pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int; diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index a6c84c66fa..795b36dc68 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -14,6 +14,7 @@ pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn pthread_getthreadid_np() c_int; +pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn posix_memalign(memptr: *?*c_void, alignment: usize, size: usize) c_int; pub extern "c" fn malloc_usable_size(?*const c_void) usize; diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index fbfabdd568..d2018f6f79 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -86,6 +86,7 @@ pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_ pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn memfd_create(name: [*:0]const u8, flags: c_uint) c_int; +pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn fallocate(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int; diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig index 46a38706f4..7169095197 100644 --- a/lib/std/c/netbsd.zig +++ b/lib/std/c/netbsd.zig @@ -16,6 +16,7 @@ pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_ pub extern "c" fn _lwp_self() lwpid_t; +pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int; pub extern "c" fn __stat50(path: [*:0]const u8, buf: *Stat) c_int; diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig index 99debf57e7..cac3df867d 100644 --- a/lib/std/c/openbsd.zig +++ b/lib/std/c/openbsd.zig @@ -17,6 +17,7 @@ pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_ pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; pub extern "c" fn getthrid() pid_t; +pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; diff --git a/lib/std/os.zig b/lib/std/os.zig index 4c8c51d5cc..8c3ea7baa8 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -3755,31 +3755,54 @@ pub fn pipe() PipeError![2]fd_t { } pub fn pipe2(flags: u32) PipeError![2]fd_t { - if (comptime std.Target.current.isDarwin()) { - var fds: [2]fd_t = try pipe(); - if (flags == 0) return fds; - errdefer { - close(fds[0]); - close(fds[1]); - } - for (fds) |fd| switch (errno(system.fcntl(fd, F_SETFL, flags))) { - 0 => {}, + if (@hasDecl(system, "pipe2")) { + var fds: [2]fd_t = undefined; + switch (errno(system.pipe2(&fds, flags))) { + 0 => return fds, EINVAL => unreachable, // Invalid flags - EBADF => unreachable, // Always a race condition + EFAULT => unreachable, // Invalid fds pointer + ENFILE => return error.SystemFdQuotaExceeded, + EMFILE => return error.ProcessFdQuotaExceeded, else => |err| return unexpectedErrno(err), - }; + } + } + + var fds: [2]fd_t = try pipe(); + errdefer { + close(fds[0]); + close(fds[1]); + } + + if (flags == 0) return fds; + + // O_CLOEXEC is special, it's a file descriptor flag and must be set using + // F_SETFD. + if (flags & O_CLOEXEC != 0) { + for (fds) |fd| { + switch (errno(system.fcntl(fd, F_SETFD, @as(u32, FD_CLOEXEC)))) { + 0 => {}, + EINVAL => unreachable, // Invalid flags + EBADF => unreachable, // Always a race condition + else => |err| return unexpectedErrno(err), + } + } } - var fds: [2]fd_t = undefined; - switch (errno(system.pipe2(&fds, flags))) { - 0 => return fds, - EINVAL => unreachable, // Invalid flags - EFAULT => unreachable, // Invalid fds pointer - ENFILE => return error.SystemFdQuotaExceeded, - EMFILE => return error.ProcessFdQuotaExceeded, - else => |err| return unexpectedErrno(err), + const new_flags = flags & ~@as(u32, O_CLOEXEC); + // Set every other flag affecting the file status using F_SETFL. + if (new_flags != 0) { + for (fds) |fd| { + switch (errno(system.fcntl(fd, F_SETFL, new_flags))) { + 0 => {}, + EINVAL => unreachable, // Invalid flags + EBADF => unreachable, // Always a race condition + else => |err| return unexpectedErrno(err), + } + } } + + return fds; } pub const SysCtlError = error{ |
