diff --git a/lib/c/unistd.zig b/lib/c/unistd.zig index f802fdb92e..46229042ed 100644 --- a/lib/c/unistd.zig +++ b/lib/c/unistd.zig @@ -21,6 +21,8 @@ comptime { symbol(&chrootLinux, "chroot"); symbol(&ctermidLinux, "ctermid"); symbol(&dupLinux, "dup"); + symbol(&dup2Linux, "dup2"); + symbol(&dup3Linux, "dup3"); symbol(&getegidLinux, "getegid"); symbol(&geteuidLinux, "geteuid"); @@ -101,6 +103,31 @@ fn dupLinux(fd: c_int) callconv(.c) c_int { return errno(linux.dup(fd)); } +fn dup2Linux(old: c_int, new: c_int) callconv(.c) c_int { + const busy: usize = @bitCast(-@as(isize, @intFromEnum(linux.E.BUSY))); + var res = busy; + while (res == busy) res = linux.dup2(old, new); + return errno(res); +} + +fn dup3Linux(old: c_int, new: c_int, flags: c_int) callconv(.c) c_int { + const busy: usize = @bitCast(-@as(isize, @intFromEnum(linux.E.BUSY))); + var res = busy; + + if (@hasField(linux.SYS, "dup3")) { + while (res == busy) res = linux.dup3(old, new, @intCast(flags)); + } else if (@hasField(linux.SYS, "dup2")) { + const cloexec: c_int = @bitCast(linux.O{ .CLOEXEC = true }); + const inval: usize = @bitCast(-@as(isize, @intFromEnum(linux.E.INVAL))); + if (old == new or (flags & ~cloexec != 0)) return errno(inval); + while (res == busy) res = linux.dup2(old, new); + _ = if (res >= 0 and (flags & cloexec == cloexec)) linux.fcntl(new, linux.F.SETFD, linux.FD_CLOEXEC); + } else { + return errno(@bitCast(-@as(isize, @intFromEnum(linux.E.NOSYS)))); + } + return errno(res); +} + fn getegidLinux() callconv(.c) linux.gid_t { return linux.getegid(); } diff --git a/lib/libc/musl/src/unistd/dup2.c b/lib/libc/musl/src/unistd/dup2.c deleted file mode 100644 index 8f43c6ddfe..0000000000 --- a/lib/libc/musl/src/unistd/dup2.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include "syscall.h" - -int dup2(int old, int new) -{ - int r; -#ifdef SYS_dup2 - while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); -#else - if (old==new) { - r = __syscall(SYS_fcntl, old, F_GETFD); - if (r >= 0) return old; - } else { - while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY); - } -#endif - return __syscall_ret(r); -} diff --git a/lib/libc/musl/src/unistd/dup3.c b/lib/libc/musl/src/unistd/dup3.c deleted file mode 100644 index 40798bdeed..0000000000 --- a/lib/libc/musl/src/unistd/dup3.c +++ /dev/null @@ -1,26 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include "syscall.h" - -int __dup3(int old, int new, int flags) -{ - int r; -#ifdef SYS_dup2 - if (old==new) return __syscall_ret(-EINVAL); - if (flags) { - while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY); - if (r!=-ENOSYS) return __syscall_ret(r); - if (flags & ~O_CLOEXEC) return __syscall_ret(-EINVAL); - } - while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); - if (r >= 0 && (flags & O_CLOEXEC)) - __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC); -#else - while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY); -#endif - return __syscall_ret(r); -} - -weak_alias(__dup3, dup3); diff --git a/src/libs/musl.zig b/src/libs/musl.zig index 2a860aa0da..f53b406568 100644 --- a/src/libs/musl.zig +++ b/src/libs/musl.zig @@ -1758,8 +1758,6 @@ const src_files = [_][]const u8{ "musl/src/time/wcsftime.c", "musl/src/time/__year_to_secs.c", "musl/src/unistd/alarm.c", - "musl/src/unistd/dup2.c", - "musl/src/unistd/dup3.c", "musl/src/unistd/faccessat.c", "musl/src/unistd/fchdir.c", "musl/src/unistd/fchown.c",