Skip to content

Commit d4c0350

Browse files
committed
zigcoro added, p2p stab
1 parent b1cb0bc commit d4c0350

26 files changed

+20189
-1
lines changed

deps/libuv/build.wren

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ var libuv = Fn.new { |b, args|
2828
b.install("include/uv", headers)
2929
b.installLibConfig(zig.libConfig(b, "uv", {
3030
"ldflags": os["ldflags"] || [],
31+
"libc": true,
32+
}))
33+
}
34+
35+
var zig = Fn.new { |b, args|
36+
var zig = b.deptool("//toolchains/zig")
37+
b.srcGlob("zig/*.zig")
38+
b.install("zig", zig.moduleConfig(b, {
39+
"root": b.src("zig/uv.zig"),
40+
"modules": {
41+
"zigcoro": b.dep("//deps/zigcoro"),
42+
},
43+
"c_deps": [zig.cDep(b.dep(":libuv"), "uv")],
3144
}))
3245
}
3346

deps/libuv/zig/cimport.zig

Lines changed: 16218 additions & 0 deletions
Large diffs are not rendered by default.

deps/libuv/zig/common.zig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const std = @import("std");
2+
const uv = @import("uv.zig");
3+
const coro = @import("zigcoro");
4+
5+
pub const uv_close_cb = struct {
6+
frame: coro.Frame,
7+
8+
pub fn init(self: *@This(), handle: *uv.uv_handle_t) void {
9+
uv.setHandleData(handle, self);
10+
self.frame = coro.xframe();
11+
}
12+
13+
pub fn cb(handle: [*c]uv.uv_handle_t) callconv(.C) void {
14+
const self = uv.getHandleData(handle, @This());
15+
coro.xresume(self.frame);
16+
}
17+
};

