mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.Io: implement fileStat
This commit is contained in:
parent
69b54b0cd1
commit
89412fda77
7 changed files with 202 additions and 156 deletions
|
|
@ -47,90 +47,14 @@ pub const Stat = struct {
|
|||
kind: Kind,
|
||||
|
||||
/// Last access time in nanoseconds, relative to UTC 1970-01-01.
|
||||
/// TODO change this to Io.Timestamp except don't waste storage on clock
|
||||
atime: i128,
|
||||
/// Last modification time in nanoseconds, relative to UTC 1970-01-01.
|
||||
/// TODO change this to Io.Timestamp except don't waste storage on clock
|
||||
mtime: i128,
|
||||
/// Last status/metadata change time in nanoseconds, relative to UTC 1970-01-01.
|
||||
/// TODO change this to Io.Timestamp except don't waste storage on clock
|
||||
ctime: i128,
|
||||
|
||||
pub fn fromPosix(st: std.posix.Stat) Stat {
|
||||
const atime = st.atime();
|
||||
const mtime = st.mtime();
|
||||
const ctime = st.ctime();
|
||||
return .{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(st.size),
|
||||
.mode = st.mode,
|
||||
.kind = k: {
|
||||
const m = st.mode & std.posix.S.IFMT;
|
||||
switch (m) {
|
||||
std.posix.S.IFBLK => break :k .block_device,
|
||||
std.posix.S.IFCHR => break :k .character_device,
|
||||
std.posix.S.IFDIR => break :k .directory,
|
||||
std.posix.S.IFIFO => break :k .named_pipe,
|
||||
std.posix.S.IFLNK => break :k .sym_link,
|
||||
std.posix.S.IFREG => break :k .file,
|
||||
std.posix.S.IFSOCK => break :k .unix_domain_socket,
|
||||
else => {},
|
||||
}
|
||||
if (builtin.os.tag == .illumos) switch (m) {
|
||||
std.posix.S.IFDOOR => break :k .door,
|
||||
std.posix.S.IFPORT => break :k .event_port,
|
||||
else => {},
|
||||
};
|
||||
|
||||
break :k .unknown;
|
||||
},
|
||||
.atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec,
|
||||
.mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec,
|
||||
.ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fromLinux(stx: std.os.linux.Statx) Stat {
|
||||
const atime = stx.atime;
|
||||
const mtime = stx.mtime;
|
||||
const ctime = stx.ctime;
|
||||
|
||||
return .{
|
||||
.inode = stx.ino,
|
||||
.size = stx.size,
|
||||
.mode = stx.mode,
|
||||
.kind = switch (stx.mode & std.os.linux.S.IFMT) {
|
||||
std.os.linux.S.IFDIR => .directory,
|
||||
std.os.linux.S.IFCHR => .character_device,
|
||||
std.os.linux.S.IFBLK => .block_device,
|
||||
std.os.linux.S.IFREG => .file,
|
||||
std.os.linux.S.IFIFO => .named_pipe,
|
||||
std.os.linux.S.IFLNK => .sym_link,
|
||||
std.os.linux.S.IFSOCK => .unix_domain_socket,
|
||||
else => .unknown,
|
||||
},
|
||||
.atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec,
|
||||
.mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec,
|
||||
.ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fromWasi(st: std.os.wasi.filestat_t) Stat {
|
||||
return .{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(st.size),
|
||||
.mode = 0,
|
||||
.kind = switch (st.filetype) {
|
||||
.BLOCK_DEVICE => .block_device,
|
||||
.CHARACTER_DEVICE => .character_device,
|
||||
.DIRECTORY => .directory,
|
||||
.SYMBOLIC_LINK => .sym_link,
|
||||
.REGULAR_FILE => .file,
|
||||
.SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket,
|
||||
else => .unknown,
|
||||
},
|
||||
.atime = st.atim,
|
||||
.mtime = st.mtim,
|
||||
.ctime = st.ctim,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn stdout() File {
|
||||
|
|
@ -145,13 +69,17 @@ pub fn stdin() File {
|
|||
return .{ .handle = if (is_windows) std.os.windows.peb().ProcessParameters.hStdInput else std.posix.STDIN_FILENO };
|
||||
}
|
||||
|
||||
pub const StatError = std.posix.FStatError || Io.Cancelable;
|
||||
pub const StatError = error{
|
||||
SystemResources,
|
||||
/// In WASI, this error may occur when the file descriptor does
|
||||
/// not hold the required rights to get its filestat information.
|
||||
AccessDenied,
|
||||
PermissionDenied,
|
||||
} || Io.Cancelable || Io.UnexpectedError;
|
||||
|
||||
/// Returns `Stat` containing basic information about the `File`.
|
||||
pub fn stat(file: File, io: Io) StatError!Stat {
|
||||
_ = file;
|
||||
_ = io;
|
||||
@panic("TODO");
|
||||
return io.vtable.fileStat(io.userdata, file);
|
||||
}
|
||||
|
||||
pub const OpenFlags = std.fs.File.OpenFlags;
|
||||
|
|
|
|||
|
|
@ -163,7 +163,12 @@ pub fn io(pool: *Pool) Io {
|
|||
.dirMake = dirMake,
|
||||
.dirStat = dirStat,
|
||||
.dirStatPath = dirStatPath,
|
||||
.fileStat = fileStat,
|
||||
.fileStat = switch (builtin.os.tag) {
|
||||
.linux => fileStatLinux,
|
||||
.windows => fileStatWindows,
|
||||
.wasi => fileStatWasi,
|
||||
else => fileStatPosix,
|
||||
},
|
||||
.createFile = createFile,
|
||||
.fileOpen = fileOpen,
|
||||
.fileClose = fileClose,
|
||||
|
|
@ -781,14 +786,80 @@ fn dirStatPath(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8) Io.Dir.
|
|||
@panic("TODO");
|
||||
}
|
||||
|
||||
fn fileStat(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||
fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||
const pool: *Pool = @ptrCast(@alignCast(userdata));
|
||||
const fstat_sym = if (posix.lfs64_abi) posix.system.fstat64 else posix.system.fstat;
|
||||
while (true) {
|
||||
try pool.checkCancel();
|
||||
var stat = std.mem.zeroes(posix.Stat);
|
||||
switch (posix.errno(fstat_sym(file.handle, &stat))) {
|
||||
.SUCCESS => return statFromPosix(&stat),
|
||||
.INTR => continue,
|
||||
.INVAL => |err| return errnoBug(err),
|
||||
.BADF => |err| return errnoBug(err),
|
||||
.NOMEM => return error.SystemResources,
|
||||
.ACCES => return error.AccessDenied,
|
||||
else => |err| return posix.unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||
const pool: *Pool = @ptrCast(@alignCast(userdata));
|
||||
const linux = std.os.linux;
|
||||
while (true) {
|
||||
try pool.checkCancel();
|
||||
var statx = std.mem.zeroes(linux.Statx);
|
||||
const rc = linux.statx(
|
||||
file.handle,
|
||||
"",
|
||||
linux.AT.EMPTY_PATH,
|
||||
linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
|
||||
&statx,
|
||||
);
|
||||
switch (linux.E.init(rc)) {
|
||||
.SUCCESS => return statFromLinux(&statx),
|
||||
.INTR => continue,
|
||||
.ACCES => |err| return errnoBug(err),
|
||||
.BADF => |err| return errnoBug(err),
|
||||
.FAULT => |err| return errnoBug(err),
|
||||
.INVAL => |err| return errnoBug(err),
|
||||
.LOOP => |err| return errnoBug(err),
|
||||
.NAMETOOLONG => |err| return errnoBug(err),
|
||||
.NOENT => |err| return errnoBug(err),
|
||||
.NOMEM => return error.SystemResources,
|
||||
.NOTDIR => |err| return errnoBug(err),
|
||||
else => |err| return posix.unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||
const pool: *Pool = @ptrCast(@alignCast(userdata));
|
||||
try pool.checkCancel();
|
||||
|
||||
_ = file;
|
||||
@panic("TODO");
|
||||
}
|
||||
|
||||
fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||
if (builtin.link_libc) return fileStatPosix(userdata, file);
|
||||
const pool: *Pool = @ptrCast(@alignCast(userdata));
|
||||
while (true) {
|
||||
try pool.checkCancel();
|
||||
var stat: std.os.wasi.filestat_t = undefined;
|
||||
switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {
|
||||
.SUCCESS => return statFromWasi(&stat),
|
||||
.INTR => continue,
|
||||
.INVAL => |err| return errnoBug(err),
|
||||
.BADF => |err| return errnoBug(err),
|
||||
.NOMEM => return error.SystemResources,
|
||||
.ACCES => return error.AccessDenied,
|
||||
.NOTCAPABLE => return error.AccessDenied,
|
||||
else => |err| return posix.unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn createFile(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
|
|
@ -2114,3 +2185,81 @@ fn clockToWasi(clock: Io.Timestamp.Clock) std.os.wasi.clockid_t {
|
|||
.cpu_thread => .THREAD_CPUTIME_ID,
|
||||
};
|
||||
}
|
||||
|
||||
fn statFromLinux(stx: *const std.os.linux.Statx) Io.File.Stat {
|
||||
const atime = stx.atime;
|
||||
const mtime = stx.mtime;
|
||||
const ctime = stx.ctime;
|
||||
return .{
|
||||
.inode = stx.ino,
|
||||
.size = stx.size,
|
||||
.mode = stx.mode,
|
||||
.kind = switch (stx.mode & std.os.linux.S.IFMT) {
|
||||
std.os.linux.S.IFDIR => .directory,
|
||||
std.os.linux.S.IFCHR => .character_device,
|
||||
std.os.linux.S.IFBLK => .block_device,
|
||||
std.os.linux.S.IFREG => .file,
|
||||
std.os.linux.S.IFIFO => .named_pipe,
|
||||
std.os.linux.S.IFLNK => .sym_link,
|
||||
std.os.linux.S.IFSOCK => .unix_domain_socket,
|
||||
else => .unknown,
|
||||
},
|
||||
.atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec,
|
||||
.mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec,
|
||||
.ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec,
|
||||
};
|
||||
}
|
||||
|
||||
fn statFromPosix(st: *const std.posix.Stat) Io.File.Stat {
|
||||
const atime = st.atime();
|
||||
const mtime = st.mtime();
|
||||
const ctime = st.ctime();
|
||||
return .{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(st.size),
|
||||
.mode = st.mode,
|
||||
.kind = k: {
|
||||
const m = st.mode & std.posix.S.IFMT;
|
||||
switch (m) {
|
||||
std.posix.S.IFBLK => break :k .block_device,
|
||||
std.posix.S.IFCHR => break :k .character_device,
|
||||
std.posix.S.IFDIR => break :k .directory,
|
||||
std.posix.S.IFIFO => break :k .named_pipe,
|
||||
std.posix.S.IFLNK => break :k .sym_link,
|
||||
std.posix.S.IFREG => break :k .file,
|
||||
std.posix.S.IFSOCK => break :k .unix_domain_socket,
|
||||
else => {},
|
||||
}
|
||||
if (builtin.os.tag == .illumos) switch (m) {
|
||||
std.posix.S.IFDOOR => break :k .door,
|
||||
std.posix.S.IFPORT => break :k .event_port,
|
||||
else => {},
|
||||
};
|
||||
|
||||
break :k .unknown;
|
||||
},
|
||||
.atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec,
|
||||
.mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec,
|
||||
.ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec,
|
||||
};
|
||||
}
|
||||
|
||||
fn statFromWasi(st: *const std.os.wasi.filestat_t) Io.File.Stat {
|
||||
return .{
|
||||
.inode = st.ino,
|
||||
.size = @bitCast(st.size),
|
||||
.mode = 0,
|
||||
.kind = switch (st.filetype) {
|
||||
.BLOCK_DEVICE => .block_device,
|
||||
.CHARACTER_DEVICE => .character_device,
|
||||
.DIRECTORY => .directory,
|
||||
.SYMBOLIC_LINK => .sym_link,
|
||||
.REGULAR_FILE => .file,
|
||||
.SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket,
|
||||
else => .unknown,
|
||||
},
|
||||
.atime = st.atim,
|
||||
.mtime = st.mtim,
|
||||
.ctime = st.ctim,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ pub const SelfInfoError = error{
|
|||
/// The required debug info could not be read from disk due to some IO error.
|
||||
ReadFailed,
|
||||
OutOfMemory,
|
||||
Canceled,
|
||||
Unexpected,
|
||||
};
|
||||
|
||||
|
|
@ -691,6 +692,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri
|
|||
error.UnsupportedDebugInfo => "unwind info unsupported",
|
||||
error.ReadFailed => "filesystem error",
|
||||
error.OutOfMemory => "out of memory",
|
||||
error.Canceled => "operation canceled",
|
||||
error.Unexpected => "unexpected error",
|
||||
};
|
||||
if (it.stratOk(options.allow_unsafe_unwind)) {
|
||||
|
|
@ -1079,7 +1081,7 @@ fn printSourceAtAddress(gpa: Allocator, debug_info: *SelfInfo, writer: *Writer,
|
|||
error.UnsupportedDebugInfo,
|
||||
error.InvalidDebugInfo,
|
||||
=> .unknown,
|
||||
error.ReadFailed, error.Unexpected => s: {
|
||||
error.ReadFailed, error.Unexpected, error.Canceled => s: {
|
||||
tty_config.setColor(writer, .dim) catch {};
|
||||
try writer.print("Failed to read debug info from filesystem, trace may be incomplete\n\n", .{});
|
||||
tty_config.setColor(writer, .reset) catch {};
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ pub const LoadError = error{
|
|||
LockedMemoryLimitExceeded,
|
||||
ProcessFdQuotaExceeded,
|
||||
SystemFdQuotaExceeded,
|
||||
Canceled,
|
||||
Unexpected,
|
||||
};
|
||||
|
||||
|
|
@ -408,7 +409,7 @@ fn loadInner(
|
|||
arena: Allocator,
|
||||
elf_file: std.fs.File,
|
||||
opt_crc: ?u32,
|
||||
) (LoadError || error{CrcMismatch})!LoadInnerResult {
|
||||
) (LoadError || error{ CrcMismatch, Canceled })!LoadInnerResult {
|
||||
const mapped_mem: []align(std.heap.page_size_min) const u8 = mapped: {
|
||||
const file_len = std.math.cast(
|
||||
usize,
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ const Module = struct {
|
|||
var elf_file = load_result catch |err| switch (err) {
|
||||
error.OutOfMemory,
|
||||
error.Unexpected,
|
||||
error.Canceled,
|
||||
=> |e| return e,
|
||||
|
||||
error.Overflow,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
const File = @This();
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const Os = std.builtin.Os;
|
||||
const native_os = builtin.os.tag;
|
||||
const is_windows = native_os == .windows;
|
||||
|
||||
const File = @This();
|
||||
const std = @import("../std.zig");
|
||||
const Io = std.Io;
|
||||
const Os = std.builtin.Os;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const posix = std.posix;
|
||||
const math = std.math;
|
||||
|
|
@ -17,12 +19,12 @@ const Alignment = std.mem.Alignment;
|
|||
/// The OS-specific file descriptor or file handle.
|
||||
handle: Handle,
|
||||
|
||||
pub const Handle = std.Io.File.Handle;
|
||||
pub const Mode = std.Io.File.Mode;
|
||||
pub const INode = std.Io.File.INode;
|
||||
pub const Handle = Io.File.Handle;
|
||||
pub const Mode = Io.File.Mode;
|
||||
pub const INode = Io.File.INode;
|
||||
pub const Uid = posix.uid_t;
|
||||
pub const Gid = posix.gid_t;
|
||||
pub const Kind = std.Io.File.Kind;
|
||||
pub const Kind = Io.File.Kind;
|
||||
|
||||
/// This is the default mode given to POSIX operating systems for creating
|
||||
/// files. `0o666` is "-rw-rw-rw-" which is counter-intuitive at first,
|
||||
|
|
@ -386,7 +388,7 @@ pub fn mode(self: File) ModeError!Mode {
|
|||
return (try self.stat()).mode;
|
||||
}
|
||||
|
||||
pub const Stat = std.Io.File.Stat;
|
||||
pub const Stat = Io.File.Stat;
|
||||
|
||||
pub const StatError = posix.FStatError;
|
||||
|
||||
|
|
@ -436,39 +438,9 @@ pub fn stat(self: File) StatError!Stat {
|
|||
};
|
||||
}
|
||||
|
||||
if (builtin.os.tag == .wasi and !builtin.link_libc) {
|
||||
const st = try std.os.fstat_wasi(self.handle);
|
||||
return Stat.fromWasi(st);
|
||||
}
|
||||
|
||||
if (builtin.os.tag == .linux) {
|
||||
var stx = std.mem.zeroes(linux.Statx);
|
||||
|
||||
const rc = linux.statx(
|
||||
self.handle,
|
||||
"",
|
||||
linux.AT.EMPTY_PATH,
|
||||
linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
|
||||
&stx,
|
||||
);
|
||||
|
||||
return switch (linux.E.init(rc)) {
|
||||
.SUCCESS => Stat.fromLinux(stx),
|
||||
.ACCES => unreachable,
|
||||
.BADF => unreachable,
|
||||
.FAULT => unreachable,
|
||||
.INVAL => unreachable,
|
||||
.LOOP => unreachable,
|
||||
.NAMETOOLONG => unreachable,
|
||||
.NOENT => unreachable,
|
||||
.NOMEM => error.SystemResources,
|
||||
.NOTDIR => unreachable,
|
||||
else => |err| posix.unexpectedErrno(err),
|
||||
};
|
||||
}
|
||||
|
||||
const st = try posix.fstat(self.handle);
|
||||
return Stat.fromPosix(st);
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
return Io.File.stat(.{ .handle = self.handle }, io);
|
||||
}
|
||||
|
||||
pub const ChmodError = posix.FChmodError;
|
||||
|
|
@ -785,8 +757,8 @@ pub fn pwritev(self: File, iovecs: []posix.iovec_const, offset: u64) PWriteError
|
|||
return posix.pwritev(self.handle, iovecs, offset);
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `std.Io.File.Reader`.
|
||||
pub const Reader = std.Io.File.Reader;
|
||||
/// Deprecated in favor of `Io.File.Reader`.
|
||||
pub const Reader = Io.File.Reader;
|
||||
|
||||
pub const Writer = struct {
|
||||
file: File,
|
||||
|
|
@ -799,7 +771,7 @@ pub const Writer = struct {
|
|||
copy_file_range_err: ?CopyFileRangeError = null,
|
||||
fcopyfile_err: ?FcopyfileError = null,
|
||||
seek_err: ?Writer.SeekError = null,
|
||||
interface: std.Io.Writer,
|
||||
interface: Io.Writer,
|
||||
|
||||
pub const Mode = Reader.Mode;
|
||||
|
||||
|
|
@ -845,13 +817,13 @@ pub const Writer = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn initInterface(buffer: []u8) std.Io.Writer {
|
||||
pub fn initInterface(buffer: []u8) Io.Writer {
|
||||
return .{
|
||||
.vtable = &.{
|
||||
.drain = drain,
|
||||
.sendFile = switch (builtin.zig_backend) {
|
||||
else => sendFile,
|
||||
.stage2_aarch64 => std.Io.Writer.unimplementedSendFile,
|
||||
.stage2_aarch64 => Io.Writer.unimplementedSendFile,
|
||||
},
|
||||
},
|
||||
.buffer = buffer,
|
||||
|
|
@ -859,7 +831,7 @@ pub const Writer = struct {
|
|||
}
|
||||
|
||||
/// TODO when this logic moves from fs.File to Io.File the io parameter should be deleted
|
||||
pub fn moveToReader(w: *Writer, io: std.Io) Reader {
|
||||
pub fn moveToReader(w: *Writer, io: Io) Reader {
|
||||
defer w.* = undefined;
|
||||
return .{
|
||||
.io = io,
|
||||
|
|
@ -871,7 +843,7 @@ pub const Writer = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
|
||||
pub fn drain(io_w: *Io.Writer, data: []const []const u8, splat: usize) Io.Writer.Error!usize {
|
||||
const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w));
|
||||
const handle = w.file.handle;
|
||||
const buffered = io_w.buffered();
|
||||
|
|
@ -1021,10 +993,10 @@ pub const Writer = struct {
|
|||
}
|
||||
|
||||
pub fn sendFile(
|
||||
io_w: *std.Io.Writer,
|
||||
file_reader: *std.Io.File.Reader,
|
||||
limit: std.Io.Limit,
|
||||
) std.Io.Writer.FileError!usize {
|
||||
io_w: *Io.Writer,
|
||||
file_reader: *Io.File.Reader,
|
||||
limit: Io.Limit,
|
||||
) Io.Writer.FileError!usize {
|
||||
const reader_buffered = file_reader.interface.buffered();
|
||||
if (reader_buffered.len >= @intFromEnum(limit))
|
||||
return sendFileBuffered(io_w, file_reader, limit.slice(reader_buffered));
|
||||
|
|
@ -1288,16 +1260,16 @@ pub const Writer = struct {
|
|||
}
|
||||
|
||||
fn sendFileBuffered(
|
||||
io_w: *std.Io.Writer,
|
||||
file_reader: *std.Io.File.Reader,
|
||||
io_w: *Io.Writer,
|
||||
file_reader: *Io.File.Reader,
|
||||
reader_buffered: []const u8,
|
||||
) std.Io.Writer.FileError!usize {
|
||||
) Io.Writer.FileError!usize {
|
||||
const n = try drain(io_w, &.{reader_buffered}, 1);
|
||||
file_reader.seekBy(@intCast(n)) catch return error.ReadFailed;
|
||||
return n;
|
||||
}
|
||||
|
||||
pub fn seekTo(w: *Writer, offset: u64) (Writer.SeekError || std.Io.Writer.Error)!void {
|
||||
pub fn seekTo(w: *Writer, offset: u64) (Writer.SeekError || Io.Writer.Error)!void {
|
||||
try w.interface.flush();
|
||||
try seekToUnbuffered(w, offset);
|
||||
}
|
||||
|
|
@ -1321,7 +1293,7 @@ pub const Writer = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub const EndError = SetEndPosError || std.Io.Writer.Error;
|
||||
pub const EndError = SetEndPosError || Io.Writer.Error;
|
||||
|
||||
/// Flushes any buffered data and sets the end position of the file.
|
||||
///
|
||||
|
|
@ -1352,14 +1324,14 @@ pub const Writer = struct {
|
|||
///
|
||||
/// Positional is more threadsafe, since the global seek position is not
|
||||
/// affected.
|
||||
pub fn reader(file: File, io: std.Io, buffer: []u8) Reader {
|
||||
pub fn reader(file: File, io: Io, buffer: []u8) Reader {
|
||||
return .init(.{ .handle = file.handle }, io, buffer);
|
||||
}
|
||||
|
||||
/// Positional is more threadsafe, since the global seek position is not
|
||||
/// affected, but when such syscalls are not available, preemptively
|
||||
/// initializing in streaming mode skips a failed syscall.
|
||||
pub fn readerStreaming(file: File, io: std.Io, buffer: []u8) Reader {
|
||||
pub fn readerStreaming(file: File, io: Io, buffer: []u8) Reader {
|
||||
return .initStreaming(.{ .handle = file.handle }, io, buffer);
|
||||
}
|
||||
|
||||
|
|
@ -1541,10 +1513,10 @@ pub fn downgradeLock(file: File) LockError!void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn adaptToNewApi(file: File) std.Io.File {
|
||||
pub fn adaptToNewApi(file: File) Io.File {
|
||||
return .{ .handle = file.handle };
|
||||
}
|
||||
|
||||
pub fn adaptFromNewApi(file: std.Io.File) File {
|
||||
pub fn adaptFromNewApi(file: Io.File) File {
|
||||
return .{ .handle = file.handle };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4458,14 +4458,7 @@ pub fn wait4(pid: pid_t, flags: u32, ru: ?*rusage) WaitPidResult {
|
|||
}
|
||||
}
|
||||
|
||||
pub const FStatError = error{
|
||||
SystemResources,
|
||||
|
||||
/// In WASI, this error may occur when the file descriptor does
|
||||
/// not hold the required rights to get its filestat information.
|
||||
AccessDenied,
|
||||
PermissionDenied,
|
||||
} || UnexpectedError;
|
||||
pub const FStatError = std.Io.File.StatError;
|
||||
|
||||
/// Return information about a file descriptor.
|
||||
pub fn fstat(fd: fd_t) FStatError!Stat {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue