mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-06-01 22:05:26 +03:00
eae06cf5cc
This was missed in ff612334fa (https://codeberg.org/ziglang/zig/pulls/31803).
Please don't forget these weak aliases when deleting musl code; doing so can
cause portions of code in musl to fail to link. For example, this particular
case broke freopen().
261 lines
8.1 KiB
Zig
261 lines
8.1 KiB
Zig
const builtin = @import("builtin");
|
|
|
|
const std = @import("std");
|
|
const linux = std.os.linux;
|
|
|
|
const symbol = @import("../c.zig").symbol;
|
|
const errno = @import("../c.zig").errno;
|
|
|
|
comptime {
|
|
if (builtin.target.isMuslLibC()) {
|
|
symbol(&_exit, "_exit");
|
|
|
|
symbol(&accessLinux, "access");
|
|
symbol(&acctLinux, "acct");
|
|
symbol(&chdirLinux, "chdir");
|
|
symbol(&chownLinux, "chown");
|
|
symbol(&close, "close");
|
|
symbol(&posix_close, "posix_close");
|
|
symbol(&fchownatLinux, "fchownat");
|
|
symbol(&lchownLinux, "lchown");
|
|
symbol(&chrootLinux, "chroot");
|
|
symbol(&ctermidLinux, "ctermid");
|
|
symbol(&dupLinux, "dup");
|
|
symbol(&dup2Linux, "dup2");
|
|
symbol(&dup3Linux, "dup3");
|
|
symbol(&dup3Linux, "__dup3");
|
|
|
|
symbol(&getegidLinux, "getegid");
|
|
symbol(&geteuidLinux, "geteuid");
|
|
symbol(&getgidLinux, "getgid");
|
|
symbol(&getgroupsLinux, "getgroups");
|
|
symbol(&getpgidLinux, "getpgid");
|
|
symbol(&getpgrpLinux, "getpgrp");
|
|
symbol(&setpgidLinux, "setpgid");
|
|
symbol(&setpgrpLinux, "setpgrp");
|
|
symbol(&getsidLinux, "getsid");
|
|
symbol(&getpidLinux, "getpid");
|
|
symbol(&getppidLinux, "getppid");
|
|
symbol(&getuidLinux, "getuid");
|
|
|
|
symbol(&rmdirLinux, "rmdir");
|
|
symbol(&linkLinux, "link");
|
|
symbol(&linkatLinux, "linkat");
|
|
symbol(&pipeLinux, "pipe");
|
|
symbol(&renameatLinux, "renameat");
|
|
symbol(&symlinkLinux, "symlink");
|
|
symbol(&symlinkatLinux, "symlinkat");
|
|
symbol(&syncLinux, "sync");
|
|
symbol(&unlinkLinux, "unlink");
|
|
symbol(&unlinkatLinux, "unlinkat");
|
|
|
|
symbol(&execveLinux, "execve");
|
|
}
|
|
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
|
|
symbol(&swab, "swab");
|
|
}
|
|
if (builtin.target.isWasiLibC()) {
|
|
symbol(&closeWasi, "close");
|
|
}
|
|
}
|
|
|
|
fn _exit(exit_code: c_int) callconv(.c) noreturn {
|
|
std.c._Exit(exit_code);
|
|
}
|
|
|
|
fn accessLinux(path: [*:0]const c_char, amode: c_int) callconv(.c) c_int {
|
|
return errno(linux.access(@ptrCast(path), @bitCast(amode)));
|
|
}
|
|
|
|
fn acctLinux(path: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.acct(@ptrCast(path)));
|
|
}
|
|
|
|
fn chdirLinux(path: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.chdir(@ptrCast(path)));
|
|
}
|
|
|
|
fn chownLinux(path: [*:0]const c_char, uid: linux.uid_t, gid: linux.gid_t) callconv(.c) c_int {
|
|
return errno(linux.chown(@ptrCast(path), uid, gid));
|
|
}
|
|
|
|
fn fchownatLinux(fd: c_int, path: [*:0]const c_char, uid: linux.uid_t, gid: linux.gid_t, flags: c_int) callconv(.c) c_int {
|
|
return errno(linux.fchownat(fd, @ptrCast(path), uid, gid, @bitCast(flags)));
|
|
}
|
|
|
|
fn lchownLinux(path: [*:0]const c_char, uid: linux.uid_t, gid: linux.gid_t) callconv(.c) c_int {
|
|
return errno(linux.lchown(@ptrCast(path), uid, gid));
|
|
}
|
|
|
|
fn chrootLinux(path: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.chroot(@ptrCast(path)));
|
|
}
|
|
|
|
fn ctermidLinux(maybe_path: ?[*]c_char) callconv(.c) [*:0]c_char {
|
|
const default_tty = "/dev/tty";
|
|
|
|
return if (maybe_path) |path| blk: {
|
|
path[0..(default_tty.len + 1)].* = @bitCast(default_tty.*);
|
|
break :blk path[0..default_tty.len :0].ptr;
|
|
} else @ptrCast(@constCast(default_tty));
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
fn geteuidLinux() callconv(.c) linux.uid_t {
|
|
return linux.geteuid();
|
|
}
|
|
|
|
fn getgidLinux() callconv(.c) linux.gid_t {
|
|
return linux.getgid();
|
|
}
|
|
|
|
fn getgroupsLinux(size: c_int, list: ?[*]linux.gid_t) callconv(.c) c_int {
|
|
return errno(linux.getgroups(@intCast(size), list));
|
|
}
|
|
|
|
fn getpgidLinux(pid: linux.pid_t) callconv(.c) linux.pid_t {
|
|
return errno(linux.getpgid(pid));
|
|
}
|
|
|
|
fn getpgrpLinux() callconv(.c) linux.pid_t {
|
|
return @intCast(linux.getpgid(0)); // @intCast as it cannot fail
|
|
}
|
|
|
|
fn setpgidLinux(pid: linux.pid_t, pgid: linux.pid_t) callconv(.c) c_int {
|
|
return errno(linux.setpgid(pid, pgid));
|
|
}
|
|
|
|
fn setpgrpLinux() callconv(.c) linux.pid_t {
|
|
return @intCast(linux.setpgid(0, 0)); // @intCast as it cannot fail
|
|
}
|
|
|
|
fn getpidLinux() callconv(.c) linux.pid_t {
|
|
return linux.getpid();
|
|
}
|
|
|
|
fn getppidLinux() callconv(.c) linux.pid_t {
|
|
return linux.getppid();
|
|
}
|
|
|
|
fn getsidLinux(pid: linux.pid_t) callconv(.c) linux.pid_t {
|
|
return errno(linux.getsid(pid));
|
|
}
|
|
|
|
fn getuidLinux() callconv(.c) linux.uid_t {
|
|
return linux.getuid();
|
|
}
|
|
|
|
fn linkLinux(old: [*:0]const c_char, new: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.link(@ptrCast(old), @ptrCast(new)));
|
|
}
|
|
|
|
fn linkatLinux(old_fd: c_int, old: [*:0]const c_char, new_fd: c_int, new: [*:0]const c_char, flags: c_int) callconv(.c) c_int {
|
|
return errno(linux.linkat(old_fd, @ptrCast(old), new_fd, @ptrCast(new), @bitCast(flags)));
|
|
}
|
|
|
|
fn pipeLinux(fd: *[2]c_int) callconv(.c) c_int {
|
|
return errno(linux.pipe(@ptrCast(fd)));
|
|
}
|
|
|
|
fn renameatLinux(old_fd: c_int, old: [*:0]const c_char, new_fd: c_int, new: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.renameat(old_fd, @ptrCast(old), new_fd, @ptrCast(new)));
|
|
}
|
|
|
|
fn rmdirLinux(path: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.rmdir(@ptrCast(path)));
|
|
}
|
|
|
|
fn symlinkLinux(existing: [*:0]const c_char, new: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.symlink(@ptrCast(existing), @ptrCast(new)));
|
|
}
|
|
|
|
fn symlinkatLinux(existing: [*:0]const c_char, fd: c_int, new: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.symlinkat(@ptrCast(existing), fd, @ptrCast(new)));
|
|
}
|
|
|
|
fn syncLinux() callconv(.c) void {
|
|
linux.sync();
|
|
}
|
|
|
|
fn unlinkLinux(path: [*:0]const c_char) callconv(.c) c_int {
|
|
return errno(linux.unlink(@ptrCast(path)));
|
|
}
|
|
|
|
fn unlinkatLinux(fd: c_int, path: [*:0]const c_char, flags: c_int) callconv(.c) c_int {
|
|
return errno(linux.unlinkat(fd, @ptrCast(path), @bitCast(flags)));
|
|
}
|
|
|
|
fn execveLinux(path: [*:0]const c_char, argv: [*:null]const ?[*:0]c_char, envp: [*:null]const ?[*:0]c_char) callconv(.c) c_int {
|
|
return errno(linux.execve(@ptrCast(path), @ptrCast(argv), @ptrCast(envp)));
|
|
}
|
|
|
|
fn swab(noalias src_ptr: *const anyopaque, noalias dest_ptr: *anyopaque, n: isize) callconv(.c) void {
|
|
var src: [*]const u8 = @ptrCast(src_ptr);
|
|
var dest: [*]u8 = @ptrCast(dest_ptr);
|
|
var i = n;
|
|
|
|
while (i > 1) : (i -= 2) {
|
|
dest[0] = src[1];
|
|
dest[1] = src[0];
|
|
dest += 2;
|
|
src += 2;
|
|
}
|
|
}
|
|
|
|
fn close(fd: std.c.fd_t) callconv(.c) c_int {
|
|
const signed: isize = @bitCast(linux.close(fd));
|
|
if (signed < 0) {
|
|
@branchHint(.unlikely);
|
|
if (-signed == @intFromEnum(linux.E.INTR)) return 0;
|
|
std.c._errno().* = @intCast(-signed);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
fn posix_close(fd: std.c.fd_t, _: c_int) callconv(.c) c_int {
|
|
return close(fd);
|
|
}
|
|
|
|
fn closeWasi(fd: std.c.fd_t) callconv(.c) c_int {
|
|
switch (std.os.wasi.fd_close(fd)) {
|
|
.SUCCESS => return 0,
|
|
else => |e| {
|
|
std.c._errno().* = @intFromEnum(e);
|
|
return -1;
|
|
},
|
|
}
|
|
}
|