authorgravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-02 23:53:29+02:00
committergravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-02 23:53:29+02:00
logd80554cedf313bc78f0419faf84776bd987263df
treebefd1953ca09d583118b4b845e582f743f587f1d
parent12ce6eb8f65e6de5920c713cf2767e4b8ba0f1d3

Made some changes and additions to the networking to make it work on windows.


4 files changed, 201 insertions(+), 110 deletions(-)

lib/std/os.zig+156-106
...@@ -2657,14 +2657,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -2657,14 +2657,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
2657 // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into windows-analagous operations2657 // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into windows-analagous operations
2658 const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC);2658 const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC);
2659 const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0;2659 const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0;
2660 const rc = windows.ws2_32.WSASocketW(@intCast(c_int, domain), @intCast(c_int, filtered_sock_type), @intCast(c_int, protocol), null, 0, flags);2660 const rc = try windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags);
2661 if (rc == windows.ws2_32.INVALID_SOCKET) switch (windows.ws2_32.WSAGetLastError()) {
2662 .WSAEMFILE => return error.ProcessFdQuotaExceeded,
2663 .WSAENOBUFS => return error.SystemResources,
2664 .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
2665 .WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
2666 else => |err| return windows.unexpectedWSAError(err),
2667 };
2668 errdefer windows.closesocket(rc) catch unreachable;2661 errdefer windows.closesocket(rc) catch unreachable;
2669 if ((socket_type & SOCK_NONBLOCK) != 0) {2662 if ((socket_type & SOCK_NONBLOCK) != 0) {
2670 var mode: c_ulong = 1; // nonblocking2663 var mode: c_ulong = 1; // nonblocking
...@@ -2741,24 +2734,34 @@ pub const BindError = error{...@@ -2741,24 +2734,34 @@ pub const BindError = error{
2741} || UnexpectedError;2734} || UnexpectedError;
27422735
2743/// addr is `*const T` where T is one of the sockaddr2736/// addr is `*const T` where T is one of the sockaddr
2744pub fn bind(sockfd: fd_t, addr: *const sockaddr, len: socklen_t) BindError!void {2737pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!void {
2745 const rc = system.bind(sockfd, addr, len);2738 const rc = system.bind(sock, addr, len);
2746 switch (errno(rc)) {2739 if (builtin.os.tag == .windows) {
2747 0 => return,2740 if (rc == windows.ws2_32.SOCKET_ERROR) {
2748 EACCES => return error.AccessDenied,2741 switch (windows.ws2_32.WSAGetLastError()) {
2749 EADDRINUSE => return error.AddressInUse,2742 // TODO: handle errors
2750 EBADF => unreachable, // always a race condition if this error is returned2743 else => |err| return windows.unexpectedWSAError(err),
2751 EINVAL => unreachable, // invalid parameters2744 }
2752 ENOTSOCK => unreachable, // invalid `sockfd`2745 }
2753 EADDRNOTAVAIL => return error.AddressNotAvailable,2746 return;
2754 EFAULT => unreachable, // invalid `addr` pointer2747 } else {
2755 ELOOP => return error.SymLinkLoop,2748 switch (errno(rc)) {
2756 ENAMETOOLONG => return error.NameTooLong,2749 0 => return,
2757 ENOENT => return error.FileNotFound,2750 EACCES => return error.AccessDenied,
2758 ENOMEM => return error.SystemResources,2751 EADDRINUSE => return error.AddressInUse,
2759 ENOTDIR => return error.NotDir,2752 EBADF => unreachable, // always a race condition if this error is returned
2760 EROFS => return error.ReadOnlyFileSystem,2753 EINVAL => unreachable, // invalid parameters
2761 else => |err| return unexpectedErrno(err),2754 ENOTSOCK => unreachable, // invalid `sockfd`
2755 EADDRNOTAVAIL => return error.AddressNotAvailable,
2756 EFAULT => unreachable, // invalid `addr` pointer
2757 ELOOP => return error.SymLinkLoop,
2758 ENAMETOOLONG => return error.NameTooLong,
2759 ENOENT => return error.FileNotFound,
2760 ENOMEM => return error.SystemResources,
2761 ENOTDIR => return error.NotDir,
2762 EROFS => return error.ReadOnlyFileSystem,
2763 else => |err| return unexpectedErrno(err),
2764 }
2762 }2765 }
2763}2766}
27642767
...@@ -2777,15 +2780,25 @@ const ListenError = error{...@@ -2777,15 +2780,25 @@ const ListenError = error{
2777 OperationNotSupported,2780 OperationNotSupported,
2778} || UnexpectedError;2781} || UnexpectedError;
27792782
2780pub fn listen(sockfd: fd_t, backlog: u32) ListenError!void {2783pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
2781 const rc = system.listen(sockfd, backlog);2784 const rc = system.listen(sock, backlog);
2782 switch (errno(rc)) {2785 if (builtin.os.tag == .windows) {
2783 0 => return,2786 if (rc == windows.ws2_32.SOCKET_ERROR) {
2784 EADDRINUSE => return error.AddressInUse,2787 switch (windows.ws2_32.WSAGetLastError()) {
2785 EBADF => unreachable,2788 // TODO: handle errors
2786 ENOTSOCK => return error.FileDescriptorNotASocket,2789 else => |err| return windows.unexpectedWSAError(err),
2787 EOPNOTSUPP => return error.OperationNotSupported,2790 }
2788 else => |err| return unexpectedErrno(err),2791 }
2792 return;
2793 } else {
2794 switch (errno(rc)) {
2795 0 => return,
2796 EADDRINUSE => return error.AddressInUse,
2797 EBADF => unreachable,
2798 ENOTSOCK => return error.FileDescriptorNotASocket,
2799 EOPNOTSUPP => return error.OperationNotSupported,
2800 else => |err| return unexpectedErrno(err),
2801 }
2789 }2802 }
2790}2803}
27912804
...@@ -2822,19 +2835,19 @@ pub const AcceptError = error{...@@ -2822,19 +2835,19 @@ pub const AcceptError = error{
2822pub fn accept(2835pub fn accept(
2823 /// This argument is a socket that has been created with `socket`, bound to a local address2836 /// This argument is a socket that has been created with `socket`, bound to a local address
2824 /// with `bind`, and is listening for connections after a `listen`.2837 /// with `bind`, and is listening for connections after a `listen`.
2825 sockfd: fd_t,2838 sock: socket_t,
2826 /// This argument is a pointer to a sockaddr structure. This structure is filled in with the2839 /// This argument is a pointer to a sockaddr structure. This structure is filled in with the
2827 /// address of the peer socket, as known to the communications layer. The exact format of the2840 /// address of the peer socket, as known to the communications layer. The exact format of the
2828 /// address returned addr is determined by the socket's address family (see `socket` and the2841 /// address returned addr is determined by the socket's address family (see `socket` and the
2829 /// respective protocol man pages).2842 /// respective protocol man pages).
2830 addr: *sockaddr,2843 addr: ?*sockaddr,
2831 /// This argument is a value-result argument: the caller must initialize it to contain the2844 /// This argument is a value-result argument: the caller must initialize it to contain the
2832 /// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size2845 /// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size
2833 /// of the peer address.2846 /// of the peer address.
2834 ///2847 ///
2835 /// The returned address is truncated if the buffer provided is too small; in this case, `addr_size`2848 /// The returned address is truncated if the buffer provided is too small; in this case, `addr_size`
2836 /// will return a value greater than was supplied to the call.2849 /// will return a value greater than was supplied to the call.
2837 addr_size: *socklen_t,2850 addr_size: ?*socklen_t,
2838 /// The following values can be bitwise ORed in flags to obtain different behavior:2851 /// The following values can be bitwise ORed in flags to obtain different behavior:
2839 /// * `SOCK_NONBLOCK` - Set the `O_NONBLOCK` file status flag on the open file description (see `open`)2852 /// * `SOCK_NONBLOCK` - Set the `O_NONBLOCK` file status flag on the open file description (see `open`)
2840 /// referred to by the new file descriptor. Using this flag saves extra calls to `fcntl` to achieve2853 /// referred to by the new file descriptor. Using this flag saves extra calls to `fcntl` to achieve
...@@ -2842,46 +2855,58 @@ pub fn accept(...@@ -2842,46 +2855,58 @@ pub fn accept(
2842 /// * `SOCK_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the2855 /// * `SOCK_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the
2843 /// description of the `O_CLOEXEC` flag in `open` for reasons why this may be useful.2856 /// description of the `O_CLOEXEC` flag in `open` for reasons why this may be useful.
2844 flags: u32,2857 flags: u32,
2845) AcceptError!fd_t {2858) AcceptError!socket_t {
2846 const have_accept4 = comptime !std.Target.current.isDarwin();2859 const have_accept4 = comptime !(std.Target.current.isDarwin() or builtin.os.tag == .windows);
2847 assert(0 == (flags & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC))); // Unsupported flag(s)2860 assert(0 == (flags & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC))); // Unsupported flag(s)
28482861
2849 while (true) {2862 const accepted_sock = while (true) {
2850 const rc = if (have_accept4)2863 const rc = if (have_accept4)
2851 system.accept4(sockfd, addr, addr_size, flags)2864 system.accept4(sock, addr, addr_size, flags)
2852 else2865 else
2853 system.accept(sockfd, addr, addr_size);2866 system.accept(sock, addr, addr_size);
28542867
2855 switch (errno(rc)) {2868 if (builtin.os.tag == .windows) {
2856 0 => {2869 if (rc == windows.ws2_32.INVALID_SOCKET) {
2857 const fd = @intCast(fd_t, rc);2870 switch (windows.ws2_32.WSAGetLastError()) {
2858 if (!have_accept4) {2871 // TODO: handle errors
2859 try setSockFlags(fd, flags);2872 else => |err| return windows.unexpectedWSAError(err),
2860 }2873 }
2861 return fd;
2862 },
2863 EINTR => continue,
2864 EAGAIN => if (std.event.Loop.instance) |loop| {
2865 loop.waitUntilFdReadable(sockfd);
2866 continue;
2867 } else {2874 } else {
2868 return error.WouldBlock;2875 break rc;
2869 },2876 }
2870 EBADF => unreachable, // always a race condition2877 } else {
2871 ECONNABORTED => return error.ConnectionAborted,2878 switch (errno(rc)) {
2872 EFAULT => unreachable,2879 0 => {
2873 EINVAL => unreachable,2880 break @intCast(socket_t, rc);
2874 ENOTSOCK => unreachable,2881 },
2875 EMFILE => return error.ProcessFdQuotaExceeded,2882 EINTR => continue,
2876 ENFILE => return error.SystemFdQuotaExceeded,2883 EAGAIN => if (std.event.Loop.instance) |loop| {
2877 ENOBUFS => return error.SystemResources,2884 loop.waitUntilFdReadable(sock);
2878 ENOMEM => return error.SystemResources,2885 continue;
2879 EOPNOTSUPP => unreachable,2886 } else {
2880 EPROTO => return error.ProtocolFailure,2887 return error.WouldBlock;
2881 EPERM => return error.BlockedByFirewall,2888 },
2882 else => |err| return unexpectedErrno(err),2889 EBADF => unreachable, // always a race condition
2890 ECONNABORTED => return error.ConnectionAborted,
2891 EFAULT => unreachable,
2892 EINVAL => unreachable,
2893 ENOTSOCK => unreachable,
2894 EMFILE => return error.ProcessFdQuotaExceeded,
2895 ENFILE => return error.SystemFdQuotaExceeded,
2896 ENOBUFS => return error.SystemResources,
2897 ENOMEM => return error.SystemResources,
2898 EOPNOTSUPP => unreachable,
2899 EPROTO => return error.ProtocolFailure,
2900 EPERM => return error.BlockedByFirewall,
2901 else => |err| return unexpectedErrno(err),
2902 }
2883 }2903 }
2904 } else unreachable;
2905
2906 if (!have_accept4) {
2907 try setSockFlags(accepted_sock, flags);
2884 }2908 }
2909 return accepted_sock;
2885}2910}
28862911
2887pub const EpollCreateError = error{2912pub const EpollCreateError = error{
...@@ -2997,16 +3022,27 @@ pub const GetSockNameError = error{...@@ -2997,16 +3022,27 @@ pub const GetSockNameError = error{
2997 SystemResources,3022 SystemResources,
2998} || UnexpectedError;3023} || UnexpectedError;
29993024
3000pub fn getsockname(sockfd: fd_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {3025pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
3001 switch (errno(system.getsockname(sockfd, addr, addrlen))) {3026 const rc = system.getsockname(sock, addr, addrlen);
3002 0 => return,3027 if (builtin.os.tag == .windows) {
3003 else => |err| return unexpectedErrno(err),3028 if (rc == windows.ws2_32.SOCKET_ERROR) {
3029 switch (windows.ws2_32.WSAGetLastError()) {
3030 // TODO: handle errors
3031 else => |err| return windows.unexpectedWSAError(err),
3032 }
3033 }
3034 return;
3035 } else {
3036 switch (errno(rc)) {
3037 0 => return,
3038 else => |err| return unexpectedErrno(err),
30043039
3005 EBADF => unreachable, // always a race condition3040 EBADF => unreachable, // always a race condition
3006 EFAULT => unreachable,3041 EFAULT => unreachable,
3007 EINVAL => unreachable, // invalid parameters3042 EINVAL => unreachable, // invalid parameters
3008 ENOTSOCK => unreachable,3043 ENOTSOCK => unreachable,
3009 ENOBUFS => return error.SystemResources,3044 ENOBUFS => return error.SystemResources,
3045 }
3010 }3046 }
3011}3047}
30123048
...@@ -3052,9 +3088,9 @@ pub const ConnectError = error{...@@ -3052,9 +3088,9 @@ pub const ConnectError = error{
3052} || UnexpectedError;3088} || UnexpectedError;
30533089
3054/// Initiate a connection on a socket.3090/// Initiate a connection on a socket.
3055pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {3091pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {
3056 if (builtin.os.tag == .windows) {3092 if (builtin.os.tag == .windows) {
3057 const rc = windows.ws2_32.connect(sockfd, sock_addr, len);3093 const rc = windows.ws2_32.connect(sock, sock_addr, len);
3058 if (rc == 0) return;3094 if (rc == 0) return;
3059 switch (windows.ws2_32.WSAGetLastError()) {3095 switch (windows.ws2_32.WSAGetLastError()) {
3060 .WSAEADDRINUSE => return error.AddressInUse,3096 .WSAEADDRINUSE => return error.AddressInUse,
...@@ -3077,7 +3113,7 @@ pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) Con...@@ -3077,7 +3113,7 @@ pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) Con
3077 }3113 }
30783114
3079 while (true) {3115 while (true) {
3080 switch (errno(system.connect(sockfd, sock_addr, len))) {3116 switch (errno(system.connect(sock, sock_addr, len))) {
3081 0 => return,3117 0 => return,
3082 EACCES => return error.PermissionDenied,3118 EACCES => return error.PermissionDenied,
3083 EPERM => return error.PermissionDenied,3119 EPERM => return error.PermissionDenied,
...@@ -3086,8 +3122,8 @@ pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) Con...@@ -3086,8 +3122,8 @@ pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) Con
3086 EAFNOSUPPORT => return error.AddressFamilyNotSupported,3122 EAFNOSUPPORT => return error.AddressFamilyNotSupported,
3087 EAGAIN, EINPROGRESS => {3123 EAGAIN, EINPROGRESS => {
3088 const loop = std.event.Loop.instance orelse return error.WouldBlock;3124 const loop = std.event.Loop.instance orelse return error.WouldBlock;
3089 loop.waitUntilFdWritable(sockfd);3125 loop.waitUntilFdWritable(sock);
3090 return getsockoptError(sockfd);3126 return getsockoptError(sock);
3091 },3127 },
3092 EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.3128 EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.
3093 EBADF => unreachable, // sockfd is not a valid open file descriptor.3129 EBADF => unreachable, // sockfd is not a valid open file descriptor.
...@@ -3928,32 +3964,46 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {...@@ -3928,32 +3964,46 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
3928 }3964 }
3929}3965}
39303966
3931fn setSockFlags(fd: fd_t, flags: u32) !void {3967fn setSockFlags(sock: socket_t, flags: u32) !void {
3932 if ((flags & SOCK_CLOEXEC) != 0) {3968 if ((flags & SOCK_CLOEXEC) != 0) {
3933 var fd_flags = fcntl(fd, F_GETFD, 0) catch |err| switch (err) {3969 if (builtin.os.tag == .windows) {
3934 error.FileBusy => unreachable,3970 // TODO: Find out if this is supported for sockets
3935 error.Locked => unreachable,3971 } else {
3936 else => |e| return e,3972 var fd_flags = fcntl(sock, F_GETFD, 0) catch |err| switch (err) {
3937 };3973 error.FileBusy => unreachable,
3938 fd_flags |= FD_CLOEXEC;3974 error.Locked => unreachable,
3939 _ = fcntl(fd, F_SETFD, fd_flags) catch |err| switch (err) {3975 else => |e| return e,
3940 error.FileBusy => unreachable,3976 };
3941 error.Locked => unreachable,3977 fd_flags |= FD_CLOEXEC;
3942 else => |e| return e,3978 _ = fcntl(sock, F_SETFD, fd_flags) catch |err| switch (err) {
3943 };3979 error.FileBusy => unreachable,
3980 error.Locked => unreachable,
3981 else => |e| return e,
3982 };
3983 }
3944 }3984 }
3945 if ((flags & SOCK_NONBLOCK) != 0) {3985 if ((flags & SOCK_NONBLOCK) != 0) {
3946 var fl_flags = fcntl(fd, F_GETFL, 0) catch |err| switch (err) {3986 if (builtin.os.tag == .windows) {
3947 error.FileBusy => unreachable,3987 var mode: c_ulong = 1;
3948 error.Locked => unreachable,3988 if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) {
3949 else => |e| return e,3989 switch (windows.ws2_32.WSAGetLastError()) {
3950 };3990 // TODO: handle errors
3951 fl_flags |= O_NONBLOCK;3991 else => |err| return windows.unexpectedWSAError(err),
3952 _ = fcntl(fd, F_SETFL, fl_flags) catch |err| switch (err) {3992 }
3953 error.FileBusy => unreachable,3993 }
3954 error.Locked => unreachable,3994 } else {
3955 else => |e| return e,3995 var fl_flags = fcntl(sock, F_GETFL, 0) catch |err| switch (err) {
3956 };3996 error.FileBusy => unreachable,
3997 error.Locked => unreachable,
3998 else => |e| return e,
3999 };
4000 fl_flags |= O_NONBLOCK;
4001 _ = fcntl(sock, F_SETFL, fl_flags) catch |err| switch (err) {
4002 error.FileBusy => unreachable,
4003 error.Locked => unreachable,
4004 else => |e| return e,
4005 };
4006 }
3957 }4007 }
3958}4008}
39594009
lib/std/os/bits/windows.zig+1-1
...@@ -172,7 +172,7 @@ pub const AT_REMOVEDIR = 0x200;...@@ -172,7 +172,7 @@ pub const AT_REMOVEDIR = 0x200;
172172
173pub const in_port_t = u16;173pub const in_port_t = u16;
174pub const sa_family_t = ws2_32.ADDRESS_FAMILY;174pub const sa_family_t = ws2_32.ADDRESS_FAMILY;
175pub const socklen_t = u32;175pub const socklen_t = ws2_32.socklen_t;
176176
177pub const sockaddr = ws2_32.sockaddr;177pub const sockaddr = ws2_32.sockaddr;
178pub const sockaddr_in = ws2_32.sockaddr_in;178pub const sockaddr_in = ws2_32.sockaddr_in;
lib/std/os/windows.zig+27
...@@ -1153,6 +1153,14 @@ pub fn WSASocketW(...@@ -1153,6 +1153,14 @@ pub fn WSASocketW(
1153 return rc;1153 return rc;
1154}1154}
11551155
1156pub fn bind(s: ws2_32.SOCKET, name: *const ws2_32.sockaddr, namelen: ws2_32.socklen_t) i32 {
1157 return ws2_32.bind(s, name, namelen);
1158}
1159
1160pub fn listen(s: ws2_32.SOCKET, backlog: u31) i32 {
1161 return ws2_32.listen(s, backlog);
1162}
1163
1156pub fn closesocket(s: ws2_32.SOCKET) !void {1164pub fn closesocket(s: ws2_32.SOCKET) !void {
1157 switch (ws2_32.closesocket(s)) {1165 switch (ws2_32.closesocket(s)) {
1158 0 => {},1166 0 => {},
...@@ -1163,6 +1171,25 @@ pub fn closesocket(s: ws2_32.SOCKET) !void {...@@ -1163,6 +1171,25 @@ pub fn closesocket(s: ws2_32.SOCKET) !void {
1163 }1171 }
1164}1172}
11651173
1174pub fn accept(s: ws2_32.SOCKET, name: ?*ws2_32.sockaddr, namelen: ?*ws2_32.socklen_t) ws2_32.SOCKET {
1175 assert((name == null) == (namelen == null));
1176 if (namelen) |name_length| {
1177 var os_namelen: c_int = name_length.*;
1178 const sock = ws2_32.accept(s, name, &os_namelen);
1179 name_length.* = @intCast(ws2_32.socklen_t, os_namelen);
1180 return sock;
1181 } else {
1182 return ws2_32.accept(s, null, null);
1183 }
1184}
1185
1186pub fn getsockname(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.socklen_t) i32 {
1187 var os_namelen: c_int = namelen.*;
1188 const rc = ws2_32.getsockname(s, name, &os_namelen);
1189 namelen.* = @intCast(ws2_32.socklen_t, os_namelen);
1190 return rc;
1191}
1192
1166pub fn WSAIoctl(1193pub fn WSAIoctl(
1167 s: ws2_32.SOCKET,1194 s: ws2_32.SOCKET,
1168 dwIoControlCode: DWORD,1195 dwIoControlCode: DWORD,
lib/std/os/windows/ws2_32.zig+17-3
...@@ -116,7 +116,7 @@ pub const WSAOVERLAPPED_COMPLETION_ROUTINE = fn (dwError: DWORD, cbTransferred:...@@ -116,7 +116,7 @@ pub const WSAOVERLAPPED_COMPLETION_ROUTINE = fn (dwError: DWORD, cbTransferred:
116pub const ADDRESS_FAMILY = u16;116pub const ADDRESS_FAMILY = u16;
117117
118// Microsoft use the signed c_int for this, but it should never be negative118// Microsoft use the signed c_int for this, but it should never be negative
119const socklen_t = u32;119pub const socklen_t = u31;
120120
121pub const AF_UNSPEC = 0;121pub const AF_UNSPEC = 0;
122pub const AF_UNIX = 1;122pub const AF_UNIX = 1;
...@@ -734,12 +734,21 @@ pub extern "ws2_32" fn WSAIoctl(...@@ -734,12 +734,21 @@ pub extern "ws2_32" fn WSAIoctl(
734pub extern "ws2_32" fn accept(734pub extern "ws2_32" fn accept(
735 s: SOCKET,735 s: SOCKET,
736 addr: ?*sockaddr,736 addr: ?*sockaddr,
737 addrlen: socklen_t,737 addrlen: ?*c_int,
738) callconv(.Stdcall) SOCKET;738) callconv(.Stdcall) SOCKET;
739pub extern "ws2_32" fn bind(
740 s: SOCKET,
741 addr: ?*const sockaddr,
742 addrlen: c_int,
743) callconv(.Stdcall) c_int;
739pub extern "ws2_32" fn connect(744pub extern "ws2_32" fn connect(
740 s: SOCKET,745 s: SOCKET,
741 name: *const sockaddr,746 name: *const sockaddr,
742 namelen: socklen_t,747 namelen: c_int,
748) callconv(.Stdcall) c_int;
749pub extern "ws2_32" fn listen(
750 s: SOCKET,
751 backlog: c_int,
743) callconv(.Stdcall) c_int;752) callconv(.Stdcall) c_int;
744pub extern "ws2_32" fn WSARecv(753pub extern "ws2_32" fn WSARecv(
745 s: SOCKET,754 s: SOCKET,
...@@ -795,3 +804,8 @@ pub extern "ws2_32" fn ioctlsocket(...@@ -795,3 +804,8 @@ pub extern "ws2_32" fn ioctlsocket(
795 cmd: c_long,804 cmd: c_long,
796 argp: *c_ulong,805 argp: *c_ulong,
797) callconv(.Stdcall) c_int;806) callconv(.Stdcall) c_int;
807pub extern "ws2_32" fn getsockname(
808 s: SOCKET,
809 name: *sockaddr,
810 namelen: *c_int,
811) callconv(.Stdcall) c_int;