Compare commits

...

2 commits

Author SHA1 Message Date
9361399898
fix: more zig-0.15 api fixes 2025-09-25 15:12:35 +02:00
0b72daf165
fix: port subprogess to zig-0.15 2025-09-25 15:12:01 +02:00
2 changed files with 45 additions and 15 deletions

View file

@ -4,11 +4,10 @@ const tp = @import("thespian.zig");
pid: ?tp.pid, pid: ?tp.pid,
stdin_behavior: std.process.Child.StdIo, stdin_behavior: std.process.Child.StdIo,
write_buf: [max_chunk_size]u8 = undefined,
const Self = @This(); const Self = @This();
pub const max_chunk_size = 4096 - 32; pub const max_chunk_size = 4096 - 32;
pub const Writer = std.io.Writer(*Self, error{Exit}, write);
pub const BufferedWriter = std.io.BufferedWriter(max_chunk_size, Writer);
pub fn init(a: std.mem.Allocator, argv: tp.message, tag: [:0]const u8, stdin_behavior: std.process.Child.StdIo) !Self { pub fn init(a: std.mem.Allocator, argv: tp.message, tag: [:0]const u8, stdin_behavior: std.process.Child.StdIo) !Self {
return .{ return .{
@ -24,11 +23,48 @@ pub fn deinit(self: *Self) void {
} }
} }
pub fn write(self: *Self, bytes: []const u8) error{Exit}!usize { pub fn write(self: *Self, bytes: []const u8) error{WriteFailed}!usize {
try self.send(bytes); self.send(bytes) catch return error.WriteFailed;
return bytes.len; return bytes.len;
} }
pub const Writer = struct {
subprocess: *Self,
interface: std.Io.Writer,
};
pub fn writer(self: *Self, buffer: []u8) Writer {
return .{
.subprocess = self,
.interface = .{
.vtable = &.{
.drain = drain,
.flush = std.Io.Writer.noopFlush,
.rebase = std.Io.Writer.failingRebase,
},
.buffer = buffer,
},
};
}
fn drain(w: *std.Io.Writer, data_: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
const writer_: *Self.Writer = @alignCast(@fieldParentPtr("interface", w));
std.debug.assert(splat == 0);
if (data_.len == 0) return 0;
var written: usize = 0;
for (data_[0 .. data_.len - 1]) |bytes| {
written += try writer_.subprocess.write(bytes);
}
const pattern_ = data_[data_.len - 1];
switch (pattern_.len) {
0 => return written,
else => for (0..splat) |_| {
written += try writer_.subprocess.write(pattern_);
},
}
return written;
}
pub fn send(self: *const Self, bytes_: []const u8) tp.result { pub fn send(self: *const Self, bytes_: []const u8) tp.result {
if (self.stdin_behavior != .Pipe) return tp.exit("cannot send to closed stdin"); if (self.stdin_behavior != .Pipe) return tp.exit("cannot send to closed stdin");
const pid = if (self.pid) |pid| pid else return tp.exit_error(error.Closed, null); const pid = if (self.pid) |pid| pid else return tp.exit_error(error.Closed, null);
@ -56,14 +92,6 @@ pub fn term(self: *Self) tp.result {
if (self.pid) |pid| if (!pid.expired()) try pid.send(.{"term"}); if (self.pid) |pid| if (!pid.expired()) try pid.send(.{"term"});
} }
pub fn writer(self: *Self) Writer {
return .{ .context = self };
}
pub fn bufferedWriter(self: *Self) BufferedWriter {
return .{ .unbuffered_writer = self.writer() };
}
const Proc = struct { const Proc = struct {
a: std.mem.Allocator, a: std.mem.Allocator,
receiver: Receiver, receiver: Receiver,

View file

@ -183,9 +183,11 @@ pub const message = struct {
return fmtbuf_internal(buf, .{value}); return fmtbuf_internal(buf, .{value});
} }
fn fmtbuf_internal(buf: []u8, value: anytype) !Self { fn fmtbuf_internal(buf: []u8, value: anytype) error{NoSpaceLeft}!Self {
var stream: std.Io.Writer = .fixed(buf); var stream: std.Io.Writer = .fixed(buf);
try cbor.writeValue(&stream, value); cbor.writeValue(&stream, value) catch |e| return switch (e) {
error.WriteFailed => error.NoSpaceLeft,
};
return .{ .buf = stream.buffered() }; return .{ .buf = stream.buffered() };
} }
@ -221,7 +223,7 @@ pub const message = struct {
} }
pub fn format(self: @This(), writer: anytype) std.Io.Writer.Error!void { pub fn format(self: @This(), writer: anytype) std.Io.Writer.Error!void {
return cbor.toJsonWriter(self.buf, writer, .{}); return cbor.toJsonWriter(self.buf, writer, .{}) catch error.WriteFailed;
} }
}; };