From 21ca54f56013897573ba5aeb67d946deaa162200 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:31:24 +1100 Subject: [PATCH 01/14] std: add alertable argument for windows.WaitForSingleObject --- lib/std/child_process.zig | 2 +- lib/std/os/windows.zig | 4 ++-- lib/std/os/windows/kernel32.zig | 2 ++ lib/std/thread.zig | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 36621758b2..e8cffaa1b9 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -235,7 +235,7 @@ pub const ChildProcess = struct { } fn waitUnwrappedWindows(self: *ChildProcess) !void { - const result = windows.WaitForSingleObject(self.handle, windows.INFINITE); + const result = windows.WaitForSingleObjectEx(self.handle, windows.INFINITE, false); self.term = @as(SpawnError!Term, x: { var exit_code: windows.DWORD = undefined; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 5fc18accb8..2f51fc67a8 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -171,8 +171,8 @@ pub const WaitForSingleObjectError = error{ Unexpected, }; -pub fn WaitForSingleObject(handle: HANDLE, milliseconds: DWORD) WaitForSingleObjectError!void { - switch (kernel32.WaitForSingleObject(handle, milliseconds)) { +pub fn WaitForSingleObjectEx(handle: HANDLE, milliseconds: DWORD, alertable: bool) WaitForSingleObjectError!void { + switch (kernel32.WaitForSingleObjectEx(handle, milliseconds, @boolToInt(alertable))) { WAIT_ABANDONED => return error.WaitAbandoned, WAIT_OBJECT_0 => return, WAIT_TIMEOUT => return error.WaitTimeOut, diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 30c4cf4785..3f14196d11 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -205,6 +205,8 @@ pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL; pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; +pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD; + pub extern "kernel32" stdcallcc fn WriteFile( in_hFile: HANDLE, in_lpBuffer: [*]const u8, diff --git a/lib/std/thread.zig b/lib/std/thread.zig index fe976a6839..9f4cb3613a 100644 --- a/lib/std/thread.zig +++ b/lib/std/thread.zig @@ -99,7 +99,7 @@ pub const Thread = struct { os.munmap(self.data.memory); }, .windows => { - windows.WaitForSingleObject(self.data.handle, windows.INFINITE) catch unreachable; + windows.WaitForSingleObjectEx(self.data.handle, windows.INFINITE, false) catch unreachable; windows.CloseHandle(self.data.handle); windows.HeapFree(self.data.heap_handle, 0, self.data.alloc_start); }, From 78c0d33eb75ed7985df39607cf0e0d2ae94ef98a Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:37:29 +1100 Subject: [PATCH 02/14] std: add WaitForMultipleObjects for windows --- lib/std/os/windows.zig | 28 ++++++++++++++++++++++++++++ lib/std/os/windows/bits.zig | 3 +++ lib/std/os/windows/kernel32.zig | 10 ++++++++++ 3 files changed, 41 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 2f51fc67a8..593a9ec29f 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -183,6 +183,34 @@ pub fn WaitForSingleObjectEx(handle: HANDLE, milliseconds: DWORD, alertable: boo } } +pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, milliseconds: DWORD, alertable: bool) !u32 { + assert(handles.len < MAXIMUM_WAIT_OBJECTS); + const nCount: DWORD = @intCast(DWORD, handles.len); + switch (kernel32.WaitForMultipleObjectsEx( + nCount, + handles.ptr, + @boolToInt(waitAll), + milliseconds, + @boolToInt(alertable), + )) { + WAIT_OBJECT_0...WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS => |n| { + const handle_index = n - WAIT_OBJECT_0; + assert(handle_index < nCount); + return handle_index; + }, + WAIT_ABANDONED_0...WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS => |n| { + const handle_index = n - WAIT_ABANDONED_0; + assert(handle_index < nCount); + return error.WaitAbandoned; + }, + WAIT_TIMEOUT => return error.WaitTimeOut, + WAIT_FAILED => switch (kernel32.GetLastError()) { + else => |err| return unexpectedError(err), + }, + else => return error.Unexpected, + } +} + pub const FindFirstFileError = error{ FileNotFound, InvalidUtf8, diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index aa478fbe5b..23dd80141a 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -534,7 +534,10 @@ pub const STARTF_USESTDHANDLES = 0x00000100; pub const INFINITE = 4294967295; +pub const MAXIMUM_WAIT_OBJECTS = 64; + pub const WAIT_ABANDONED = 0x00000080; +pub const WAIT_ABANDONED_0 = WAIT_ABANDONED + 0; pub const WAIT_OBJECT_0 = 0x00000000; pub const WAIT_TIMEOUT = 0x00000102; pub const WAIT_FAILED = 0xFFFFFFFF; diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 3f14196d11..748d9e25fa 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -207,6 +207,16 @@ pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMillis pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD; +pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll:BOOL, dwMilliseconds: DWORD) DWORD; + +pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx( + nCount: DWORD, + lpHandle: [*]const HANDLE, + bWaitAll:BOOL, + dwMilliseconds: DWORD, + bAlertable: BOOL, +) DWORD; + pub extern "kernel32" stdcallcc fn WriteFile( in_hFile: HANDLE, in_lpBuffer: [*]const u8, From b05a5a3e52a0b14396d94c0d659edc980c1d79ce Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:38:23 +1100 Subject: [PATCH 03/14] std: add CreateEvent for windows --- lib/std/os/windows.zig | 16 ++++++++++++++++ lib/std/os/windows/bits.zig | 7 +++++++ lib/std/os/windows/kernel32.zig | 7 +++++++ 3 files changed, 30 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 593a9ec29f..4249205a34 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -97,6 +97,22 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C } } +pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE { + const nameW = try sliceToPrefixedFileW(name); + return CreateEventExW(attributes, &nameW, flags, desired_access); +} + +pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, flags: DWORD, desired_access: DWORD) !HANDLE { + const handle = kernel32.CreateEventExW(attributes, nameW, flags, desired_access); + if (handle) |h| { + return h; + } else { + switch (kernel32.GetLastError()) { + else => |err| return unexpectedError(err), + } + } +} + pub fn DeviceIoControl( h: HANDLE, ioControlCode: DWORD, diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 23dd80141a..80b0545dc4 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -489,6 +489,13 @@ pub const FILE_ATTRIBUTE_SYSTEM = 0x4; pub const FILE_ATTRIBUTE_TEMPORARY = 0x100; pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000; +// flags for CreateEvent +pub const CREATE_EVENT_INITIAL_SET = 0x00000002; +pub const CREATE_EVENT_MANUAL_RESET = 0x00000001; + +pub const EVENT_ALL_ACCESS = 0x1F0003; +pub const EVENT_MODIFY_STATE = 0x0002; + pub const PROCESS_INFORMATION = extern struct { hProcess: HANDLE, hThread: HANDLE, diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 748d9e25fa..82dd03b829 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -9,6 +9,13 @@ pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL; pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL; +pub extern "kernel32" stdcallcc fn CreateEventExW( + lpEventAttributes: ?*SECURITY_ATTRIBUTES, + lpName: [*:0]const u16, + dwFlags: DWORD, + dwDesiredAccess: DWORD, +) ?HANDLE; + pub extern "kernel32" stdcallcc fn CreateFileW( lpFileName: [*]const u16, // TODO null terminated pointer type dwDesiredAccess: DWORD, From ce9966a39b8ab33504bfb185b5f78bddef49b28e Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:39:50 +1100 Subject: [PATCH 04/14] std: improved windows.DeviceIoControl --- lib/std/os/windows.zig | 1 + lib/std/os/windows/kernel32.zig | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 4249205a34..346eab7915 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -132,6 +132,7 @@ pub fn DeviceIoControl( overlapped, ) == 0) { switch (kernel32.GetLastError()) { + ERROR.IO_PENDING => if (overlapped == null) unreachable, else => |err| return unexpectedError(err), } } diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 82dd03b829..954261bd1b 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -59,7 +59,7 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl( nInBufferSize: DWORD, lpOutBuffer: ?LPVOID, nOutBufferSize: DWORD, - lpBytesReturned: LPDWORD, + lpBytesReturned: ?*DWORD, lpOverlapped: ?*OVERLAPPED, ) BOOL; From 6b5b0e6cd6b46b30fc8e8379bc136175e876956b Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:40:24 +1100 Subject: [PATCH 05/14] std: fix windows.GetOverlappedResult --- lib/std/os/windows.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 346eab7915..101a2a339f 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -141,9 +141,9 @@ pub fn DeviceIoControl( pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD { var bytes: DWORD = undefined; - if (kernel32.GetOverlappedResult(h, overlapped, &bytes, wait) == 0) { + if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @boolToInt(wait)) == 0) { switch (kernel32.GetLastError()) { - ERROR_IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable, + ERROR.IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable, else => |err| return unexpectedError(err), } } From 2c6788d7de19653a5e7eee1117cc5b88545dc17f Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:40:44 +1100 Subject: [PATCH 06/14] std: add windows.closesocket --- lib/std/os/windows.zig | 10 ++++++++++ lib/std/os/windows/ws2_32.zig | 1 + 2 files changed, 11 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 101a2a339f..601f3a79b9 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -692,6 +692,16 @@ pub fn WSASocketW( return rc; } +pub fn closesocket(s: ws2_32.SOCKET) !void { + switch (ws2_32.closesocket(s)) { + 0 => {}, + ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) { + else => |err| return unexpectedWSAError(err), + }, + else => unreachable, + } +} + pub fn WSAIoctl( s: ws2_32.SOCKET, dwIoControlCode: DWORD, diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index 0554f09705..faaaedd443 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -240,6 +240,7 @@ pub extern "ws2_32" stdcallcc fn WSASocketW( g: GROUP, dwFlags: DWORD, ) SOCKET; +pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int; pub extern "ws2_32" stdcallcc fn WSAIoctl( s: SOCKET, dwIoControlCode: DWORD, From a453c99ba95ab1cc8de128aeffdaae561a6f1a8d Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:41:24 +1100 Subject: [PATCH 07/14] std: add comments for some nt status codes --- lib/std/os/windows/status.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/std/os/windows/status.zig b/lib/std/os/windows/status.zig index 23e5ade7c2..71c1fbeacf 100644 --- a/lib/std/os/windows/status.zig +++ b/lib/std/os/windows/status.zig @@ -11,8 +11,13 @@ pub const ABANDONED_WAIT_0 = 0x00000080; pub const ABANDONED_WAIT_63 = 0x000000BF; pub const USER_APC = 0x000000C0; pub const ALERTED = 0x00000101; + +/// The given Timeout interval expired. pub const TIMEOUT = 0x00000102; + +/// The operation that was requested is pending completion. pub const PENDING = 0x00000103; + pub const REPARSE = 0x00000104; pub const MORE_ENTRIES = 0x00000105; pub const NOT_ALL_ASSIGNED = 0x00000106; @@ -128,6 +133,8 @@ pub const GUARD_PAGE_VIOLATION = 0x80000001; pub const DATATYPE_MISALIGNMENT = 0x80000002; pub const BREAKPOINT = 0x80000003; pub const SINGLE_STEP = 0x80000004; + +/// The data was too large to fit into the specified buffer. pub const BUFFER_OVERFLOW = 0x80000005; pub const NO_MORE_FILES = 0x80000006; pub const WAKE_SYSTEM_DEBUGGER = 0x80000007; From 1537d4701effe780d68444dec55073901001576a Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:44:27 +1100 Subject: [PATCH 08/14] std: fix definition of NtDeviceIoControlFile --- lib/std/os/windows/ntdll.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index d70b1cfefa..84de0ca946 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -24,8 +24,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile( pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( FileHandle: HANDLE, Event: ?HANDLE, - ApcRoutine: ?*IO_APC_ROUTINE, - ApcContext: usize, + ApcRoutine: ?IO_APC_ROUTINE, + ApcContext: ?*c_void, IoStatusBlock: *IO_STATUS_BLOCK, IoControlCode: ULONG, InputBuffer: ?*const c_void, From d99f0a2b8fc3c8617e95396d3c308fccf8beceb6 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 19 Nov 2019 16:58:48 +1100 Subject: [PATCH 09/14] std: IO_STATUS_BLOCK's status member is an NTSTATUS; add union --- lib/std/os/windows/bits.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 80b0545dc4..eefcc72ecc 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -236,7 +236,11 @@ pub const FILE_NAME_INFORMATION = extern struct { }; pub const IO_STATUS_BLOCK = extern struct { - Status: usize, + // "DUMMYUNIONNAME" expands to "u" + u: extern union { + Status: NTSTATUS, + Pointer: ?*c_void, + }, Information: ULONG_PTR, }; From 254c79125b7bc664ef2bfa1e81dcd170ab49aef2 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 22 Nov 2019 14:49:24 +1100 Subject: [PATCH 10/14] std: fix WSAIoctl definition zig automatically passes functions as pointers --- lib/std/os/windows.zig | 2 +- lib/std/os/windows/ws2_32.zig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 601f3a79b9..7dddd39c41 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -708,7 +708,7 @@ pub fn WSAIoctl( inBuffer: ?[]const u8, outBuffer: []u8, overlapped: ?*ws2_32.WSAOVERLAPPED, - completionRoutine: ?*ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE, + completionRoutine: ?ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE, ) !DWORD { var bytes: DWORD = undefined; switch (ws2_32.WSAIoctl( diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index faaaedd443..ecb68a259e 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -250,5 +250,5 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl( cbOutBuffer: DWORD, lpcbBytesReturned: LPDWORD, lpOverlapped: ?*WSAOVERLAPPED, - lpCompletionRoutine: ?*WSAOVERLAPPED_COMPLETION_ROUTINE, + lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, ) c_int; From 8aa3d6019c57c00282085d7cf87e84bff25cbe36 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 27 Nov 2019 11:15:11 +1100 Subject: [PATCH 11/14] std: add windows.USHORT definition --- lib/std/os/windows/bits.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index eefcc72ecc..def987bd23 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -19,7 +19,6 @@ pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1; /// The standard error device. Initially, this is the active console screen buffer, CONOUT$. pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1; -pub const SHORT = c_short; pub const BOOL = c_int; pub const BOOLEAN = BYTE; pub const BYTE = u8; @@ -54,6 +53,8 @@ pub const UNICODE = false; pub const WCHAR = u16; pub const WORD = u16; pub const LARGE_INTEGER = i64; +pub const USHORT = u16; +pub const SHORT = i16; pub const ULONG = u32; pub const LONG = i32; pub const ULONGLONG = u64; From 19f26578c0be503c22f9503d9e5bf316d7e06f3b Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 22 Nov 2019 14:40:22 +1100 Subject: [PATCH 12/14] std: windows sockaddr constants come from ws2_32 --- lib/std/os/bits/windows.zig | 124 +++++++++++++++------------------- lib/std/os/windows/ws2_32.zig | 94 ++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 70 deletions(-) diff --git a/lib/std/os/bits/windows.zig b/lib/std/os/bits/windows.zig index a1ceb8ff5c..2998049577 100644 --- a/lib/std/os/bits/windows.zig +++ b/lib/std/os/bits/windows.zig @@ -1,6 +1,7 @@ // The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime). usingnamespace @import("../windows/bits.zig"); +const ws2_32 = @import("../windows/ws2_32.zig"); pub const fd_t = HANDLE; pub const pid_t = HANDLE; @@ -163,80 +164,63 @@ pub const F_OK = 0; pub const AT_REMOVEDIR = 0x200; pub const in_port_t = u16; -pub const sa_family_t = u16; +pub const sa_family_t = ws2_32.ADDRESS_FAMILY; pub const socklen_t = u32; -pub const sockaddr = extern struct { - family: sa_family_t, - data: [14]u8, -}; -pub const sockaddr_in = extern struct { - family: sa_family_t = AF_INET, - port: in_port_t, - addr: in_addr, - zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }, -}; -pub const sockaddr_in6 = extern struct { - family: sa_family_t = AF_INET6, - port: in_port_t, - flowinfo: u32, - addr: in6_addr, - scope_id: u32, -}; +pub const sockaddr = ws2_32.sockaddr; +pub const sockaddr_in = ws2_32.sockaddr_in; +pub const sockaddr_in6 = ws2_32.sockaddr_in6; +pub const sockaddr_un = ws2_32.sockaddr_un; + pub const in6_addr = [16]u8; pub const in_addr = u32; -pub const sockaddr_un = extern struct { - family: sa_family_t = AF_UNIX, - path: [108]u8, -}; +pub const AF_UNSPEC = ws2_32.AF_UNSPEC; +pub const AF_UNIX = ws2_32.AF_UNIX; +pub const AF_INET = ws2_32.AF_INET; +pub const AF_IMPLINK = ws2_32.AF_IMPLINK; +pub const AF_PUP = ws2_32.AF_PUP; +pub const AF_CHAOS = ws2_32.AF_CHAOS; +pub const AF_NS = ws2_32.AF_NS; +pub const AF_IPX = ws2_32.AF_IPX; +pub const AF_ISO = ws2_32.AF_ISO; +pub const AF_OSI = ws2_32.AF_OSI; +pub const AF_ECMA = ws2_32.AF_ECMA; +pub const AF_DATAKIT = ws2_32.AF_DATAKIT; +pub const AF_CCITT = ws2_32.AF_CCITT; +pub const AF_SNA = ws2_32.AF_SNA; +pub const AF_DECnet = ws2_32.AF_DECnet; +pub const AF_DLI = ws2_32.AF_DLI; +pub const AF_LAT = ws2_32.AF_LAT; +pub const AF_HYLINK = ws2_32.AF_HYLINK; +pub const AF_APPLETALK = ws2_32.AF_APPLETALK; +pub const AF_NETBIOS = ws2_32.AF_NETBIOS; +pub const AF_VOICEVIEW = ws2_32.AF_VOICEVIEW; +pub const AF_FIREFOX = ws2_32.AF_FIREFOX; +pub const AF_UNKNOWN1 = ws2_32.AF_UNKNOWN1; +pub const AF_BAN = ws2_32.AF_BAN; +pub const AF_ATM = ws2_32.AF_ATM; +pub const AF_INET6 = ws2_32.AF_INET6; +pub const AF_CLUSTER = ws2_32.AF_CLUSTER; +pub const AF_12844 = ws2_32.AF_12844; +pub const AF_IRDA = ws2_32.AF_IRDA; +pub const AF_NETDES = ws2_32.AF_NETDES; +pub const AF_TCNPROCESS = ws2_32.AF_TCNPROCESS; +pub const AF_TCNMESSAGE = ws2_32.AF_TCNMESSAGE; +pub const AF_ICLFXBM = ws2_32.AF_ICLFXBM; +pub const AF_BTH = ws2_32.AF_BTH; +pub const AF_MAX = ws2_32.AF_MAX; -pub const AF_UNSPEC = 0; -pub const AF_UNIX = 1; -pub const AF_INET = 2; -pub const AF_IMPLINK = 3; -pub const AF_PUP = 4; -pub const AF_CHAOS = 5; -pub const AF_NS = 6; -pub const AF_IPX = AF_NS; -pub const AF_ISO = 7; -pub const AF_OSI = AF_ISO; -pub const AF_ECMA = 8; -pub const AF_DATAKIT = 9; -pub const AF_CCITT = 10; -pub const AF_SNA = 11; -pub const AF_DECnet = 12; -pub const AF_DLI = 13; -pub const AF_LAT = 14; -pub const AF_HYLINK = 15; -pub const AF_APPLETALK = 16; -pub const AF_NETBIOS = 17; -pub const AF_VOICEVIEW = 18; -pub const AF_FIREFOX = 19; -pub const AF_UNKNOWN1 = 20; -pub const AF_BAN = 21; -pub const AF_ATM = 22; -pub const AF_INET6 = 23; -pub const AF_CLUSTER = 24; -pub const AF_12844 = 25; -pub const AF_IRDA = 26; -pub const AF_NETDES = 28; -pub const AF_TCNPROCESS = 29; -pub const AF_TCNMESSAGE = 30; -pub const AF_ICLFXBM = 31; -pub const AF_BTH = 32; -pub const AF_MAX = 33; +pub const SOCK_STREAM = ws2_32.SOCK_STREAM; +pub const SOCK_DGRAM = ws2_32.SOCK_DGRAM; +pub const SOCK_RAW = ws2_32.SOCK_RAW; +pub const SOCK_RDM = ws2_32.SOCK_RDM; +pub const SOCK_SEQPACKET = ws2_32.SOCK_SEQPACKET; -pub const SOCK_STREAM = 1; -pub const SOCK_DGRAM = 2; -pub const SOCK_RAW = 3; -pub const SOCK_RDM = 4; -pub const SOCK_SEQPACKET = 5; - -pub const IPPROTO_ICMP = 1; -pub const IPPROTO_IGMP = 2; -pub const BTHPROTO_RFCOMM = 3; -pub const IPPROTO_TCP = 6; -pub const IPPROTO_UDP = 17; -pub const IPPROTO_ICMPV6 = 58; -pub const IPPROTO_RM = 113; +pub const IPPROTO_ICMP = ws2_32.IPPROTO_ICMP; +pub const IPPROTO_IGMP = ws2_32.IPPROTO_IGMP; +pub const BTHPROTO_RFCOMM = ws2_32.BTHPROTO_RFCOMM; +pub const IPPROTO_TCP = ws2_32.IPPROTO_TCP; +pub const IPPROTO_UDP = ws2_32.IPPROTO_UDP; +pub const IPPROTO_ICMPV6 = ws2_32.IPPROTO_ICMPV6; +pub const IPPROTO_RM = ws2_32.IPPROTO_RM; diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index ecb68a259e..dc636df87d 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -108,6 +108,100 @@ pub const WSAOVERLAPPED = extern struct { pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) void; +pub const ADDRESS_FAMILY = u16; + +pub const AF_UNSPEC = 0; +pub const AF_UNIX = 1; +pub const AF_INET = 2; +pub const AF_IMPLINK = 3; +pub const AF_PUP = 4; +pub const AF_CHAOS = 5; +pub const AF_NS = 6; +pub const AF_IPX = AF_NS; +pub const AF_ISO = 7; +pub const AF_OSI = AF_ISO; +pub const AF_ECMA = 8; +pub const AF_DATAKIT = 9; +pub const AF_CCITT = 10; +pub const AF_SNA = 11; +pub const AF_DECnet = 12; +pub const AF_DLI = 13; +pub const AF_LAT = 14; +pub const AF_HYLINK = 15; +pub const AF_APPLETALK = 16; +pub const AF_NETBIOS = 17; +pub const AF_VOICEVIEW = 18; +pub const AF_FIREFOX = 19; +pub const AF_UNKNOWN1 = 20; +pub const AF_BAN = 21; +pub const AF_ATM = 22; +pub const AF_INET6 = 23; +pub const AF_CLUSTER = 24; +pub const AF_12844 = 25; +pub const AF_IRDA = 26; +pub const AF_NETDES = 28; +pub const AF_TCNPROCESS = 29; +pub const AF_TCNMESSAGE = 30; +pub const AF_ICLFXBM = 31; +pub const AF_BTH = 32; +pub const AF_MAX = 33; + +pub const SOCK_STREAM = 1; +pub const SOCK_DGRAM = 2; +pub const SOCK_RAW = 3; +pub const SOCK_RDM = 4; +pub const SOCK_SEQPACKET = 5; + +pub const IPPROTO_ICMP = 1; +pub const IPPROTO_IGMP = 2; +pub const BTHPROTO_RFCOMM = 3; +pub const IPPROTO_TCP = 6; +pub const IPPROTO_UDP = 17; +pub const IPPROTO_ICMPV6 = 58; +pub const IPPROTO_RM = 113; + +pub const sockaddr = extern struct { + family: ADDRESS_FAMILY, + data: [14]u8, +}; + +/// IPv4 socket address +pub const sockaddr_in = extern struct { + family: ADDRESS_FAMILY = AF_INET, + port: USHORT, + addr: u32, + zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }, +}; + +/// IPv6 socket address +pub const sockaddr_in6 = extern struct { + family: ADDRESS_FAMILY = AF_INET6, + port: USHORT, + flowinfo: u32, + addr: [16]u8, + scope_id: u32, +}; + +/// UNIX domain socket address +pub const sockaddr_un = extern struct { + family: ADDRESS_FAMILY = AF_UNIX, + path: [108]u8, +}; + +pub const WSABUF = extern struct { + len: ULONG, + buf: [*]u8, +}; + +pub const WSAMSG = extern struct { + name: *const sockaddr, + namelen: INT, + lpBuffers: [*]WSABUF, + dwBufferCount: DWORD, + Control: WSABUF, + dwFlags: DWORD, +}; + pub const WSA_INVALID_HANDLE = 6; pub const WSA_NOT_ENOUGH_MEMORY = 8; pub const WSA_INVALID_PARAMETER = 87; From edc84e7ef78831a6da154fd648740f637c8a918e Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 27 Nov 2019 11:20:35 +1100 Subject: [PATCH 13/14] std: add more winsock functions --- lib/std/os/windows/ws2_32.zig | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index dc636df87d..48ac212b0d 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -346,3 +346,53 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl( lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, ) c_int; +pub extern "ws2_32" stdcallcc fn accept( + s: SOCKET, + addr: ?*sockaddr, + addrlen: c_int, +) SOCKET; +pub extern "ws2_32" stdcallcc fn connect( + s: SOCKET, + name: *const sockaddr, + namelen: c_int, +) c_int; +pub extern "ws2_32" stdcallcc fn WSARecv( + s: SOCKET, + lpBuffers: [*]const WSABUF, + dwBufferCount: DWORD, + lpNumberOfBytesRecvd: ?*DWORD, + lpFlags: *DWORD, + lpOverlapped: ?*WSAOVERLAPPED, + lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, +) c_int; +pub extern "ws2_32" stdcallcc fn WSARecvFrom( + s: SOCKET, + lpBuffers: [*]const WSABUF, + dwBufferCount: DWORD, + lpNumberOfBytesRecvd: ?*DWORD, + lpFlags: *DWORD, + lpFrom: ?*sockaddr, + lpFromlen: c_int, + lpOverlapped: ?*WSAOVERLAPPED, + lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, +) c_int; +pub extern "ws2_32" stdcallcc fn WSASend( + s: SOCKET, + lpBuffers: [*]WSABUF, + dwBufferCount: DWORD, + lpNumberOfBytesSent: ?*DWORD, + dwFlags: DWORD, + lpOverlapped: ?*WSAOVERLAPPED, + lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, +) c_int; +pub extern "ws2_32" stdcallcc fn WSASendTo( + s: SOCKET, + lpBuffers: [*]WSABUF, + dwBufferCount: DWORD, + lpNumberOfBytesSent: ?*DWORD, + dwFlags: DWORD, + lpTo: ?*const sockaddr, + iTolen: c_int, + lpOverlapped: ?*WSAOVERLAPPED, + lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, +) c_int; From 8a71f77c4a094c98c57fc3a3332bb4e17ed6febf Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 27 Nov 2019 12:29:14 +1100 Subject: [PATCH 14/14] std: lie about windows socklen_t signed-ness --- lib/std/os/windows/ws2_32.zig | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index 48ac212b0d..c3dece2909 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -110,6 +110,9 @@ pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (dwError: DWORD, cbTransf pub const ADDRESS_FAMILY = u16; +// Microsoft use the signed c_int for this, but it should never be negative +const socklen_t = u32; + pub const AF_UNSPEC = 0; pub const AF_UNIX = 1; pub const AF_INET = 2; @@ -349,12 +352,12 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl( pub extern "ws2_32" stdcallcc fn accept( s: SOCKET, addr: ?*sockaddr, - addrlen: c_int, + addrlen: socklen_t, ) SOCKET; pub extern "ws2_32" stdcallcc fn connect( s: SOCKET, name: *const sockaddr, - namelen: c_int, + namelen: socklen_t, ) c_int; pub extern "ws2_32" stdcallcc fn WSARecv( s: SOCKET, @@ -372,7 +375,7 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom( lpNumberOfBytesRecvd: ?*DWORD, lpFlags: *DWORD, lpFrom: ?*sockaddr, - lpFromlen: c_int, + lpFromlen: socklen_t, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, ) c_int; @@ -392,7 +395,7 @@ pub extern "ws2_32" stdcallcc fn WSASendTo( lpNumberOfBytesSent: ?*DWORD, dwFlags: DWORD, lpTo: ?*const sockaddr, - iTolen: c_int, + iTolen: socklen_t, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, ) c_int;