mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.Io.Threaded: add ioBasic which disables networking
This commit is contained in:
parent
701d4bc80b
commit
46f7e3ea9f
@ -168,80 +168,28 @@ pub fn io(t: *Threaded) Io {
|
||||
.conditionWaitUncancelable = conditionWaitUncancelable,
|
||||
.conditionWake = conditionWake,
|
||||
|
||||
.dirMake = switch (native_os) {
|
||||
.windows => dirMakeWindows,
|
||||
.wasi => dirMakeWasi,
|
||||
else => dirMakePosix,
|
||||
},
|
||||
.dirMakePath = switch (native_os) {
|
||||
.windows => dirMakePathWindows,
|
||||
else => dirMakePathPosix,
|
||||
},
|
||||
.dirMakeOpenPath = switch (native_os) {
|
||||
.windows => dirMakeOpenPathWindows,
|
||||
.wasi => dirMakeOpenPathWasi,
|
||||
else => dirMakeOpenPathPosix,
|
||||
},
|
||||
.dirMake = dirMake,
|
||||
.dirMakePath = dirMakePath,
|
||||
.dirMakeOpenPath = dirMakeOpenPath,
|
||||
.dirStat = dirStat,
|
||||
.dirStatPath = switch (native_os) {
|
||||
.linux => dirStatPathLinux,
|
||||
.windows => dirStatPathWindows,
|
||||
.wasi => dirStatPathWasi,
|
||||
else => dirStatPathPosix,
|
||||
},
|
||||
.fileStat = switch (native_os) {
|
||||
.linux => fileStatLinux,
|
||||
.windows => fileStatWindows,
|
||||
.wasi => fileStatWasi,
|
||||
else => fileStatPosix,
|
||||
},
|
||||
.dirAccess = switch (native_os) {
|
||||
.windows => dirAccessWindows,
|
||||
.wasi => dirAccessWasi,
|
||||
else => dirAccessPosix,
|
||||
},
|
||||
.dirCreateFile = switch (native_os) {
|
||||
.windows => dirCreateFileWindows,
|
||||
.wasi => dirCreateFileWasi,
|
||||
else => dirCreateFilePosix,
|
||||
},
|
||||
.dirOpenFile = switch (native_os) {
|
||||
.windows => dirOpenFileWindows,
|
||||
.wasi => dirOpenFileWasi,
|
||||
else => dirOpenFilePosix,
|
||||
},
|
||||
.dirOpenDir = switch (native_os) {
|
||||
.wasi => dirOpenDirWasi,
|
||||
.haiku => dirOpenDirHaiku,
|
||||
else => dirOpenDirPosix,
|
||||
},
|
||||
.dirStatPath = dirStatPath,
|
||||
.fileStat = fileStat,
|
||||
.dirAccess = dirAccess,
|
||||
.dirCreateFile = dirCreateFile,
|
||||
.dirOpenFile = dirOpenFile,
|
||||
.dirOpenDir = dirOpenDir,
|
||||
.dirClose = dirClose,
|
||||
.fileClose = fileClose,
|
||||
.fileWriteStreaming = fileWriteStreaming,
|
||||
.fileWritePositional = fileWritePositional,
|
||||
.fileReadStreaming = switch (native_os) {
|
||||
.windows => fileReadStreamingWindows,
|
||||
else => fileReadStreamingPosix,
|
||||
},
|
||||
.fileReadPositional = switch (native_os) {
|
||||
.windows => fileReadPositionalWindows,
|
||||
else => fileReadPositionalPosix,
|
||||
},
|
||||
.fileReadStreaming = fileReadStreaming,
|
||||
.fileReadPositional = fileReadPositional,
|
||||
.fileSeekBy = fileSeekBy,
|
||||
.fileSeekTo = fileSeekTo,
|
||||
.openSelfExe = openSelfExe,
|
||||
|
||||
.now = switch (native_os) {
|
||||
.windows => nowWindows,
|
||||
.wasi => nowWasi,
|
||||
else => nowPosix,
|
||||
},
|
||||
.sleep = switch (native_os) {
|
||||
.windows => sleepWindows,
|
||||
.wasi => sleepWasi,
|
||||
.linux => sleepLinux,
|
||||
else => sleepPosix,
|
||||
},
|
||||
.now = now,
|
||||
.sleep = sleep,
|
||||
|
||||
.netListenIp = switch (native_os) {
|
||||
.windows => netListenIpWindows,
|
||||
@ -291,6 +239,73 @@ pub fn io(t: *Threaded) Io {
|
||||
};
|
||||
}
|
||||
|
||||
/// Same as `io` but disables all networking functionality, which has
|
||||
/// an additional dependency on Windows (ws2_32).
|
||||
pub fn ioBasic(t: *Threaded) Io {
|
||||
return .{
|
||||
.userdata = t,
|
||||
.vtable = &.{
|
||||
.async = async,
|
||||
.concurrent = concurrent,
|
||||
.await = await,
|
||||
.cancel = cancel,
|
||||
.cancelRequested = cancelRequested,
|
||||
.select = select,
|
||||
|
||||
.groupAsync = groupAsync,
|
||||
.groupWait = groupWait,
|
||||
.groupWaitUncancelable = groupWaitUncancelable,
|
||||
.groupCancel = groupCancel,
|
||||
|
||||
.mutexLock = mutexLock,
|
||||
.mutexLockUncancelable = mutexLockUncancelable,
|
||||
.mutexUnlock = mutexUnlock,
|
||||
|
||||
.conditionWait = conditionWait,
|
||||
.conditionWaitUncancelable = conditionWaitUncancelable,
|
||||
.conditionWake = conditionWake,
|
||||
|
||||
.dirMake = dirMake,
|
||||
.dirMakePath = dirMakePath,
|
||||
.dirMakeOpenPath = dirMakeOpenPath,
|
||||
.dirStat = dirStat,
|
||||
.dirStatPath = dirStatPath,
|
||||
.fileStat = fileStat,
|
||||
.dirAccess = dirAccess,
|
||||
.dirCreateFile = dirCreateFile,
|
||||
.dirOpenFile = dirOpenFile,
|
||||
.dirOpenDir = dirOpenDir,
|
||||
.dirClose = dirClose,
|
||||
.fileClose = fileClose,
|
||||
.fileWriteStreaming = fileWriteStreaming,
|
||||
.fileWritePositional = fileWritePositional,
|
||||
.fileReadStreaming = fileReadStreaming,
|
||||
.fileReadPositional = fileReadPositional,
|
||||
.fileSeekBy = fileSeekBy,
|
||||
.fileSeekTo = fileSeekTo,
|
||||
.openSelfExe = openSelfExe,
|
||||
|
||||
.now = now,
|
||||
.sleep = sleep,
|
||||
|
||||
.netListenIp = netListenIpUnavailable,
|
||||
.netListenUnix = netListenUnixUnavailable,
|
||||
.netAccept = netAcceptUnavailable,
|
||||
.netBindIp = netBindIpUnavailable,
|
||||
.netConnectIp = netConnectIpUnavailable,
|
||||
.netConnectUnix = netConnectUnixUnavailable,
|
||||
.netClose = netCloseUnavailable,
|
||||
.netRead = netReadUnavailable,
|
||||
.netWrite = netWriteUnavailable,
|
||||
.netSend = netSendUnavailable,
|
||||
.netReceive = netReceiveUnavailable,
|
||||
.netInterfaceNameResolve = netInterfaceNameResolveUnavailable,
|
||||
.netInterfaceName = netInterfaceNameUnavailable,
|
||||
.netLookup = netLookupUnavailable,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub const socket_flags_unsupported = native_os.isDarwin() or native_os == .haiku; // 💩💩
|
||||
const have_accept4 = !socket_flags_unsupported;
|
||||
const have_flock_open_flags = @hasField(posix.O, "EXLOCK");
|
||||
@ -804,7 +819,7 @@ fn mutexUnlock(userdata: ?*anyopaque, prev_state: Io.Mutex.State, mutex: *Io.Mut
|
||||
fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) void {
|
||||
if (builtin.single_threaded) unreachable; // Deadlock.
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = t.io();
|
||||
const t_io = ioBasic(t);
|
||||
comptime assert(@TypeOf(cond.state) == u64);
|
||||
const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);
|
||||
const cond_state = &ints[0];
|
||||
@ -835,6 +850,7 @@ fn conditionWaitUncancelable(userdata: ?*anyopaque, cond: *Io.Condition, mutex:
|
||||
fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) Io.Cancelable!void {
|
||||
if (builtin.single_threaded) unreachable; // Deadlock.
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = ioBasic(t);
|
||||
comptime assert(@TypeOf(cond.state) == u64);
|
||||
const ints: *[2]std.atomic.Value(u32) = @ptrCast(&cond.state);
|
||||
const cond_state = &ints[0];
|
||||
@ -858,8 +874,8 @@ fn conditionWait(userdata: ?*anyopaque, cond: *Io.Condition, mutex: *Io.Mutex) I
|
||||
assert(state & waiter_mask != waiter_mask);
|
||||
state += one_waiter;
|
||||
|
||||
mutex.unlock(t.io());
|
||||
defer mutex.lockUncancelable(t.io());
|
||||
mutex.unlock(t_io);
|
||||
defer mutex.lockUncancelable(t_io);
|
||||
|
||||
while (true) {
|
||||
try futexWait(t, cond_epoch, epoch);
|
||||
@ -939,6 +955,12 @@ fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition.
|
||||
}
|
||||
}
|
||||
|
||||
const dirMake = switch (native_os) {
|
||||
.windows => dirMakeWindows,
|
||||
.wasi => dirMakeWasi,
|
||||
else => dirMakePosix,
|
||||
};
|
||||
|
||||
fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
|
||||
@ -1027,6 +1049,11 @@ fn dirMakeWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode
|
||||
windows.CloseHandle(sub_dir_handle);
|
||||
}
|
||||
|
||||
const dirMakePath = switch (native_os) {
|
||||
.windows => dirMakePathWindows,
|
||||
else => dirMakePathPosix,
|
||||
};
|
||||
|
||||
fn dirMakePathPosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
_ = t;
|
||||
@ -1045,6 +1072,12 @@ fn dirMakePathWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8,
|
||||
@panic("TODO implement dirMakePathWindows");
|
||||
}
|
||||
|
||||
const dirMakeOpenPath = switch (native_os) {
|
||||
.windows => dirMakeOpenPathWindows,
|
||||
.wasi => dirMakeOpenPathWasi,
|
||||
else => dirMakeOpenPathPosix,
|
||||
};
|
||||
|
||||
fn dirMakeOpenPathPosix(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
@ -1052,11 +1085,11 @@ fn dirMakeOpenPathPosix(
|
||||
options: Io.Dir.OpenOptions,
|
||||
) Io.Dir.MakeOpenPathError!Io.Dir {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = t.io();
|
||||
return dir.openDir(t_io, sub_path, options) catch |err| switch (err) {
|
||||
const t_io = ioBasic(t);
|
||||
return dirOpenDirPosix(t, dir, sub_path, options) catch |err| switch (err) {
|
||||
error.FileNotFound => {
|
||||
try dir.makePath(t_io, sub_path);
|
||||
return dir.openDir(t_io, sub_path, options);
|
||||
return dirOpenDirPosix(t, dir, sub_path, options);
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
@ -1135,7 +1168,7 @@ fn dirMakeOpenPathWindows(
|
||||
// could cause an infinite loop
|
||||
check_dir: {
|
||||
// workaround for windows, see https://github.com/ziglang/zig/issues/16738
|
||||
const fstat = dir.statPath(t.io(), component.path, .{
|
||||
const fstat = dirStatPathWindows(t, dir, component.path, .{
|
||||
.follow_symlinks = options.follow_symlinks,
|
||||
}) catch |stat_err| switch (stat_err) {
|
||||
error.IsDir => break :check_dir,
|
||||
@ -1187,6 +1220,13 @@ fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
|
||||
@panic("TODO implement dirStat");
|
||||
}
|
||||
|
||||
const dirStatPath = switch (native_os) {
|
||||
.linux => dirStatPathLinux,
|
||||
.windows => dirStatPathWindows,
|
||||
.wasi => dirStatPathWasi,
|
||||
else => dirStatPathPosix,
|
||||
};
|
||||
|
||||
fn dirStatPathLinux(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
@ -1275,12 +1315,11 @@ fn dirStatPathWindows(
|
||||
options: Io.Dir.StatPathOptions,
|
||||
) Io.Dir.StatPathError!Io.File.Stat {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = t.io();
|
||||
var file = try dir.openFile(t_io, sub_path, .{
|
||||
const file = try dirOpenFileWindows(t, dir, sub_path, .{
|
||||
.follow_symlinks = options.follow_symlinks,
|
||||
});
|
||||
defer file.close(t_io);
|
||||
return file.stat(t_io);
|
||||
defer windows.CloseHandle(file.handle);
|
||||
return fileStatWindows(t, file);
|
||||
}
|
||||
|
||||
fn dirStatPathWasi(
|
||||
@ -1318,6 +1357,13 @@ fn dirStatPathWasi(
|
||||
}
|
||||
}
|
||||
|
||||
const fileStat = switch (native_os) {
|
||||
.linux => fileStatLinux,
|
||||
.windows => fileStatWindows,
|
||||
.wasi => fileStatWasi,
|
||||
else => fileStatPosix,
|
||||
};
|
||||
|
||||
fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
|
||||
@ -1440,6 +1486,12 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
|
||||
}
|
||||
}
|
||||
|
||||
const dirAccess = switch (native_os) {
|
||||
.windows => dirAccessWindows,
|
||||
.wasi => dirAccessWasi,
|
||||
else => dirAccessPosix,
|
||||
};
|
||||
|
||||
fn dirAccessPosix(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
@ -1589,6 +1641,12 @@ fn dirAccessWindows(
|
||||
}
|
||||
}
|
||||
|
||||
const dirCreateFile = switch (native_os) {
|
||||
.windows => dirCreateFileWindows,
|
||||
.wasi => dirCreateFileWasi,
|
||||
else => dirCreateFilePosix,
|
||||
};
|
||||
|
||||
fn dirCreateFilePosix(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
@ -1827,6 +1885,12 @@ fn dirCreateFileWasi(
|
||||
}
|
||||
}
|
||||
|
||||
const dirOpenFile = switch (native_os) {
|
||||
.windows => dirOpenFileWindows,
|
||||
.wasi => dirOpenFileWasi,
|
||||
else => dirOpenFilePosix,
|
||||
};
|
||||
|
||||
fn dirOpenFilePosix(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
@ -2077,6 +2141,12 @@ fn dirOpenFileWasi(
|
||||
}
|
||||
}
|
||||
|
||||
const dirOpenDir = switch (native_os) {
|
||||
.wasi => dirOpenDirWasi,
|
||||
.haiku => dirOpenDirHaiku,
|
||||
else => dirOpenDirPosix,
|
||||
};
|
||||
|
||||
fn dirOpenDirPosix(
|
||||
userdata: ?*anyopaque,
|
||||
dir: Io.Dir,
|
||||
@ -2320,6 +2390,11 @@ fn fileClose(userdata: ?*anyopaque, file: Io.File) void {
|
||||
posix.close(file.handle);
|
||||
}
|
||||
|
||||
const fileReadStreaming = switch (native_os) {
|
||||
.windows => fileReadStreamingWindows,
|
||||
else => fileReadStreamingPosix,
|
||||
};
|
||||
|
||||
fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
|
||||
@ -2482,6 +2557,11 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
|
||||
}
|
||||
}
|
||||
|
||||
const fileReadPositional = switch (native_os) {
|
||||
.windows => fileReadPositionalWindows,
|
||||
else => fileReadPositionalPosix,
|
||||
};
|
||||
|
||||
fn fileReadPositionalWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
try t.checkCancel();
|
||||
@ -2652,6 +2732,12 @@ fn nowPosix(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp
|
||||
}
|
||||
}
|
||||
|
||||
const now = switch (native_os) {
|
||||
.windows => nowWindows,
|
||||
.wasi => nowWasi,
|
||||
else => nowPosix,
|
||||
};
|
||||
|
||||
fn nowWindows(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
_ = t;
|
||||
@ -2680,6 +2766,13 @@ fn nowWasi(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
|
||||
return .fromNanoseconds(ns);
|
||||
}
|
||||
|
||||
const sleep = switch (native_os) {
|
||||
.windows => sleepWindows,
|
||||
.wasi => sleepWasi,
|
||||
.linux => sleepLinux,
|
||||
else => sleepPosix,
|
||||
};
|
||||
|
||||
fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {
|
||||
@ -2710,9 +2803,10 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
|
||||
fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = ioBasic(t);
|
||||
try t.checkCancel();
|
||||
const ms = ms: {
|
||||
const d = (try timeout.toDurationFromNow(t.io())) orelse
|
||||
const d = (try timeout.toDurationFromNow(t_io)) orelse
|
||||
break :ms std.math.maxInt(windows.DWORD);
|
||||
break :ms std.math.lossyCast(windows.DWORD, d.raw.toMilliseconds());
|
||||
};
|
||||
@ -2721,11 +2815,12 @@ fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
|
||||
fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = ioBasic(t);
|
||||
try t.checkCancel();
|
||||
|
||||
const w = std.os.wasi;
|
||||
|
||||
const clock: w.subscription_clock_t = if (try timeout.toDurationFromNow(t.io())) |d| .{
|
||||
const clock: w.subscription_clock_t = if (try timeout.toDurationFromNow(t_io)) |d| .{
|
||||
.id = clockToWasi(d.clock),
|
||||
.timeout = std.math.lossyCast(u64, d.raw.nanoseconds),
|
||||
.precision = 0,
|
||||
@ -2750,11 +2845,12 @@ fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
|
||||
fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = ioBasic(t);
|
||||
const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;
|
||||
const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;
|
||||
|
||||
var timespec: posix.timespec = t: {
|
||||
const d = (try timeout.toDurationFromNow(t.io())) orelse break :t .{
|
||||
const d = (try timeout.toDurationFromNow(t_io)) orelse break :t .{
|
||||
.sec = std.math.maxInt(sec_type),
|
||||
.nsec = std.math.maxInt(nsec_type),
|
||||
};
|
||||
@ -2919,6 +3015,17 @@ fn netListenIpWindows(
|
||||
};
|
||||
}
|
||||
|
||||
fn netListenIpUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
address: IpAddress,
|
||||
options: IpAddress.ListenOptions,
|
||||
) IpAddress.ListenError!net.Server {
|
||||
_ = userdata;
|
||||
_ = address;
|
||||
_ = options;
|
||||
return error.NetworkDown;
|
||||
}
|
||||
|
||||
fn netListenUnixPosix(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const net.UnixAddress,
|
||||
@ -2965,6 +3072,17 @@ fn netListenUnixWindows(
|
||||
@panic("TODO implement netListenUnixWindows");
|
||||
}
|
||||
|
||||
fn netListenUnixUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const net.UnixAddress,
|
||||
options: net.UnixAddress.ListenOptions,
|
||||
) net.UnixAddress.ListenError!net.Socket.Handle {
|
||||
_ = userdata;
|
||||
_ = address;
|
||||
_ = options;
|
||||
return error.AddressFamilyUnsupported;
|
||||
}
|
||||
|
||||
fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
|
||||
while (true) {
|
||||
try t.checkCancel();
|
||||
@ -3235,6 +3353,17 @@ fn netConnectIpWindows(
|
||||
} };
|
||||
}
|
||||
|
||||
fn netConnectIpUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const IpAddress,
|
||||
options: IpAddress.ConnectOptions,
|
||||
) IpAddress.ConnectError!net.Stream {
|
||||
_ = userdata;
|
||||
_ = address;
|
||||
_ = options;
|
||||
return error.NetworkDown;
|
||||
}
|
||||
|
||||
fn netConnectUnixPosix(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const net.UnixAddress,
|
||||
@ -3263,6 +3392,15 @@ fn netConnectUnixWindows(
|
||||
@panic("TODO implement netConnectUnixWindows");
|
||||
}
|
||||
|
||||
fn netConnectUnixUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const net.UnixAddress,
|
||||
) net.UnixAddress.ConnectError!net.Socket.Handle {
|
||||
_ = userdata;
|
||||
_ = address;
|
||||
return error.AddressFamilyUnsupported;
|
||||
}
|
||||
|
||||
fn netBindIpPosix(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const IpAddress,
|
||||
@ -3330,6 +3468,17 @@ fn netBindIpWindows(
|
||||
};
|
||||
}
|
||||
|
||||
fn netBindIpUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
address: *const IpAddress,
|
||||
options: IpAddress.BindOptions,
|
||||
) IpAddress.BindError!net.Socket {
|
||||
_ = userdata;
|
||||
_ = address;
|
||||
_ = options;
|
||||
return error.NetworkDown;
|
||||
}
|
||||
|
||||
fn openSocketPosix(
|
||||
t: *Threaded,
|
||||
family: posix.sa_family_t,
|
||||
@ -3498,7 +3647,14 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net
|
||||
}
|
||||
}
|
||||
|
||||
fn netAcceptUnavailable(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {
|
||||
_ = userdata;
|
||||
_ = listen_handle;
|
||||
return error.NetworkDown;
|
||||
}
|
||||
|
||||
fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
|
||||
if (!have_networking) return error.NetworkDown;
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
|
||||
var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
|
||||
@ -3560,7 +3716,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
|
||||
}
|
||||
|
||||
fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
|
||||
if (!have_networking) return .{ error.NetworkDown, 0 };
|
||||
if (!have_networking) return error.NetworkDown;
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
_ = t;
|
||||
_ = handle;
|
||||
@ -3568,6 +3724,13 @@ fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8
|
||||
@panic("TODO implement netReadWindows");
|
||||
}
|
||||
|
||||
fn netReadUnavailable(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
|
||||
_ = userdata;
|
||||
_ = fd;
|
||||
_ = data;
|
||||
return error.NetworkDown;
|
||||
}
|
||||
|
||||
fn netSendPosix(
|
||||
userdata: ?*anyopaque,
|
||||
handle: net.Socket.Handle,
|
||||
@ -3612,6 +3775,19 @@ fn netSendWindows(
|
||||
@panic("TODO netSendWindows");
|
||||
}
|
||||
|
||||
fn netSendUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
handle: net.Socket.Handle,
|
||||
messages: []net.OutgoingMessage,
|
||||
flags: net.SendFlags,
|
||||
) struct { ?net.Socket.SendError, usize } {
|
||||
_ = userdata;
|
||||
_ = handle;
|
||||
_ = messages;
|
||||
_ = flags;
|
||||
return .{ error.NetworkDown, 0 };
|
||||
}
|
||||
|
||||
fn netSendOne(
|
||||
t: *Threaded,
|
||||
handle: net.Socket.Handle,
|
||||
@ -3777,6 +3953,7 @@ fn netReceivePosix(
|
||||
) struct { ?net.Socket.ReceiveTimeoutError, usize } {
|
||||
if (!have_networking) return .{ error.NetworkDown, 0 };
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = io(t);
|
||||
|
||||
// recvmmsg is useless, here's why:
|
||||
// * [timeout bug](https://bugzilla.kernel.org/show_bug.cgi?id=75371)
|
||||
@ -3803,7 +3980,7 @@ fn netReceivePosix(
|
||||
var message_i: usize = 0;
|
||||
var data_i: usize = 0;
|
||||
|
||||
const deadline = timeout.toDeadline(t.io()) catch |err| return .{ err, message_i };
|
||||
const deadline = timeout.toDeadline(t_io) catch |err| return .{ err, message_i };
|
||||
|
||||
recv: while (true) {
|
||||
t.checkCancel() catch |err| return .{ err, message_i };
|
||||
@ -3849,7 +4026,7 @@ fn netReceivePosix(
|
||||
|
||||
const max_poll_ms = std.math.maxInt(u31);
|
||||
const timeout_ms: u31 = if (deadline) |d| t: {
|
||||
const duration = d.durationFromNow(t.io()) catch |err| return .{ err, message_i };
|
||||
const duration = d.durationFromNow(t_io) catch |err| return .{ err, message_i };
|
||||
if (duration.raw.nanoseconds <= 0) return .{ error.Timeout, message_i };
|
||||
break :t @intCast(@min(max_poll_ms, duration.raw.toMilliseconds()));
|
||||
} else max_poll_ms;
|
||||
@ -3915,6 +4092,23 @@ fn netReceiveWindows(
|
||||
@panic("TODO implement netReceiveWindows");
|
||||
}
|
||||
|
||||
fn netReceiveUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
handle: net.Socket.Handle,
|
||||
message_buffer: []net.IncomingMessage,
|
||||
data_buffer: []u8,
|
||||
flags: net.ReceiveFlags,
|
||||
timeout: Io.Timeout,
|
||||
) struct { ?net.Socket.ReceiveTimeoutError, usize } {
|
||||
_ = userdata;
|
||||
_ = handle;
|
||||
_ = message_buffer;
|
||||
_ = data_buffer;
|
||||
_ = flags;
|
||||
_ = timeout;
|
||||
return .{ error.NetworkDown, 0 };
|
||||
}
|
||||
|
||||
fn netWritePosix(
|
||||
userdata: ?*anyopaque,
|
||||
fd: net.Socket.Handle,
|
||||
@ -4013,6 +4207,21 @@ fn netWriteWindows(
|
||||
@panic("TODO implement netWriteWindows");
|
||||
}
|
||||
|
||||
fn netWriteUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
handle: net.Socket.Handle,
|
||||
header: []const u8,
|
||||
data: []const []const u8,
|
||||
splat: usize,
|
||||
) net.Stream.Writer.Error!usize {
|
||||
_ = userdata;
|
||||
_ = handle;
|
||||
_ = header;
|
||||
_ = data;
|
||||
_ = splat;
|
||||
return error.NetworkDown;
|
||||
}
|
||||
|
||||
fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"), bytes: []const u8) void {
|
||||
// OS checks ptr addr before length so zero length vectors must be omitted.
|
||||
if (bytes.len == 0) return;
|
||||
@ -4030,6 +4239,12 @@ fn netClose(userdata: ?*anyopaque, handle: net.Socket.Handle) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn netCloseUnavailable(userdata: ?*anyopaque, handle: net.Socket.Handle) void {
|
||||
_ = userdata;
|
||||
_ = handle;
|
||||
unreachable; // How you gonna close something that was impossible to open?
|
||||
}
|
||||
|
||||
fn netInterfaceNameResolve(
|
||||
userdata: ?*anyopaque,
|
||||
name: *const net.Interface.Name,
|
||||
@ -4089,6 +4304,15 @@ fn netInterfaceNameResolve(
|
||||
@panic("unimplemented");
|
||||
}
|
||||
|
||||
fn netInterfaceNameResolveUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
name: *const net.Interface.Name,
|
||||
) net.Interface.Name.ResolveError!net.Interface {
|
||||
_ = userdata;
|
||||
_ = name;
|
||||
return error.InterfaceNotFound;
|
||||
}
|
||||
|
||||
fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
try t.checkCancel();
|
||||
@ -4109,6 +4333,12 @@ fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interfa
|
||||
@panic("unimplemented");
|
||||
}
|
||||
|
||||
fn netInterfaceNameUnavailable(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
|
||||
_ = userdata;
|
||||
_ = interface;
|
||||
return error.Unexpected;
|
||||
}
|
||||
|
||||
fn netLookup(
|
||||
userdata: ?*anyopaque,
|
||||
host_name: HostName,
|
||||
@ -4116,17 +4346,31 @@ fn netLookup(
|
||||
options: HostName.LookupOptions,
|
||||
) void {
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = t.io();
|
||||
const t_io = io(t);
|
||||
resolved.putOneUncancelable(t_io, .{ .end = netLookupFallible(t, host_name, resolved, options) });
|
||||
}
|
||||
|
||||
fn netLookupUnavailable(
|
||||
userdata: ?*anyopaque,
|
||||
host_name: HostName,
|
||||
resolved: *Io.Queue(HostName.LookupResult),
|
||||
options: HostName.LookupOptions,
|
||||
) void {
|
||||
_ = host_name;
|
||||
_ = options;
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const t_io = ioBasic(t);
|
||||
resolved.putOneUncancelable(t_io, .{ .end = error.NetworkDown });
|
||||
}
|
||||
|
||||
fn netLookupFallible(
|
||||
t: *Threaded,
|
||||
host_name: HostName,
|
||||
resolved: *Io.Queue(HostName.LookupResult),
|
||||
options: HostName.LookupOptions,
|
||||
) !void {
|
||||
const t_io = t.io();
|
||||
if (!have_networking) return error.NetworkDown;
|
||||
const t_io = io(t);
|
||||
const name = host_name.bytes;
|
||||
assert(name.len <= HostName.max_len);
|
||||
|
||||
@ -4637,7 +4881,7 @@ fn lookupDnsSearch(
|
||||
resolved: *Io.Queue(HostName.LookupResult),
|
||||
options: HostName.LookupOptions,
|
||||
) HostName.LookupError!void {
|
||||
const t_io = t.io();
|
||||
const t_io = io(t);
|
||||
const rc = HostName.ResolvConf.init(t_io) catch return error.ResolvConfParseFailed;
|
||||
|
||||
// Count dots, suppress search when >=ndots or name ends in
|
||||
@ -4681,7 +4925,7 @@ fn lookupDns(
|
||||
resolved: *Io.Queue(HostName.LookupResult),
|
||||
options: HostName.LookupOptions,
|
||||
) HostName.LookupError!void {
|
||||
const t_io = t.io();
|
||||
const t_io = io(t);
|
||||
const family_records: [2]struct { af: IpAddress.Family, rr: HostName.DnsRecord } = .{
|
||||
.{ .af = .ip6, .rr = .A },
|
||||
.{ .af = .ip4, .rr = .AAAA },
|
||||
@ -4868,7 +5112,7 @@ fn lookupHosts(
|
||||
resolved: *Io.Queue(HostName.LookupResult),
|
||||
options: HostName.LookupOptions,
|
||||
) !void {
|
||||
const t_io = t.io();
|
||||
const t_io = io(t);
|
||||
const file = Io.File.openAbsolute(t_io, "/etc/hosts", .{}) catch |err| switch (err) {
|
||||
error.FileNotFound,
|
||||
error.NotDir,
|
||||
@ -4906,7 +5150,7 @@ fn lookupHostsReader(
|
||||
options: HostName.LookupOptions,
|
||||
reader: *Io.Reader,
|
||||
) error{ ReadFailed, Canceled, UnknownHostName }!void {
|
||||
const t_io = t.io();
|
||||
const t_io = io(t);
|
||||
var addresses_len: usize = 0;
|
||||
var canonical_name: ?HostName = null;
|
||||
while (true) {
|
||||
@ -5374,7 +5618,7 @@ const Wsa = struct {
|
||||
};
|
||||
|
||||
fn initializeWsa(t: *Threaded) error{NetworkDown}!void {
|
||||
const t_io = t.io();
|
||||
const t_io = io(t);
|
||||
const wsa = &t.wsa;
|
||||
wsa.mutex.lockUncancelable(t_io);
|
||||
defer wsa.mutex.unlock(t_io);
|
||||
|
||||
@ -320,7 +320,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
|
||||
const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()});
|
||||
|
||||
var threaded: std.Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
|
||||
const file = try std.fs.cwd().openFile(path, .{});
|
||||
defer file.close();
|
||||
|
||||
@ -649,7 +649,7 @@ pub noinline fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf:
|
||||
/// See `captureCurrentStackTrace` to capture the trace addresses into a buffer instead of printing.
|
||||
pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Writer, tty_config: tty.Config) Writer.Error!void {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
|
||||
if (!std.options.allow_stack_tracing) {
|
||||
tty_config.setColor(writer, .dim) catch {};
|
||||
@ -780,7 +780,7 @@ pub fn writeStackTrace(st: *const StackTrace, writer: *Writer, tty_config: tty.C
|
||||
// We use an independent Io implementation here in case there was a problem
|
||||
// with the application's Io implementation itself.
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
|
||||
// Fetch `st.index` straight away. Aside from avoiding redundant loads, this prevents issues if
|
||||
// `st` is `@errorReturnTrace()` and errors are encountered while writing the stack trace.
|
||||
@ -1602,7 +1602,7 @@ test "manage resources correctly" {
|
||||
};
|
||||
const gpa = std.testing.allocator;
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
var discarding: Io.Writer.Discarding = .init(&.{});
|
||||
var di: SelfInfo = .init;
|
||||
defer di.deinit(gpa);
|
||||
|
||||
@ -340,7 +340,7 @@ pub const OpenSelfExeError = Io.File.OpenSelfExeError;
|
||||
pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
|
||||
if (native_os == .linux or native_os == .serenity or native_os == .windows) {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return .adaptFromNewApi(try Io.File.openSelfExe(io, flags));
|
||||
}
|
||||
// Use of max_path_bytes here is valid as the resulting path is immediately
|
||||
|
||||
@ -849,14 +849,14 @@ pub fn close(self: *Dir) void {
|
||||
/// Deprecated in favor of `Io.Dir.openFile`.
|
||||
pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return .adaptFromNewApi(try Io.Dir.openFile(self.adaptToNewApi(), io, sub_path, flags));
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `Io.Dir.createFile`.
|
||||
pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
const new_file = try Io.Dir.createFile(self.adaptToNewApi(), io, sub_path, flags);
|
||||
return .adaptFromNewApi(new_file);
|
||||
}
|
||||
@ -867,7 +867,7 @@ pub const MakeError = Io.Dir.MakeError;
|
||||
/// Deprecated in favor of `Io.Dir.makeDir`.
|
||||
pub fn makeDir(self: Dir, sub_path: []const u8) MakeError!void {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return Io.Dir.makeDir(.{ .handle = self.fd }, io, sub_path);
|
||||
}
|
||||
|
||||
@ -894,14 +894,14 @@ pub const MakePathError = Io.Dir.MakePathError;
|
||||
/// Deprecated in favor of `Io.Dir.makePathStatus`.
|
||||
pub fn makePathStatus(self: Dir, sub_path: []const u8) MakePathError!MakePathStatus {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return Io.Dir.makePathStatus(.{ .handle = self.fd }, io, sub_path);
|
||||
}
|
||||
|
||||
/// Deprecated in favor of `Io.Dir.makeOpenPath`.
|
||||
pub fn makeOpenPath(dir: Dir, sub_path: []const u8, options: OpenOptions) Io.Dir.MakeOpenPathError!Dir {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return .adaptFromNewApi(try Io.Dir.makeOpenPath(dir.adaptToNewApi(), io, sub_path, options));
|
||||
}
|
||||
|
||||
@ -1070,7 +1070,7 @@ pub const OpenOptions = Io.Dir.OpenOptions;
|
||||
/// Deprecated in favor of `Io.Dir.openDir`.
|
||||
pub fn openDir(self: Dir, sub_path: []const u8, args: OpenOptions) OpenError!Dir {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return .adaptFromNewApi(try Io.Dir.openDir(.{ .handle = self.fd }, io, sub_path, args));
|
||||
}
|
||||
|
||||
@ -1384,7 +1384,7 @@ pub fn readLinkW(self: Dir, sub_path_w: []const u16, buffer: []u8) ![]u8 {
|
||||
/// Deprecated in favor of `Io.Dir.readFile`.
|
||||
pub fn readFile(self: Dir, file_path: []const u8, buffer: []u8) ![]u8 {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return Io.Dir.readFile(.{ .handle = self.fd }, io, file_path, buffer);
|
||||
}
|
||||
|
||||
@ -1437,7 +1437,7 @@ pub fn readFileAllocOptions(
|
||||
comptime sentinel: ?u8,
|
||||
) ReadFileAllocError!(if (sentinel) |s| [:s]align(alignment.toByteUnits()) u8 else []align(alignment.toByteUnits()) u8) {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
|
||||
var file = try dir.openFile(sub_path, .{});
|
||||
defer file.close();
|
||||
@ -1892,7 +1892,7 @@ pub const AccessError = Io.Dir.AccessError;
|
||||
/// Deprecated in favor of `Io.Dir.access`.
|
||||
pub fn access(self: Dir, sub_path: []const u8, options: Io.Dir.AccessOptions) AccessError!void {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return Io.Dir.access(self.adaptToNewApi(), io, sub_path, options);
|
||||
}
|
||||
|
||||
@ -1928,7 +1928,7 @@ pub fn copyFile(
|
||||
options: CopyFileOptions,
|
||||
) CopyFileError!void {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
|
||||
const file = try source_dir.openFile(source_path, .{});
|
||||
var file_reader: File.Reader = .init(.{ .handle = file.handle }, io, &.{});
|
||||
@ -1996,7 +1996,7 @@ pub const StatFileError = File.OpenError || File.StatError || posix.FStatAtError
|
||||
/// Deprecated in favor of `Io.Dir.statPath`.
|
||||
pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return Io.Dir.statPath(.{ .handle = self.fd }, io, sub_path, .{});
|
||||
}
|
||||
|
||||
|
||||
@ -313,7 +313,7 @@ pub const StatError = posix.FStatError;
|
||||
/// Returns `Stat` containing basic information about the `File`.
|
||||
pub fn stat(self: File) StatError!Stat {
|
||||
var threaded: Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
return Io.File.stat(.{ .handle = self.handle }, io);
|
||||
}
|
||||
|
||||
|
||||
@ -1089,7 +1089,7 @@ fn windowsCreateProcessPathExt(
|
||||
// opening function knowing which implementation we are in. Here, we imitate
|
||||
// that scenario.
|
||||
var threaded: std.Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
const io = threaded.ioBasic();
|
||||
|
||||
var dir = dir: {
|
||||
// needs to be null-terminated
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
// 42 is expected by parent; other values result in test failure
|
||||
var exit_code: u8 = 42;
|
||||
@ -6,12 +7,17 @@ var exit_code: u8 = 42;
|
||||
pub fn main() !void {
|
||||
var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
const arena = arena_state.allocator();
|
||||
try run(arena);
|
||||
|
||||
var threaded: std.Io.Threaded = .init(arena);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
|
||||
try run(arena, io);
|
||||
arena_state.deinit();
|
||||
std.process.exit(exit_code);
|
||||
}
|
||||
|
||||
fn run(allocator: std.mem.Allocator) !void {
|
||||
fn run(allocator: std.mem.Allocator, io: Io) !void {
|
||||
var args = try std.process.argsWithAllocator(allocator);
|
||||
defer args.deinit();
|
||||
_ = args.next() orelse unreachable; // skip binary name
|
||||
@ -33,7 +39,8 @@ fn run(allocator: std.mem.Allocator) !void {
|
||||
const hello_stdin = "hello from stdin";
|
||||
var buf: [hello_stdin.len]u8 = undefined;
|
||||
const stdin: std.fs.File = .stdin();
|
||||
const n = try stdin.readAll(&buf);
|
||||
var reader = stdin.reader(io, &.{});
|
||||
const n = try reader.interface.readSliceShort(&buf);
|
||||
if (!std.mem.eql(u8, buf[0..n], hello_stdin)) {
|
||||
testError("stdin: '{s}'; want '{s}'", .{ buf[0..n], hello_stdin });
|
||||
}
|
||||
|
||||
@ -9,6 +9,10 @@ pub fn main() !void {
|
||||
defer arena_instance.deinit();
|
||||
const arena = arena_instance.allocator();
|
||||
|
||||
var threaded: std.Io.Threaded = .init(arena);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
|
||||
const args = try std.process.argsAlloc(arena);
|
||||
|
||||
const exe = args[0];
|
||||
@ -16,7 +20,7 @@ pub fn main() !void {
|
||||
var stdout_buffer: [4096]u8 = undefined;
|
||||
var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer);
|
||||
const stdout = &stdout_writer.interface;
|
||||
var stdin_reader = fs.File.stdin().readerStreaming(&.{});
|
||||
var stdin_reader = fs.File.stdin().readerStreaming(io, &.{});
|
||||
|
||||
const cwd = fs.cwd();
|
||||
|
||||
@ -32,7 +36,7 @@ pub fn main() !void {
|
||||
defer file.close();
|
||||
|
||||
catted_anything = true;
|
||||
var file_reader = file.reader(&.{});
|
||||
var file_reader = file.reader(io, &.{});
|
||||
_ = try stdout.sendFileAll(&file_reader, .unlimited);
|
||||
try stdout.flush();
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
const fs = std.fs;
|
||||
const mem = std.mem;
|
||||
const process = std.process;
|
||||
@ -85,7 +86,7 @@ pub fn main() anyerror!void {
|
||||
} else try argv.append(arg);
|
||||
}
|
||||
|
||||
var threaded: std.Io.Threaded = .init(gpa);
|
||||
var threaded: Io.Threaded = .init(gpa);
|
||||
defer threaded.deinit();
|
||||
const io = threaded.io();
|
||||
|
||||
@ -118,12 +119,13 @@ pub fn main() anyerror!void {
|
||||
.arch = arch,
|
||||
.os_ver = os_ver,
|
||||
};
|
||||
try fetchTarget(allocator, argv.items, sysroot_path, target, version, tmp);
|
||||
try fetchTarget(allocator, io, argv.items, sysroot_path, target, version, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
fn fetchTarget(
|
||||
arena: Allocator,
|
||||
io: Io,
|
||||
args: []const []const u8,
|
||||
sysroot: []const u8,
|
||||
target: Target,
|
||||
@ -194,7 +196,7 @@ fn fetchTarget(
|
||||
var dirs = std.StringHashMap(fs.Dir).init(arena);
|
||||
try dirs.putNoClobber(".", dest_dir);
|
||||
|
||||
var headers_list_file_reader = headers_list_file.reader(&.{});
|
||||
var headers_list_file_reader = headers_list_file.reader(io, &.{});
|
||||
const headers_list_str = try headers_list_file_reader.interface.allocRemaining(arena, .unlimited);
|
||||
const prefix = "/usr/include";
|
||||
|
||||
@ -267,8 +269,8 @@ const Version = struct {
|
||||
|
||||
pub fn format(
|
||||
v: Version,
|
||||
writer: *std.Io.Writer,
|
||||
) std.Io.Writer.Error!void {
|
||||
writer: *Io.Writer,
|
||||
) Io.Writer.Error!void {
|
||||
try writer.print("{d}.{d}.{d}", .{ v.major, v.minor, v.patch });
|
||||
}
|
||||
};
|
||||
|
||||
@ -73,7 +73,7 @@ fn findHeaders(
|
||||
switch (entry.kind) {
|
||||
.directory => {
|
||||
const path = try std.fs.path.join(arena, &.{ prefix, entry.name });
|
||||
var subdir = try dir.openDir(entry.name, .{ .no_follow = true });
|
||||
var subdir = try dir.openDir(entry.name, .{ .follow_symlinks = false });
|
||||
defer subdir.close();
|
||||
try findHeaders(arena, subdir, path, paths);
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user