authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-08 20:08:40-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-08 20:08:40-04:00
logcbda0fa78c37dd84821061309469c85a2281174c
tree5fd46a2d100cba00659bfef98c5ff2483e61c812
parentacd8f6ef184c031f672fa6d6a690d831344de4b4

basic tcp server working when used with netcat


3 files changed, 44 insertions(+), 8 deletions(-)

std/event.zig+14-8
...@@ -5,11 +5,12 @@ const mem = std.mem;...@@ -5,11 +5,12 @@ const mem = std.mem;
5const posix = std.os.posix;5const posix = std.os.posix;
66
7pub const TcpServer = struct {7pub const TcpServer = struct {
8 handleRequestFn: async(&mem.Allocator) fn (&TcpServer, &const std.net.Address, &const std.os.File) void,8 handleRequestFn: async<&mem.Allocator> fn (&TcpServer, &const std.net.Address, &const std.os.File) void,
99
10 loop: &Loop,10 loop: &Loop,
11 sockfd: i32,11 sockfd: i32,
12 accept_coro: ?promise,12 accept_coro: ?promise,
13 listen_address: std.net.Address,
1314
14 waiting_for_emfile_node: PromiseNode,15 waiting_for_emfile_node: PromiseNode,
1516
...@@ -28,18 +29,20 @@ pub const TcpServer = struct {...@@ -28,18 +29,20 @@ pub const TcpServer = struct {
28 .accept_coro = null,29 .accept_coro = null,
29 .handleRequestFn = undefined,30 .handleRequestFn = undefined,
30 .waiting_for_emfile_node = undefined,31 .waiting_for_emfile_node = undefined,
32 .listen_address = undefined,
31 };33 };
32 }34 }
3335
34 pub fn listen(self: &TcpServer, address: &const std.net.Address,36 pub fn listen(self: &TcpServer, address: &const std.net.Address,
35 handleRequestFn: async(&mem.Allocator) fn (&TcpServer, &const std.net.Address, &const std.os.File)void) !void37 handleRequestFn: async<&mem.Allocator> fn (&TcpServer, &const std.net.Address, &const std.os.File)void) !void
36 {38 {
37 self.handleRequestFn = handleRequestFn;39 self.handleRequestFn = handleRequestFn;
3840
39 try std.os.posixBind(self.sockfd, &address.sockaddr);41 try std.os.posixBind(self.sockfd, &address.sockaddr);
40 try std.os.posixListen(self.sockfd, posix.SOMAXCONN);42 try std.os.posixListen(self.sockfd, posix.SOMAXCONN);
43 self.listen_address = std.net.Address.initPosix(try std.os.posixGetSockName(self.sockfd));
4144
42 self.accept_coro = try async(self.loop.allocator) (TcpServer.handler)(self); // TODO #81745 self.accept_coro = try async<self.loop.allocator> TcpServer.handler(self);
43 errdefer cancel ??self.accept_coro;46 errdefer cancel ??self.accept_coro;
4447
45 try self.loop.addFd(self.sockfd, ??self.accept_coro);48 try self.loop.addFd(self.sockfd, ??self.accept_coro);
...@@ -60,10 +63,7 @@ pub const TcpServer = struct {...@@ -60,10 +63,7 @@ pub const TcpServer = struct {
60 posix.SOCK_NONBLOCK | posix.SOCK_CLOEXEC)) |accepted_fd|63 posix.SOCK_NONBLOCK | posix.SOCK_CLOEXEC)) |accepted_fd|
61 {64 {
62 var socket = std.os.File.openHandle(accepted_fd);65 var socket = std.os.File.openHandle(accepted_fd);
63 // TODO #81766 _ = async<self.loop.allocator> self.handleRequestFn(self, accepted_addr, socket) catch |err| switch (err) {
64 _ = async(self.loop.allocator) (self.handleRequestFn)(self, accepted_addr,
65 socket) catch |err| switch (err)
66 {
67 error.OutOfMemory => {67 error.OutOfMemory => {
68 socket.close();68 socket.close();
69 continue;69 continue;
...@@ -161,7 +161,7 @@ test "listen on a port, send bytes, receive bytes" {...@@ -161,7 +161,7 @@ test "listen on a port, send bytes, receive bytes" {
161161
162 const Self = this;162 const Self = this;
163163
164 async(&mem.Allocator) fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address,164 async<&mem.Allocator> fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address,
165 _socket: &const std.os.File) void165 _socket: &const std.os.File) void
166 {166 {
167 const self = @fieldParentPtr(Self, "tcp_server", tcp_server);167 const self = @fieldParentPtr(Self, "tcp_server", tcp_server);
...@@ -198,5 +198,11 @@ test "listen on a port, send bytes, receive bytes" {...@@ -198,5 +198,11 @@ test "listen on a port, send bytes, receive bytes" {
198 defer server.tcp_server.deinit();198 defer server.tcp_server.deinit();
199 try server.tcp_server.listen(addr, MyServer.handler);199 try server.tcp_server.listen(addr, MyServer.handler);
200200
201 var stderr_file = try std.io.getStdErr();
202 var stderr_stream = &std.io.FileOutStream.init(&stderr_file).stream;
203 try stderr_stream.print("\nlistening at ");
204 try server.tcp_server.listen_address.format(stderr_stream);
205 try stderr_stream.print("\n");
206
201 loop.run();207 loop.run();
202}208}
std/net.zig+6
...@@ -35,6 +35,12 @@ pub const Address = struct {...@@ -35,6 +35,12 @@ pub const Address = struct {
35 };35 };
36 }36 }
3737
38 pub fn initPosix(addr: &const posix.sockaddr) Address {
39 return Address {
40 .sockaddr = *addr,
41 };
42 }
43
38 pub fn format(self: &const Address, out_stream: var) !void {44 pub fn format(self: &const Address, out_stream: var) !void {
39 switch (self.sockaddr.in.family) {45 switch (self.sockaddr.in.family) {
40 posix.AF_INET => {46 posix.AF_INET => {
std/os/index.zig+24
...@@ -2229,3 +2229,27 @@ pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usiz...@@ -2229,3 +2229,27 @@ pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usiz
2229 }2229 }
2230 }2230 }
2231}2231}
2232
2233pub const PosixGetSockNameError = error {
2234 /// Insufficient resources were available in the system to perform the operation.
2235 SystemResources,
2236
2237 Unexpected,
2238};
2239
2240pub fn posixGetSockName(sockfd: i32) PosixGetSockNameError!posix.sockaddr {
2241 var addr: posix.sockaddr = undefined;
2242 var addrlen: posix.socklen_t = @sizeOf(posix.sockaddr);
2243 const rc = posix.getsockname(sockfd, &addr, &addrlen);
2244 const err = posix.getErrno(rc);
2245 switch (err) {
2246 0 => return addr,
2247 else => return unexpectedErrorPosix(err),
2248
2249 posix.EBADF => unreachable,
2250 posix.EFAULT => unreachable,
2251 posix.EINVAL => unreachable,
2252 posix.ENOTSOCK => unreachable,
2253 posix.ENOBUFS => return PosixGetSockNameError.SystemResources,
2254 }
2255}