aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-01-18 11:49:42 -0800
committerGitHub <noreply@github.com>2021-01-18 11:49:42 -0800
commit0353c9601a7a72cf453738818d0fba4e980512ba (patch)
tree833e668796e537ddb51bbd59df2612068ffbe9e3 /lib/std
parentc3dadfa95b01d140460eb3d3d47d13859302f298 (diff)
parent6418f9ae91e2444da0743ea0fb0c81fc07ea86a9 (diff)
downloadzig-0353c9601a7a72cf453738818d0fba4e980512ba.tar.gz
zig-0353c9601a7a72cf453738818d0fba4e980512ba.zip
Merge pull request #7814 from LemonBoy/fix-7760
std: Fixed pipe2 fallback
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/c.zig1
-rw-r--r--lib/std/c/dragonfly.zig1
-rw-r--r--lib/std/c/freebsd.zig1
-rw-r--r--lib/std/c/linux.zig1
-rw-r--r--lib/std/c/netbsd.zig1
-rw-r--r--lib/std/c/openbsd.zig1
-rw-r--r--lib/std/os.zig61
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{