diff options
Diffstat (limited to 'lib/std/os/linux.zig')
| -rw-r--r-- | lib/std/os/linux.zig | 180 |
1 files changed, 8 insertions, 172 deletions
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index d0cd278224..96b4c8ee6f 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1420,7 +1420,7 @@ pub fn chmod(path: [*:0]const u8, mode: mode_t) usize { if (@hasField(SYS, "chmod")) { return syscall2(.chmod, @intFromPtr(path), mode); } else { - return fchmodat(AT.FDCWD, path, mode, 0); + return fchmodat(AT.FDCWD, path, mode); } } @@ -1432,7 +1432,7 @@ pub fn fchown(fd: i32, owner: uid_t, group: gid_t) usize { } } -pub fn fchmodat(fd: i32, path: [*:0]const u8, mode: mode_t, _: u32) usize { +pub fn fchmodat(fd: i32, path: [*:0]const u8, mode: mode_t) usize { return syscall3(.fchmodat, @bitCast(@as(isize, fd)), @intFromPtr(path), mode); } @@ -1561,14 +1561,14 @@ pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) usize { } } -pub fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: i32) usize { +pub fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: u32) usize { return syscall5( .linkat, @as(usize, @bitCast(@as(isize, oldfd))), @intFromPtr(oldpath), @as(usize, @bitCast(@as(isize, newfd))), @intFromPtr(newpath), - @as(usize, @bitCast(@as(isize, flags))), + flags, ); } @@ -6040,7 +6040,7 @@ pub const dirent64 = extern struct { off: u64, reclen: u16, type: u8, - name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173 + name: [0]u8, }; pub const dl_phdr_info = extern struct { @@ -6891,10 +6891,6 @@ pub const utsname = extern struct { }; pub const HOST_NAME_MAX = 64; -/// Flags used to request specific members in `Statx` be filled out. -/// The `Statx.mask` member will be updated with what information the kernel -/// returned. Callers must check this field since support varies by kernel -/// version and filesystem. pub const STATX = packed struct(u32) { /// Want `mode & S.IFMT`. TYPE: bool = false, @@ -6982,7 +6978,9 @@ pub const statx_timestamp = extern struct { /// Renamed to `Statx` to not conflict with the `statx` function. pub const Statx = extern struct { - /// Mask of bits indicating filled fields. + /// Mask of bits indicating filled fields. Updated with what information + /// the kernel returned. Callers must check this field since support varies + /// by kernel version and filesystem. mask: STATX, /// Block size for filesystem I/O. blksize: u32, @@ -9872,165 +9870,3 @@ pub const cmsghdr = extern struct { level: i32, type: i32, }; - -/// The syscalls, but with Zig error sets, going through libc if linking libc, -/// and with some footguns eliminated. -pub const wrapped = struct { - pub const lfs64_abi = builtin.link_libc and (builtin.abi.isGnu() or builtin.abi.isAndroid()); - const system = if (builtin.link_libc) std.c else std.os.linux; - - pub const SendfileError = std.posix.UnexpectedError || error{ - /// `out_fd` is an unconnected socket, or out_fd closed its read end. - BrokenPipe, - /// Descriptor is not valid or locked, or an mmap(2)-like operation is not available for in_fd. - UnsupportedOperation, - /// Nonblocking I/O has been selected but the write would block. - WouldBlock, - /// Unspecified error while reading from in_fd. - InputOutput, - /// Insufficient kernel memory to read from in_fd. - SystemResources, - /// `offset` is not `null` but the input file is not seekable. - Unseekable, - }; - - pub fn sendfile( - out_fd: fd_t, - in_fd: fd_t, - in_offset: ?*off_t, - in_len: usize, - ) SendfileError!usize { - const adjusted_len = @min(in_len, 0x7ffff000); // Prevents EOVERFLOW. - const sendfileSymbol = if (lfs64_abi) system.sendfile64 else system.sendfile; - const rc = sendfileSymbol(out_fd, in_fd, in_offset, adjusted_len); - switch (system.errno(rc)) { - .SUCCESS => return @intCast(rc), - .BADF => return invalidApiUsage(), // Always a race condition. - .FAULT => return invalidApiUsage(), // Segmentation fault. - .OVERFLOW => return unexpectedErrno(.OVERFLOW), // We avoid passing too large of a `count`. - .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket - .INVAL => return error.UnsupportedOperation, - .AGAIN => return error.WouldBlock, - .IO => return error.InputOutput, - .PIPE => return error.BrokenPipe, - .NOMEM => return error.SystemResources, - .NXIO => return error.Unseekable, - .SPIPE => return error.Unseekable, - else => |err| return unexpectedErrno(err), - } - } - - pub const CopyFileRangeError = std.posix.UnexpectedError || error{ - /// One of: - /// * One or more file descriptors are not valid. - /// * fd_in is not open for reading; or fd_out is not open for writing. - /// * The O_APPEND flag is set for the open file description referred - /// to by the file descriptor fd_out. - BadFileFlags, - /// One of: - /// * An attempt was made to write at a position past the maximum file - /// offset the kernel supports. - /// * An attempt was made to write a range that exceeds the allowed - /// maximum file size. The maximum file size differs between - /// filesystem implementations and can be different from the maximum - /// allowed file offset. - /// * An attempt was made to write beyond the process's file size - /// resource limit. This may also result in the process receiving a - /// SIGXFSZ signal. - FileTooBig, - /// One of: - /// * either fd_in or fd_out is not a regular file - /// * flags argument is not zero - /// * fd_in and fd_out refer to the same file and the source and target ranges overlap. - InvalidArguments, - /// A low-level I/O error occurred while copying. - InputOutput, - /// Either fd_in or fd_out refers to a directory. - IsDir, - OutOfMemory, - /// There is not enough space on the target filesystem to complete the copy. - NoSpaceLeft, - /// (since Linux 5.19) the filesystem does not support this operation. - OperationNotSupported, - /// The requested source or destination range is too large to represent - /// in the specified data types. - Overflow, - /// fd_out refers to an immutable file. - PermissionDenied, - /// Either fd_in or fd_out refers to an active swap file. - SwapFile, - /// The files referred to by fd_in and fd_out are not on the same - /// filesystem, and the source and target filesystems are not of the - /// same type, or do not support cross-filesystem copy. - NotSameFileSystem, - }; - - pub fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, len: usize, flags: u32) CopyFileRangeError!usize { - const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 }); - const sys = if (use_c) std.c else std.os.linux; - const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags); - switch (sys.errno(rc)) { - .SUCCESS => return @intCast(rc), - .BADF => return error.BadFileFlags, - .FBIG => return error.FileTooBig, - .INVAL => return error.InvalidArguments, - .IO => return error.InputOutput, - .ISDIR => return error.IsDir, - .NOMEM => return error.OutOfMemory, - .NOSPC => return error.NoSpaceLeft, - .OPNOTSUPP => return error.OperationNotSupported, - .OVERFLOW => return error.Overflow, - .PERM => return error.PermissionDenied, - .TXTBSY => return error.SwapFile, - .XDEV => return error.NotSameFileSystem, - else => |err| return unexpectedErrno(err), - } - } - - pub const StatxError = std.posix.UnexpectedError || error{ - /// Search permission is denied for one of the directories in `path`. - AccessDenied, - /// Too many symbolic links were encountered traversing `path`. - SymLinkLoop, - /// `path` is too long. - NameTooLong, - /// One of: - /// - A component of `path` does not exist. - /// - A component of `path` is not a directory. - /// - `path` is a relative and `dirfd` is not a directory file descriptor. - FileNotFound, - /// Insufficient memory is available. - SystemResources, - }; - - pub fn statx(dirfd: fd_t, path: [*:0]const u8, flags: u32, mask: STATX) StatxError!Statx { - const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) - .{ .major = 30, .minor = 0, .patch = 0 } - else - .{ .major = 2, .minor = 28, .patch = 0 }); - const sys = if (use_c) std.c else std.os.linux; - - var stx = std.mem.zeroes(Statx); - const rc = sys.statx(dirfd, path, flags, mask, &stx); - return switch (sys.errno(rc)) { - .SUCCESS => stx, - .ACCES => error.AccessDenied, - .BADF => invalidApiUsage(), - .FAULT => invalidApiUsage(), - .INVAL => invalidApiUsage(), - .LOOP => error.SymLinkLoop, - .NAMETOOLONG => error.NameTooLong, - .NOENT => error.FileNotFound, - .NOTDIR => error.FileNotFound, - .NOMEM => error.SystemResources, - else => |err| unexpectedErrno(err), - }; - } - - const unexpectedErrno = std.posix.unexpectedErrno; - - fn invalidApiUsage() error{Unexpected} { - if (builtin.mode == .Debug) @panic("invalid API usage"); - return error.Unexpected; - } -}; |
