aboutsummaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
Diffstat (limited to 'std')
-rw-r--r--std/event/tcp.zig50
-rw-r--r--std/os/index.zig4
-rw-r--r--std/os/linux/index.zig10
3 files changed, 59 insertions, 5 deletions
diff --git a/std/event/tcp.zig b/std/event/tcp.zig
index 5715e46a62..c1e6e891cd 100644
--- a/std/event/tcp.zig
+++ b/std/event/tcp.zig
@@ -110,13 +110,61 @@ pub const Server = struct {
}
};
+pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {
+ const sockfd = try std.os.posixSocket(
+ posix.AF_UNIX,
+ posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK,
+ 0,
+ );
+ errdefer std.os.close(sockfd);
+
+ var sock_addr = posix.sockaddr{
+ .un = posix.sockaddr_un{
+ .family = posix.AF_UNIX,
+ .path = undefined,
+ },
+ };
+
+ if (path.len > @typeOf(sock_addr.un.path).len) return error.NameTooLong;
+ mem.copy(u8, sock_addr.un.path[0..], path);
+ const size = @intCast(u32, @sizeOf(posix.sa_family_t) + path.len);
+ try std.os.posixConnectAsync(sockfd, &sock_addr, size);
+ try await try async loop.linuxWaitFd(sockfd, posix.EPOLLIN | posix.EPOLLOUT | posix.EPOLLET);
+ try std.os.posixGetSockOptConnectError(sockfd);
+
+ return sockfd;
+}
+
+pub async fn socketRead(loop: *std.event.Loop, fd: i32, buffer: []u8) !void {
+ while (true) {
+ return std.os.posixRead(fd, buffer) catch |err| switch (err) {
+ error.WouldBlock => {
+ try await try async loop.linuxWaitFd(fd, std.os.posix.EPOLLET | std.os.posix.EPOLLIN);
+ continue;
+ },
+ else => return err,
+ };
+ }
+}
+pub async fn socketWrite(loop: *std.event.Loop, fd: i32, buffer: []const u8) !void {
+ while (true) {
+ return std.os.posixWrite(fd, buffer) catch |err| switch (err) {
+ error.WouldBlock => {
+ try await try async loop.linuxWaitFd(fd, std.os.posix.EPOLLET | std.os.posix.EPOLLOUT);
+ continue;
+ },
+ else => return err,
+ };
+ }
+}
+
pub async fn connect(loop: *Loop, _address: *const std.net.Address) !std.os.File {
var address = _address.*; // TODO https://github.com/ziglang/zig/issues/733
const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK, posix.PROTO_tcp);
errdefer std.os.close(sockfd);
- try std.os.posixConnectAsync(sockfd, &address.os_addr);
+ try std.os.posixConnectAsync(sockfd, &address.os_addr, @sizeOf(posix.sockaddr_in));
try await try async loop.linuxWaitFd(sockfd, posix.EPOLLIN | posix.EPOLLOUT | posix.EPOLLET);
try std.os.posixGetSockOptConnectError(sockfd);
diff --git a/std/os/index.zig b/std/os/index.zig
index d86ab119df..1ce9bd7278 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -2677,9 +2677,9 @@ pub fn posixConnect(sockfd: i32, sockaddr: *const posix.sockaddr) PosixConnectEr
/// Same as posixConnect except it is for blocking socket file descriptors.
/// It expects to receive EINPROGRESS.
-pub fn posixConnectAsync(sockfd: i32, sockaddr: *const posix.sockaddr) PosixConnectError!void {
+pub fn posixConnectAsync(sockfd: i32, sockaddr: *const c_void, len: u32) PosixConnectError!void {
while (true) {
- const rc = posix.connect(sockfd, sockaddr, @sizeOf(posix.sockaddr));
+ const rc = posix.connect(sockfd, sockaddr, len);
const err = posix.getErrno(rc);
switch (err) {
0, posix.EINPROGRESS => return,
diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig
index c369921e14..6323c89dda 100644
--- a/std/os/linux/index.zig
+++ b/std/os/linux/index.zig
@@ -1094,6 +1094,7 @@ pub const in_port_t = u16;
pub const sa_family_t = u16;
pub const socklen_t = u32;
+/// This intentionally only has ip4 and ip6
pub const sockaddr = extern union {
in: sockaddr_in,
in6: sockaddr_in6,
@@ -1114,6 +1115,11 @@ pub const sockaddr_in6 = extern struct {
scope_id: u32,
};
+pub const sockaddr_un = extern struct {
+ family: sa_family_t,
+ path: [108]u8,
+};
+
pub const iovec = extern struct {
iov_base: [*]u8,
iov_len: usize,
@@ -1148,8 +1154,8 @@ pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize {
return syscall3(SYS_sendmsg, @intCast(usize, fd), @ptrToInt(msg), flags);
}
-pub fn connect(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
- return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len));
+pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
+ return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), len);
}
pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {