Commit 7f46672193

LemonBoy <thatlemon@gmail.com>
2020-10-28 10:03:23
More fixups for Windows targets
* Use closeSocket on sockets instead of plain old close, the latter doesn't work on them. * Use winsocket2 everywhere, mingw has no BSD sockets.
1 parent 1ea0d40
Changed files (3)
lib/std/net/test.zig
@@ -148,6 +148,8 @@ test "listen on a port, send bytes, receive bytes" {
     const localhost = try net.Address.parseIp("127.0.0.1", 8080);
 
     var server = net.StreamServer.init(.{});
+    defer server.deinit();
+
     try server.listen(localhost);
 
     const S = struct {
lib/std/net.zig
@@ -606,7 +606,7 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
         os.SOCK_STREAM | os.SOCK_CLOEXEC | opt_non_block,
         0,
     );
-    errdefer os.close(sockfd);
+    errdefer os.closeSocket(sockfd);
 
     var addr = try std.net.Address.initUnix(path);
 
@@ -625,7 +625,7 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
 fn if_nametoindex(name: []const u8) !u32 {
     var ifr: os.ifreq = undefined;
     var sockfd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM | os.SOCK_CLOEXEC, 0);
-    defer os.close(sockfd);
+    defer os.closeSocket(sockfd);
 
     std.mem.copy(u8, &ifr.ifrn.name, name);
     ifr.ifrn.name[name.len] = 0;
@@ -673,7 +673,7 @@ pub fn tcpConnectToAddress(address: Address) !fs.File {
     const sock_flags = os.SOCK_STREAM | nonblock |
         (if (builtin.os.tag == .windows) 0 else os.SOCK_CLOEXEC);
     const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);
-    errdefer os.close(sockfd);
+    errdefer os.closeSocket(sockfd);
 
     if (std.io.is_async) {
         const loop = std.event.Loop.instance orelse return error.WouldBlock;
@@ -908,7 +908,7 @@ fn linuxLookupName(
         var prefixlen: i32 = 0;
         const sock_flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC;
         if (os.socket(addr.addr.any.family, sock_flags, os.IPPROTO_UDP)) |fd| syscalls: {
-            defer os.close(fd);
+            defer os.closeSocket(fd);
             os.connect(fd, da, dalen) catch break :syscalls;
             key |= DAS_USABLE;
             os.getsockname(fd, sa, &salen) catch break :syscalls;
@@ -1388,7 +1388,7 @@ fn resMSendRc(
         },
         else => |e| return e,
     };
-    defer os.close(fd);
+    defer os.closeSocket(fd);
     try os.bind(fd, &sa.any, sl);
 
     // Past this point, there are no errors. Each individual query will
@@ -1610,7 +1610,7 @@ pub const StreamServer = struct {
         const sockfd = try os.socket(address.any.family, sock_flags, proto);
         self.sockfd = sockfd;
         errdefer {
-            os.close(sockfd);
+            os.closeSocket(sockfd);
             self.sockfd = null;
         }
 
@@ -1634,7 +1634,7 @@ pub const StreamServer = struct {
     /// not listening.
     pub fn close(self: *StreamServer) void {
         if (self.sockfd) |fd| {
-            os.close(fd);
+            os.closeSocket(fd);
             self.sockfd = null;
             self.listen_address = undefined;
         }
lib/std/os.zig
@@ -2687,6 +2687,14 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
     }
 }
 
+pub fn closeSocket(sock: socket_t) void {
+    if (builtin.os.tag == .windows) {
+        windows.closesocket(sock) catch unreachable;
+    } else {
+        close(sock);
+    }
+}
+
 pub const BindError = error{
     /// The address is protected, and the user is not the superuser.
     /// For UNIX domain sockets: Search permission is denied on  a  component
@@ -2731,8 +2739,8 @@ pub const BindError = error{
 
 /// addr is `*const T` where T is one of the sockaddr
 pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!void {
-    const rc = system.bind(sock, addr, len);
     if (builtin.os.tag == .windows) {
+        const rc = windows.bind(sock, addr, len);
         if (rc == windows.ws2_32.SOCKET_ERROR) {
             switch (windows.ws2_32.WSAGetLastError()) {
                 .WSANOTINITIALISED => unreachable, // not initialized WSA
@@ -2750,6 +2758,7 @@ pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!voi
         }
         return;
     } else {
+        const rc = system.bind(sock, addr, len);
         switch (errno(rc)) {
             0 => return,
             EACCES => return error.AccessDenied,
@@ -2800,8 +2809,8 @@ const ListenError = error{
 } || UnexpectedError;
 
 pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
-    const rc = system.listen(sock, backlog);
     if (builtin.os.tag == .windows) {
+        const rc = windows.listen(sock, backlog);
         if (rc == windows.ws2_32.SOCKET_ERROR) {
             switch (windows.ws2_32.WSAGetLastError()) {
                 .WSANOTINITIALISED => unreachable, // not initialized WSA
@@ -2818,6 +2827,7 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
         }
         return;
     } else {
+        const rc = system.listen(sock, backlog);
         switch (errno(rc)) {
             0 => return,
             EADDRINUSE => return error.AddressInUse,
@@ -2905,6 +2915,8 @@ pub fn accept(
     const accepted_sock = while (true) {
         const rc = if (have_accept4)
             system.accept4(sock, addr, addr_size, flags)
+        else if (builtin.os.tag == .windows)
+            windows.accept(sock, addr, addr_size)
         else
             system.accept(sock, addr, addr_size);
 
@@ -3077,8 +3089,8 @@ pub const GetSockNameError = error{
 } || UnexpectedError;
 
 pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
-    const rc = system.getsockname(sock, addr, addrlen);
     if (builtin.os.tag == .windows) {
+        const rc = windows.getsockname(sock, addr, addrlen);
         if (rc == windows.ws2_32.SOCKET_ERROR) {
             switch (windows.ws2_32.WSAGetLastError()) {
                 .WSANOTINITIALISED => unreachable,
@@ -3091,6 +3103,7 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock
         }
         return;
     } else {
+        const rc = system.getsockname(sock, addr, addrlen);
         switch (errno(rc)) {
             0 => return,
             else => |err| return unexpectedErrno(err),