Merge pull request #7814 from LemonBoy/fix-7760

std: Fixed pipe2 fallback
This commit is contained in:
Andrew Kelley 2021-01-18 11:49:42 -08:00 committed by GitHub
commit 0353c9601a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 21 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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),
};
return fds;
}
}
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),
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),
}
}
}
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{