deps/libuv/zig/file.zig

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
const std = @import("std");
2+
const uv = @import("uv.zig");
3+
const coro = @import("zigcoro");
4+
5+
const log = std.log.scoped(.uvzig);
6+
7+
pub const File = struct {
8+
loop: *uv.uv_loop_t,
9+
fd: c_int,
10+
11+
const Data = struct {
12+
frame: coro.Frame,
13+
done: bool = false,
14+
fn init() @This() {
15+
return .{ .frame = coro.xframe() };
16+
}
17+
};
18+
19+
pub fn open(loop: *uv.uv_loop_t, path: [:0]const u8, flags: c_int, mode: c_int) !@This() {
20+
log.debug("open {s} flags={b} mode={o}", .{ path, flags, mode });
21+
var data = Data.init();
22+
var req = uv.uv_fs_t{};
23+
defer uv.uv_fs_req_cleanup(&req);
24+
uv.setReqData(&req, &data);
25+
try uv.check(uv.uv_fs_open(loop, &req, path, flags, mode, xresume));
26+
while (!data.done) coro.xsuspend();
27+
try uv.check(req.result);
28+
29+
return .{
30+
.loop = loop,
31+
.fd = @intCast(req.result),
32+
};
33+
}
34+
35+
pub fn close(self: @This()) void {
36+
var req = uv.uv_fs_t{};
37+
defer uv.uv_fs_req_cleanup(&req);
38+
var data = Data.init();
39+
uv.setReqData(&req, &data);
40+
uv.check(uv.uv_fs_close(self.loop, &req, self.fd, xresume)) catch {};
41+
coro.xsuspend();
42+
}
43+
44+
fn xresume(req: [*c]uv.uv_fs_t) callconv(.C) void {
45+
const data = uv.getReqData(req, Data);
46+
data.done = true;
47+
coro.xresume(data.frame);
48+
}
49+
50+
const Error = error{
51+
Read,
52+
Write,
53+
} || uv.Error;
54+
const Reader = std.io.Reader(@This(), Error, read);
55+
56+
fn read(self: @This(), buf: []u8) Error!usize {
57+
log.debug("read {d}", .{buf.len});
58+
var req = uv.uv_fs_t{};
59+
defer uv.uv_fs_req_cleanup(&req);
60+
var data = Data.init();
61+
uv.setReqData(&req, &data);
62+
var uvbuf = uv.newbuf(buf);
63+
try uv.check(uv.uv_fs_read(self.loop, &req, self.fd, &uvbuf, 1, -1, xresume));
64+
coro.xsuspend();
65+
if (req.result < 0) {
66+
return Error.Read;
67+
} else {
68+
return @intCast(req.result);
69+
}
70+
}
71+
72+
const Writer = std.io.Writer(@This(), Error, write);
73+
74+
fn write(self: @This(), buf: []const u8) Error!usize {
75+
log.debug("write", .{});
76+
var req = uv.uv_fs_t{};
77+
defer uv.uv_fs_req_cleanup(&req);
78+
var data = Data.init();
79+
uv.setReqData(&req, &data);
80+
var uvbuf = uv.newbuf(@constCast(buf));
81+
try uv.check(uv.uv_fs_write(self.loop, &req, self.fd, &uvbuf, 1, -1, xresume));
82+
coro.xsuspend();
83+
if (req.result < 0) {
84+
return Error.Write;
85+
} else {
86+
return @intCast(req.result);
87+
}
88+
}
89+
90+
pub fn writer(self: @This()) Writer {
91+
return .{ .context = self };
92+
}
93+
94+
pub fn reader(self: @This()) Reader {
95+
return .{ .context = self };
96+
}
97+
98+
pub fn stat(self: @This()) !uv.uv_stat_t {
99+
var req = uv.uv_fs_t{};
100+
defer uv.uv_fs_req_cleanup(&req);
101+
var data = Data.init();
102+
uv.setReqData(&req, &data);
103+
try uv.check(uv.uv_fs_fstat(self.loop, &req, self.fd, xresume));
104+
coro.xsuspend();
105+
try uv.check(req.result);
106+
return uv.uv_fs_get_statbuf(&req).*;
107+
}
108+
109+
pub fn fsync(self: @This()) !void {
110+
var req = uv.uv_fs_t{};
111+
defer uv.uv_fs_req_cleanup(&req);
112+
var data = Data.init();
113+
uv.setReqData(&req, &data);
114+
try uv.check(uv.uv_fs_fsync(self.loop, &req, self.fd, xresume));
115+
coro.xsuspend();
116+
try uv.check(req.result);
117+
}
118+
119+
pub fn sendfile(self: @This(), dst: c_int, src_offset: ?usize, n: usize) !usize {
120+
log.debug("send {d}", .{n});
121+
var req = uv.uv_fs_t{};
122+
defer uv.uv_fs_req_cleanup(&req);
123+
var data = Data.init();
124+
uv.setReqData(&req, &data);
125+
126+
try uv.check(uv.uv_fs_sendfile(self.loop, &req, dst, self.fd, @intCast(src_offset orelse 0), n, xresume));
127+
coro.xsuspend();
128+
129+
try uv.check(req.result);
130+
return @intCast(req.result);
131+
}
132+
133+
// TODO:
134+
// chown
135+
// utime
136+
// chmod
137+
// datasync
138+
};
139+
140+
pub const fs = struct {
141+
pub fn mkdir(loop: *uv.uv_loop_t, path: [:0]const u8, mode: c_int) !void {
142+
var req: uv_fs_cb = undefined;
143+
req.init();
144+
defer req.deinit();
145+
try uv.check(uv.uv_fs_mkdir(loop, &req.req, path.ptr, mode, uv_fs_cb.cb));
146+
coro.xsuspend();
147+
}
148+
149+
pub fn mkdtemp(loop: *uv.uv_loop_t, tpl: [:0]const u8, out: []u8) ![:0]const u8 {
150+
var req: uv_fs_cb = undefined;
151+
req.init();
152+
defer req.deinit();
153+
try uv.check(uv.uv_fs_mkdtemp(loop, &req.req, tpl.ptr, uv_fs_cb.cb));
154+
coro.xsuspend();
155+
const n = std.mem.len(req.req.path);
156+
if (n >= out.len) return error.BufTooSmall;
157+
std.mem.copyForwards(u8, out, req.req.path[0..n]);
158+
out[n] = 0;
159+
return out[0..n :0];
160+
}
161+
162+
const TmpFileInfo = struct {
163+
path: ?[:0]const u8,
164+
fd: uv.uv_file,
165+
};
166+
pub fn mkstemp(loop: *uv.uv_loop_t, tpl: [:0]const u8, out: ?[]u8) !TmpFileInfo {
167+
var req: uv_fs_cb = undefined;
168+
req.init();
169+
defer req.deinit();
170+
try uv.check(uv.uv_fs_mkstemp(loop, &req.req, tpl.ptr, uv_fs_cb.cb));
171+
coro.xsuspend();
172+
var info = TmpFileInfo{ .path = null, .fd = @intCast(req.req.result) };
173+
if (out) |buf| {
174+
const n = std.mem.len(req.req.path);
175+
if (n >= buf.len) return error.BufTooSmall;
176+
std.mem.copyForwards(u8, buf, req.req.path[0..n]);
177+
buf[n] = 0;
178+
info.path = buf[0..n :0];
179+
}
180+
return info;
181+
}
182+
};
183+
184+
const uv_fs_cb = struct {
185+
frame: coro.Frame,
186+
req: uv.uv_fs_t,
187+
188+
fn init(self: *@This()) void {
189+
uv.setReqData(&self.req, self);
190+
self.frame = coro.xframe();
191+
}
192+
193+
fn deinit(self: @This()) void {
194+
uv.uv_fs_req_cleanup(@constCast(&self.req));
195+
}
196+
197+
fn cb(req: [*c]uv.uv_fs_t) callconv(.C) void {
198+
const self = uv.getReqData(req, @This());
199+
coro.xresume(self.frame);
200+
}
201+
};

