authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-21 00:28:40+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-21 00:28:40+01:00
log7cbe05cbd4d89fe88f17e4c82888823864c6cc8d
treeb1ada46ebcaa52de55bcbe00f68a5a6f8c42aa32
parente6ac1b77f0b958f8cefc6e357620f9fdef2c0eed
parent8042096bca247dd33e35154e0ee031ada10443d5

Merge pull request 'std.os.linux: add some missing syscalls' (#30899) from brickmonster/zig:syscalls into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30899 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

1 files changed, 153 insertions(+), 3 deletions(-)

lib/std/os/linux.zig+153-3
...@@ -632,6 +632,20 @@ pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:...@@ -632,6 +632,20 @@ pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:
632 return syscall3(.execve, @intFromPtr(path), @intFromPtr(argv), @intFromPtr(envp));632 return syscall3(.execve, @intFromPtr(path), @intFromPtr(argv), @intFromPtr(envp));
633}633}
634634
635pub const EXECVEAT = packed struct(u32) {
636 _1: u8 = 0, // 0x00000001
637 /// Do not follow symbolic links.
638 SYMLINK_NOFOLLOW: bool, // 0x00000100
639 _200: u3 = 0, // 0x00000200
640 /// Allow empty relative pathname.
641 EMPTY_PATH: bool, // 0x00001000
642 _: u19 = 0,
643};
644
645pub fn execveat(dirfd: fd_t, path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8, flags: EXECVEAT) usize {
646 return syscall5(.execveat, fd_to_usize(dirfd), @intFromPtr(path), @intFromPtr(argv), @intFromPtr(envp), @as(u32, @bitCast(flags)));
647}
648
635pub fn fork() usize {649pub fn fork() usize {
636 if (comptime native_arch.isSPARC()) {650 if (comptime native_arch.isSPARC()) {
637 return syscall_fork();651 return syscall_fork();
...@@ -982,6 +996,118 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {...@@ -982,6 +996,118 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {
982 return syscall2(.umount2, @intFromPtr(special), flags);996 return syscall2(.umount2, @intFromPtr(special), flags);
983}997}
984998
999pub const MOVE_MOUNT = packed struct(u32) {
1000 /// Follow symlinks on from path.
1001 F_SYMLINKS: bool, // 0x00000001
1002 /// Follow automounts on from path.
1003 F_AUTOMOUNTS: bool, // 0x00000002
1004 /// Empty from path permitted.
1005 F_EMPTY_PATH: bool, // 0x00000004
1006 _8: bool = false, // 0x00000008
1007 /// Follow symlinks on to path.
1008 T_SYMLINKS: bool, // 0x00000010
1009 /// Follow automounts on to path.
1010 T_AUTOMOUNTS: bool, // 0x00000020
1011 /// Empty to path permitted.
1012 T_EMPTY_PATH: bool, // 0x00000040
1013 _80: bool = false, // 0x00000080
1014 /// Set sharing group instead.
1015 SET_GROUP: bool, // 0x00000100
1016 _: u23 = 0,
1017};
1018
1019pub fn move_mount(from_dirfd: fd_t, from_path: [*:0]const u8, to_dirfd: fd_t, to_path: [*:0]const u8, flags: MOVE_MOUNT) usize {
1020 return syscall5(.move_mount, fd_to_usize(from_dirfd), @intFromPtr(from_path), fd_to_usize(to_dirfd), @intFromPtr(to_path), @as(u32, @bitCast(flags)));
1021}
1022
1023pub const MOUNT_ATTR = packed struct(u32) {
1024 /// Update atime relative to mtime/ctime.
1025 RELATIME: u0, // This is the default ATIME, it's true unless a different ATIME is set.
1026 /// Mount read-only.
1027 RDONLY: bool, // 0x00000001
1028 /// Ignore suid and sgid bits.
1029 NOSUID: bool, // 0x00000002
1030 /// Disallow access to device special files.
1031 NODEV: bool, // 0x00000004
1032 /// Disallow program execution.
1033 NOEXEC: bool, // 0x00000008
1034 /// Do not update access times.
1035 NOATIME: bool, // 0x00000010
1036 /// Always perform atime updates.
1037 STRICTATIME: bool, // 0x00000020
1038 _40: bool = false, // 0x00000040
1039 /// Do not update directory access times.
1040 NODIRATIME: bool, // 0x00000080
1041 _100: u12 = 0, // 0x00000100
1042 /// Idmap mount to @userns_fd in struct mount_attr.
1043 IDMAP: bool, // 0x00100000
1044 /// Do not follow symlinks.
1045 NOSYMFOLLOW: bool, // 0x00200000
1046 _: u10 = 0,
1047
1048 // ATIME: u32, // 0x00000070 This is a mask, not a flag.
1049};
1050
1051pub fn mount_setattr(dirfd: fd_t, path: [*:0]const u8, flags: MOUNT_ATTR) usize {
1052 return syscall3(.mount_setattr, fd_to_usize(dirfd), @intFromPtr(path), @as(u32, @bitCast(flags)));
1053}
1054
1055pub const FSOPEN = packed struct(u32) {
1056 /// Set CLOEXEC on the new fd.
1057 CLOEXEC: bool, // 0x00000001
1058 _: u31 = 0,
1059};
1060
1061pub fn fsopen(fsname: [*:0]const u8, flags: FSOPEN) usize {
1062 return syscall2(.fsopen, @intFromPtr(fsname), @as(u32, @bitCast(flags)));
1063}
1064
1065pub const FSCONFIG_CMD = enum(u32) {
1066 /// Set parameter, supplying no value.
1067 SET_FLAG,
1068 /// Set parameter, supplying a string value.
1069 SET_STRING,
1070 /// Set parameter, supplying a binary blob value.
1071 SET_BINARY,
1072 /// Set parameter, supplying an object by path.
1073 SET_PATH,
1074 /// Set parameter, supplying an object by (empty) path.
1075 SET_PATH_EMPTY,
1076 /// Set parameter, supplying an object by fd.
1077 SET_FD,
1078 /// Invoke superblock creation.
1079 CREATE,
1080 /// Invoke superblock reconfiguration.
1081 RECONFIGURE,
1082};
1083
1084pub fn fsconfig(fd: fd_t, cmd: FSCONFIG_CMD, key: ?[*:0]const u8, value: ?[*:0]const u8, aux: u32) usize {
1085 return syscall5(.fsconfig, fd_to_usize(fd), @intFromEnum(cmd), @intFromPtr(key), @intFromPtr(value), aux);
1086}
1087
1088pub const FSMOUNT = packed struct(u32) {
1089 /// Set CLOEXEC on the fd.
1090 CLOEXEC: bool, // 0x00000001
1091 _31: u31 = 0,
1092};
1093
1094pub fn fsmount(fsfd: fd_t, flags: FSMOUNT, attr_flags: MOUNT_ATTR) usize {
1095 return syscall3(.fsmount, fd_to_usize(fsfd), @as(u32, @bitCast(flags)), @as(u32, @bitCast(attr_flags)));
1096}
1097
1098pub const FSPICK = packed struct(u32) {
1099 /// Set CLOEXEC on the new fd.
1100 CLOEXEC: bool, // 0x00000001
1101 SYMLINK_NOFOLLOW: bool, // 0x00000002
1102 NO_AUTOMOUNT: bool, // 0x00000004
1103 EMPTY_PATH: bool, // 0x00000008
1104 _28: u28 = 0,
1105};
1106
1107pub fn fspick(dirfd: fd_t, path: [*:0]const u8, flags: FSPICK) usize {
1108 return syscall3(.fspick, fd_to_usize(dirfd), @intFromPtr(path), @as(u32, @bitCast(flags)));
1109}
1110
985pub fn pivot_root(new_root: [*:0]const u8, put_old: [*:0]const u8) usize {1111pub fn pivot_root(new_root: [*:0]const u8, put_old: [*:0]const u8) usize {
986 return syscall2(.pivot_root, @intFromPtr(new_root), @intFromPtr(put_old));1112 return syscall2(.pivot_root, @intFromPtr(new_root), @intFromPtr(put_old));
987}1113}
...@@ -1443,6 +1569,18 @@ pub fn close(fd: i32) usize {...@@ -1443,6 +1569,18 @@ pub fn close(fd: i32) usize {
1443 return syscall1(.close, @as(usize, @bitCast(@as(isize, fd))));1569 return syscall1(.close, @as(usize, @bitCast(@as(isize, fd))));
1444}1570}
14451571
1572pub const CLOSE_RANGE = packed struct(u32) {
1573 /// Unshare the file descriptor table before closing file descriptors.
1574 UNSHARE: bool, // 0x00000001
1575 /// Set the FD_CLOEXEC bit instead of closing the file descriptor.
1576 CLOEXEC: bool, // 0x00000002
1577 _: u30 = 0,
1578};
1579
1580pub fn close_range(first: fd_t, last: fd_t, flags: CLOSE_RANGE) usize {
1581 return syscall3(.close_range, fd_to_usize(first), fd_to_usize(last), @as(u32, @bitCast(flags)));
1582}
1583
1446pub fn fchmod(fd: i32, mode: mode_t) usize {1584pub fn fchmod(fd: i32, mode: mode_t) usize {
1447 return syscall2(.fchmod, @as(usize, @bitCast(@as(isize, fd))), mode);1585 return syscall2(.fchmod, @as(usize, @bitCast(@as(isize, fd))), mode);
1448}1586}
...@@ -1463,6 +1601,14 @@ pub fn fchown(fd: i32, owner: uid_t, group: gid_t) usize {...@@ -1463,6 +1601,14 @@ pub fn fchown(fd: i32, owner: uid_t, group: gid_t) usize {
1463 }1601 }
1464}1602}
14651603
1604pub fn chown(path: [*:0]const u8, owner: uid_t, group: gid_t) usize {
1605 if (@hasField(SYS, "chown32")) {
1606 return syscall3(.chown32, @intFromPtr(path), owner, group);
1607 } else {
1608 return syscall3(.chown, @intFromPtr(path), owner, group);
1609 }
1610}
1611
1466pub fn fchmodat(fd: i32, path: [*:0]const u8, mode: mode_t) usize {1612pub fn fchmodat(fd: i32, path: [*:0]const u8, mode: mode_t) usize {
1467 return syscall3(.fchmodat, @bitCast(@as(isize, fd)), @intFromPtr(path), mode);1613 return syscall3(.fchmodat, @bitCast(@as(isize, fd)), @intFromPtr(path), mode);
1468}1614}
...@@ -2477,7 +2623,7 @@ pub fn unshare(flags: usize) usize {...@@ -2477,7 +2623,7 @@ pub fn unshare(flags: usize) usize {
2477}2623}
24782624
2479pub fn setns(fd: fd_t, flags: u32) usize {2625pub fn setns(fd: fd_t, flags: u32) usize {
2480 return syscall2(.setns, fd, flags);2626 return syscall2(.setns, @as(usize, @bitCast(@as(isize, fd))), flags);
2481}2627}
24822628
2483pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize {2629pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize {
...@@ -7794,13 +7940,13 @@ pub const SIOCOUTQ = T.IOCOUTQ;...@@ -7794,13 +7940,13 @@ pub const SIOCOUTQ = T.IOCOUTQ;
77947940
7795pub const SOCK_IOC_TYPE = 0x89;7941pub const SOCK_IOC_TYPE = 0x89;
77967942
7797pub const SIOCGSTAMP_NEW = IOCTL.IOR(SOCK_IOC_TYPE, 0x06, i64[2]);7943pub const SIOCGSTAMP_NEW = IOCTL.IOR(SOCK_IOC_TYPE, 0x06, [2]i64);
7798pub const SIOCGSTAMP_OLD = IOCTL.IOR('s', 100, timeval);7944pub const SIOCGSTAMP_OLD = IOCTL.IOR('s', 100, timeval);
77997945
7800/// Get stamp (timeval)7946/// Get stamp (timeval)
7801pub const SIOCGSTAMP = if (native_arch == .x86_64 or @sizeOf(timeval) == 8) SIOCGSTAMP_OLD else SIOCGSTAMP_NEW;7947pub const SIOCGSTAMP = if (native_arch == .x86_64 or @sizeOf(timeval) == 8) SIOCGSTAMP_OLD else SIOCGSTAMP_NEW;
78027948
7803pub const SIOCGSTAMPNS_NEW = IOCTL.IOR(SOCK_IOC_TYPE, 0x07, i64[2]);7949pub const SIOCGSTAMPNS_NEW = IOCTL.IOR(SOCK_IOC_TYPE, 0x07, [2]i64);
7804pub const SIOCGSTAMPNS_OLD = IOCTL.IOR('s', 101, kernel_timespec);7950pub const SIOCGSTAMPNS_OLD = IOCTL.IOR('s', 101, kernel_timespec);
78057951
7806/// Get stamp (timespec)7952/// Get stamp (timespec)
...@@ -9948,3 +10094,7 @@ pub const cmsghdr = extern struct {...@@ -9948,3 +10094,7 @@ pub const cmsghdr = extern struct {
9948 level: i32,10094 level: i32,
9949 type: i32,10095 type: i32,
9950};10096};
10097
10098inline fn fd_to_usize(fd: fd_t) usize {
10099 return @as(usize, @bitCast(@as(isize, fd)));
10100}