mirror of
https://github.com/oven-sh/bun
synced 2026-02-18 06:41:50 +00:00
155 lines
4.4 KiB
Zig
155 lines
4.4 KiB
Zig
const std = @import("std");
|
|
const bun = @import("root").bun;
|
|
const uv = bun.windows.libuv;
|
|
|
|
const log = bun.Output.scoped(.PipeSource, false);
|
|
|
|
pub const Source = union(enum) {
|
|
pipe: *Pipe,
|
|
tty: *Tty,
|
|
file: *File,
|
|
|
|
const Pipe = uv.Pipe;
|
|
const Tty = uv.uv_tty_t;
|
|
pub const File = struct {
|
|
fs: uv.fs_t,
|
|
iov: uv.uv_buf_t,
|
|
file: uv.uv_file,
|
|
};
|
|
|
|
pub fn isClosed(this: Source) bool {
|
|
switch (this) {
|
|
.pipe => |pipe| return pipe.isClosed(),
|
|
.tty => |tty| return tty.isClosed(),
|
|
.file => |file| return file.file == -1,
|
|
}
|
|
}
|
|
|
|
pub fn isActive(this: Source) bool {
|
|
switch (this) {
|
|
.pipe => |pipe| return pipe.isActive(),
|
|
.tty => |tty| return tty.isActive(),
|
|
.file => return true,
|
|
}
|
|
}
|
|
|
|
pub fn getHandle(this: Source) *uv.Handle {
|
|
switch (this) {
|
|
.pipe => return @ptrCast(this.pipe),
|
|
.tty => return @ptrCast(this.tty),
|
|
.file => unreachable,
|
|
}
|
|
}
|
|
pub fn toStream(this: Source) *uv.uv_stream_t {
|
|
switch (this) {
|
|
.pipe => return @ptrCast(this.pipe),
|
|
.tty => return @ptrCast(this.tty),
|
|
.file => unreachable,
|
|
}
|
|
}
|
|
|
|
pub fn getFd(this: Source) bun.FileDescriptor {
|
|
switch (this) {
|
|
.pipe => return this.pipe.fd(),
|
|
.tty => return this.tty.fd(),
|
|
.file => return bun.FDImpl.fromUV(this.file.file).encode(),
|
|
}
|
|
}
|
|
|
|
pub fn setData(this: Source, data: ?*anyopaque) void {
|
|
switch (this) {
|
|
.pipe => this.pipe.data = data,
|
|
.tty => this.tty.data = data,
|
|
.file => this.file.fs.data = data,
|
|
}
|
|
}
|
|
|
|
pub fn getData(this: Source) ?*anyopaque {
|
|
switch (this) {
|
|
.pipe => |pipe| return pipe.data,
|
|
.tty => |tty| return tty.data,
|
|
.file => |file| return file.fs.data,
|
|
}
|
|
}
|
|
|
|
pub fn ref(this: Source) void {
|
|
switch (this) {
|
|
.pipe => this.pipe.ref(),
|
|
.tty => this.tty.ref(),
|
|
.file => return,
|
|
}
|
|
}
|
|
|
|
pub fn unref(this: Source) void {
|
|
switch (this) {
|
|
.pipe => this.pipe.unref(),
|
|
.tty => this.tty.unref(),
|
|
.file => return,
|
|
}
|
|
}
|
|
|
|
pub fn hasRef(this: Source) bool {
|
|
switch (this) {
|
|
.pipe => return this.pipe.hasRef(),
|
|
.tty => return this.tty.hasRef(),
|
|
.file => return false,
|
|
}
|
|
}
|
|
|
|
pub fn openPipe(loop: *uv.Loop, fd: bun.FileDescriptor, ipc: bool) bun.JSC.Maybe(*Source.Pipe) {
|
|
log("openPipe (fd = {})", .{fd});
|
|
const pipe = bun.default_allocator.create(Source.Pipe) catch bun.outOfMemory();
|
|
|
|
switch (pipe.init(loop, ipc)) {
|
|
.err => |err| {
|
|
return .{ .err = err };
|
|
},
|
|
else => {},
|
|
}
|
|
|
|
const file_fd = bun.uvfdcast(fd);
|
|
|
|
return switch (pipe.open(file_fd)) {
|
|
.err => |err| .{
|
|
.err = err,
|
|
},
|
|
.result => .{
|
|
.result = pipe,
|
|
},
|
|
};
|
|
}
|
|
|
|
pub fn openTty(loop: *uv.Loop, fd: bun.FileDescriptor) bun.JSC.Maybe(*Source.Tty) {
|
|
log("openTTY (fd = {})", .{fd});
|
|
const tty = bun.default_allocator.create(Source.Tty) catch bun.outOfMemory();
|
|
|
|
return switch (tty.init(loop, bun.uvfdcast(fd))) {
|
|
.err => |err| .{ .err = err },
|
|
.result => .{ .result = tty },
|
|
};
|
|
}
|
|
|
|
pub fn openFile(fd: bun.FileDescriptor) bun.JSC.Maybe(*Source.File) {
|
|
log("openFile (fd = {})", .{fd});
|
|
const file = bun.default_allocator.create(Source.File) catch bun.outOfMemory();
|
|
|
|
file.* = std.mem.zeroes(Source.File);
|
|
file.file = bun.uvfdcast(fd);
|
|
return .{ .result = file };
|
|
}
|
|
|
|
pub fn open(loop: *uv.Loop, fd: bun.FileDescriptor) bun.JSC.Maybe(Source) {
|
|
log("open (fd = {})", .{fd});
|
|
const rc = bun.windows.GetFileType(fd.cast());
|
|
if (rc == bun.windows.FILE_TYPE_CHAR) .{ .tty = switch (openTty(loop, fd)) {
|
|
.result => |tty| return .{ .result = .{ .tty = tty } },
|
|
.err => |err| return .{ .err = err },
|
|
} } else .{
|
|
.file = switch (openFile(fd)) {
|
|
.result => |file| return .{ .result = .{ .file = file } },
|
|
.err => |err| return .{ .err = err },
|
|
},
|
|
};
|
|
}
|
|
};
|