deps/libuv/zig/process.zig

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
const std = @import("std");
2+
const uv = @import("uv.zig");
3+
const coro = @import("zigcoro");
4+
5+
const log = std.log.scoped(.uvzig);
6+
7+
pub const Process = struct {
8+
pub const StdioOpts = union(enum) {
9+
inherit_fd: uv.uv_file,
10+
inherit_stream: *uv.uv_stream_t,
11+
create_pipe: struct {
12+
pipe: *uv.uv_stream_t,
13+
flow: enum { RO, WO, RW },
14+
nonblock: bool = false,
15+
},
16+
};
17+
const RunOpts = struct {
18+
env: ?[][:0]const u8 = null,
19+
cwd: ?[:0]const u8 = null,
20+
stdio: [3]?StdioOpts = .{ null, null, null },
21+
};
22+
23+
pub const Status = struct {
24+
exit_status: i64,
25+
term_signal: c_int,
26+
};
27+
28+
pub fn run(loop: *uv.uv_loop_t, alloc: std.mem.Allocator, args: [][:0]const u8, opts: RunOpts) !Status {
29+
log.debug("process run", .{});
30+
var handle = uv.uv_process_t{};
31+
defer {
32+
var closer = Closer.init();
33+
closer.close(@ptrCast(&handle));
34+
}
35+
var data = Data.init();
36+
uv.setHandleData(&handle, &data);
37+
38+
const cargs = try alloc.alloc([*c]const u8, args.len + 1);
39+
defer alloc.free(cargs);
40+
cargs[args.len] = null;
41+
for (args, 0..) |a, i| {
42+
log.debug("- {s}", .{a});
43+
cargs[i] = a;
44+
}
45+
46+
var cenv: ?[][*c]const u8 = null;
47+
if (opts.env) |env| {
48+
cenv = try alloc.alloc([*c]const u8, env.len + 1);
49+
cenv.?[env.len] = null;
50+
for (env, 0..) |e, i| cenv.?[i] = e;
51+
}
52+
defer if (cenv) |e| alloc.free(e);
53+
54+
var stdio: [3]uv.uv_stdio_container_t = undefined;
55+
for (0..3) |i| {
56+
if (opts.stdio[i]) |sopt| {
57+
switch (sopt) {
58+
.inherit_fd => |fd| {
59+
log.debug("stdio[{d}]=.inherit_fd={d}", .{ i, fd });
60+
stdio[i].flags = uv.UV_INHERIT_FD;
61+
stdio[i].data.fd = fd;
62+
},
63+
.inherit_stream => |s| {
64+
log.debug("stdio[{d}]=.inherit_stream={*}", .{ i, s });
65+
stdio[i].flags = uv.UV_INHERIT_STREAM;
66+
stdio[i].data.stream = s;
67+
},
68+
.create_pipe => |opt| {
69+
log.debug("stdio[{d}]=.create_pipe {s}", .{ i, @tagName(opt.flow) });
70+
var flags = uv.UV_CREATE_PIPE;
71+
if (opt.nonblock) flags |= uv.UV_NONBLOCK_PIPE;
72+
flags |= switch (opt.flow) {
73+
.RO => uv.UV_READABLE_PIPE,
74+
.WO => uv.UV_WRITABLE_PIPE,
75+
.RW => uv.UV_READABLE_PIPE | uv.UV_WRITABLE_PIPE,
76+
};
77+
78+
stdio[i].flags = @intCast(flags);
79+
stdio[i].data.stream = opt.pipe;
80+
},
81+
}
82+
} else {
83+
stdio[i].flags = uv.UV_IGNORE;
84+
}
85+
}
86+
87+
var o = uv.uv_process_options_t{};
88+
o.file = cargs[0];
89+
o.args = @constCast(@ptrCast(cargs.ptr));
90+
o.env = if (cenv) |env| @constCast(@ptrCast(env.ptr)) else null;
91+
o.cwd = if (opts.cwd) |cwd| cwd.ptr else null;
92+
o.stdio_count = 3;
93+
o.stdio = &stdio;
94+
o.exit_cb = Data.onExit;
95+
96+
try uv.check(uv.uv_spawn(loop, &handle, &o));
97+
log.debug("process spawned pid={d}", .{handle.pid});
98+
coro.xsuspend();
99+
log.debug("process exited pid={d} code={d}", .{ handle.pid, data.out.?.exit_status });
100+
101+
return data.out.?;
102+
}
103+
104+
const Data = struct {
105+
frame: coro.Frame,
106+
out: ?Status = null,
107+
fn init() @This() {
108+
return .{ .frame = coro.xframe() };
109+
}
110+
111+
fn onExit(process: [*c]uv.uv_process_t, exit_status: i64, term_signal: c_int) callconv(.C) void {
112+
const data = uv.getHandleData(process, Data);
113+
data.out = .{
114+
.exit_status = exit_status,
115+
.term_signal = term_signal,
116+
};
117+
coro.xresume(data.frame);
118+
}
119+
};
120+
};
121+
122+
const Closer = struct {
123+
frame: coro.Frame,
124+
fn init() @This() {
125+
return .{ .frame = coro.xframe() };
126+
}
127+
fn close(self: *@This(), handle: [*c]uv.uv_handle_t) void {
128+
uv.setHandleData(handle, self);
129+
uv.uv_close(handle, onClose);
130+
coro.xsuspend();
131+
}
132+
fn onClose(handle: [*c]uv.uv_handle_t) callconv(.C) void {
133+
const data = uv.getHandleData(handle, @This());
134+
coro.xresume(data.frame);
135+
}
136+
};

0 commit comments

Comments
 (0)