Skip to content

Commit b7be577

Browse files
authored
Merge pull request #3715 from daurnimator/towards-afd
Misc windows additions+fixes
2 parents 55202a0 + 8a71f77 commit b7be577

File tree

9 files changed

+313
-85
lines changed

9 files changed

+313
-85
lines changed

lib/std/child_process.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ pub const ChildProcess = struct {
235235
}
236236

237237
fn waitUnwrappedWindows(self: *ChildProcess) !void {
238-
const result = windows.WaitForSingleObject(self.handle, windows.INFINITE);
238+
const result = windows.WaitForSingleObjectEx(self.handle, windows.INFINITE, false);
239239

240240
self.term = @as(SpawnError!Term, x: {
241241
var exit_code: windows.DWORD = undefined;

lib/std/os/bits/windows.zig

Lines changed: 56 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime).
22

33
usingnamespace @import("../windows/bits.zig");
4+
const ws2_32 = @import("../windows/ws2_32.zig");
45

56
pub const fd_t = HANDLE;
67
pub const pid_t = HANDLE;
@@ -163,80 +164,63 @@ pub const F_OK = 0;
163164
pub const AT_REMOVEDIR = 0x200;
164165

165166
pub const in_port_t = u16;
166-
pub const sa_family_t = u16;
167+
pub const sa_family_t = ws2_32.ADDRESS_FAMILY;
167168
pub const socklen_t = u32;
168169

169-
pub const sockaddr = extern struct {
170-
family: sa_family_t,
171-
data: [14]u8,
172-
};
173-
pub const sockaddr_in = extern struct {
174-
family: sa_family_t = AF_INET,
175-
port: in_port_t,
176-
addr: in_addr,
177-
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
178-
};
179-
pub const sockaddr_in6 = extern struct {
180-
family: sa_family_t = AF_INET6,
181-
port: in_port_t,
182-
flowinfo: u32,
183-
addr: in6_addr,
184-
scope_id: u32,
185-
};
170+
pub const sockaddr = ws2_32.sockaddr;
171+
pub const sockaddr_in = ws2_32.sockaddr_in;
172+
pub const sockaddr_in6 = ws2_32.sockaddr_in6;
173+
pub const sockaddr_un = ws2_32.sockaddr_un;
174+
186175
pub const in6_addr = [16]u8;
187176
pub const in_addr = u32;
188177

189-
pub const sockaddr_un = extern struct {
190-
family: sa_family_t = AF_UNIX,
191-
path: [108]u8,
192-
};
193-
194-
pub const AF_UNSPEC = 0;
195-
pub const AF_UNIX = 1;
196-
pub const AF_INET = 2;
197-
pub const AF_IMPLINK = 3;
198-
pub const AF_PUP = 4;
199-
pub const AF_CHAOS = 5;
200-
pub const AF_NS = 6;
201-
pub const AF_IPX = AF_NS;
202-
pub const AF_ISO = 7;
203-
pub const AF_OSI = AF_ISO;
204-
pub const AF_ECMA = 8;
205-
pub const AF_DATAKIT = 9;
206-
pub const AF_CCITT = 10;
207-
pub const AF_SNA = 11;
208-
pub const AF_DECnet = 12;
209-
pub const AF_DLI = 13;
210-
pub const AF_LAT = 14;
211-
pub const AF_HYLINK = 15;
212-
pub const AF_APPLETALK = 16;
213-
pub const AF_NETBIOS = 17;
214-
pub const AF_VOICEVIEW = 18;
215-
pub const AF_FIREFOX = 19;
216-
pub const AF_UNKNOWN1 = 20;
217-
pub const AF_BAN = 21;
218-
pub const AF_ATM = 22;
219-
pub const AF_INET6 = 23;
220-
pub const AF_CLUSTER = 24;
221-
pub const AF_12844 = 25;
222-
pub const AF_IRDA = 26;
223-
pub const AF_NETDES = 28;
224-
pub const AF_TCNPROCESS = 29;
225-
pub const AF_TCNMESSAGE = 30;
226-
pub const AF_ICLFXBM = 31;
227-
pub const AF_BTH = 32;
228-
pub const AF_MAX = 33;
229-
230-
pub const SOCK_STREAM = 1;
231-
pub const SOCK_DGRAM = 2;
232-
pub const SOCK_RAW = 3;
233-
pub const SOCK_RDM = 4;
234-
pub const SOCK_SEQPACKET = 5;
235-
236-
pub const IPPROTO_ICMP = 1;
237-
pub const IPPROTO_IGMP = 2;
238-
pub const BTHPROTO_RFCOMM = 3;
239-
pub const IPPROTO_TCP = 6;
240-
pub const IPPROTO_UDP = 17;
241-
pub const IPPROTO_ICMPV6 = 58;
242-
pub const IPPROTO_RM = 113;
178+
pub const AF_UNSPEC = ws2_32.AF_UNSPEC;
179+
pub const AF_UNIX = ws2_32.AF_UNIX;
180+
pub const AF_INET = ws2_32.AF_INET;
181+
pub const AF_IMPLINK = ws2_32.AF_IMPLINK;
182+
pub const AF_PUP = ws2_32.AF_PUP;
183+
pub const AF_CHAOS = ws2_32.AF_CHAOS;
184+
pub const AF_NS = ws2_32.AF_NS;
185+
pub const AF_IPX = ws2_32.AF_IPX;
186+
pub const AF_ISO = ws2_32.AF_ISO;
187+
pub const AF_OSI = ws2_32.AF_OSI;
188+
pub const AF_ECMA = ws2_32.AF_ECMA;
189+
pub const AF_DATAKIT = ws2_32.AF_DATAKIT;
190+
pub const AF_CCITT = ws2_32.AF_CCITT;
191+
pub const AF_SNA = ws2_32.AF_SNA;
192+
pub const AF_DECnet = ws2_32.AF_DECnet;
193+
pub const AF_DLI = ws2_32.AF_DLI;
194+
pub const AF_LAT = ws2_32.AF_LAT;
195+
pub const AF_HYLINK = ws2_32.AF_HYLINK;
196+
pub const AF_APPLETALK = ws2_32.AF_APPLETALK;
197+
pub const AF_NETBIOS = ws2_32.AF_NETBIOS;
198+
pub const AF_VOICEVIEW = ws2_32.AF_VOICEVIEW;
199+
pub const AF_FIREFOX = ws2_32.AF_FIREFOX;
200+
pub const AF_UNKNOWN1 = ws2_32.AF_UNKNOWN1;
201+
pub const AF_BAN = ws2_32.AF_BAN;
202+
pub const AF_ATM = ws2_32.AF_ATM;
203+
pub const AF_INET6 = ws2_32.AF_INET6;
204+
pub const AF_CLUSTER = ws2_32.AF_CLUSTER;
205+
pub const AF_12844 = ws2_32.AF_12844;
206+
pub const AF_IRDA = ws2_32.AF_IRDA;
207+
pub const AF_NETDES = ws2_32.AF_NETDES;
208+
pub const AF_TCNPROCESS = ws2_32.AF_TCNPROCESS;
209+
pub const AF_TCNMESSAGE = ws2_32.AF_TCNMESSAGE;
210+
pub const AF_ICLFXBM = ws2_32.AF_ICLFXBM;
211+
pub const AF_BTH = ws2_32.AF_BTH;
212+
pub const AF_MAX = ws2_32.AF_MAX;
213+
214+
pub const SOCK_STREAM = ws2_32.SOCK_STREAM;
215+
pub const SOCK_DGRAM = ws2_32.SOCK_DGRAM;
216+
pub const SOCK_RAW = ws2_32.SOCK_RAW;
217+
pub const SOCK_RDM = ws2_32.SOCK_RDM;
218+
pub const SOCK_SEQPACKET = ws2_32.SOCK_SEQPACKET;
219+
220+
pub const IPPROTO_ICMP = ws2_32.IPPROTO_ICMP;
221+
pub const IPPROTO_IGMP = ws2_32.IPPROTO_IGMP;
222+
pub const BTHPROTO_RFCOMM = ws2_32.BTHPROTO_RFCOMM;
223+
pub const IPPROTO_TCP = ws2_32.IPPROTO_TCP;
224+
pub const IPPROTO_UDP = ws2_32.IPPROTO_UDP;
225+
pub const IPPROTO_ICMPV6 = ws2_32.IPPROTO_ICMPV6;
226+
pub const IPPROTO_RM = ws2_32.IPPROTO_RM;

lib/std/os/windows.zig

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
9797
}
9898
}
9999

100+
pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE {
101+
const nameW = try sliceToPrefixedFileW(name);
102+
return CreateEventExW(attributes, &nameW, flags, desired_access);
103+
}
104+
105+
pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, flags: DWORD, desired_access: DWORD) !HANDLE {
106+
const handle = kernel32.CreateEventExW(attributes, nameW, flags, desired_access);
107+
if (handle) |h| {
108+
return h;
109+
} else {
110+
switch (kernel32.GetLastError()) {
111+
else => |err| return unexpectedError(err),
112+
}
113+
}
114+
}
115+
100116
pub fn DeviceIoControl(
101117
h: HANDLE,
102118
ioControlCode: DWORD,
@@ -116,6 +132,7 @@ pub fn DeviceIoControl(
116132
overlapped,
117133
) == 0) {
118134
switch (kernel32.GetLastError()) {
135+
ERROR.IO_PENDING => if (overlapped == null) unreachable,
119136
else => |err| return unexpectedError(err),
120137
}
121138
}
@@ -124,9 +141,9 @@ pub fn DeviceIoControl(
124141

125142
pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
126143
var bytes: DWORD = undefined;
127-
if (kernel32.GetOverlappedResult(h, overlapped, &bytes, wait) == 0) {
144+
if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @boolToInt(wait)) == 0) {
128145
switch (kernel32.GetLastError()) {
129-
ERROR_IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
146+
ERROR.IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
130147
else => |err| return unexpectedError(err),
131148
}
132149
}
@@ -171,8 +188,8 @@ pub const WaitForSingleObjectError = error{
171188
Unexpected,
172189
};
173190

174-
pub fn WaitForSingleObject(handle: HANDLE, milliseconds: DWORD) WaitForSingleObjectError!void {
175-
switch (kernel32.WaitForSingleObject(handle, milliseconds)) {
191+
pub fn WaitForSingleObjectEx(handle: HANDLE, milliseconds: DWORD, alertable: bool) WaitForSingleObjectError!void {
192+
switch (kernel32.WaitForSingleObjectEx(handle, milliseconds, @boolToInt(alertable))) {
176193
WAIT_ABANDONED => return error.WaitAbandoned,
177194
WAIT_OBJECT_0 => return,
178195
WAIT_TIMEOUT => return error.WaitTimeOut,
@@ -183,6 +200,34 @@ pub fn WaitForSingleObject(handle: HANDLE, milliseconds: DWORD) WaitForSingleObj
183200
}
184201
}
185202

203+
pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, milliseconds: DWORD, alertable: bool) !u32 {
204+
assert(handles.len < MAXIMUM_WAIT_OBJECTS);
205+
const nCount: DWORD = @intCast(DWORD, handles.len);
206+
switch (kernel32.WaitForMultipleObjectsEx(
207+
nCount,
208+
handles.ptr,
209+
@boolToInt(waitAll),
210+
milliseconds,
211+
@boolToInt(alertable),
212+
)) {
213+
WAIT_OBJECT_0...WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS => |n| {
214+
const handle_index = n - WAIT_OBJECT_0;
215+
assert(handle_index < nCount);
216+
return handle_index;
217+
},
218+
WAIT_ABANDONED_0...WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS => |n| {
219+
const handle_index = n - WAIT_ABANDONED_0;
220+
assert(handle_index < nCount);
221+
return error.WaitAbandoned;
222+
},
223+
WAIT_TIMEOUT => return error.WaitTimeOut,
224+
WAIT_FAILED => switch (kernel32.GetLastError()) {
225+
else => |err| return unexpectedError(err),
226+
},
227+
else => return error.Unexpected,
228+
}
229+
}
230+
186231
pub const FindFirstFileError = error{
187232
FileNotFound,
188233
InvalidUtf8,
@@ -647,13 +692,23 @@ pub fn WSASocketW(
647692
return rc;
648693
}
649694

695+
pub fn closesocket(s: ws2_32.SOCKET) !void {
696+
switch (ws2_32.closesocket(s)) {
697+
0 => {},
698+
ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
699+
else => |err| return unexpectedWSAError(err),
700+
},
701+
else => unreachable,
702+
}
703+
}
704+
650705
pub fn WSAIoctl(
651706
s: ws2_32.SOCKET,
652707
dwIoControlCode: DWORD,
653708
inBuffer: ?[]const u8,
654709
outBuffer: []u8,
655710
overlapped: ?*ws2_32.WSAOVERLAPPED,
656-
completionRoutine: ?*ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,
711+
completionRoutine: ?ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,
657712
) !DWORD {
658713
var bytes: DWORD = undefined;
659714
switch (ws2_32.WSAIoctl(

lib/std/os/windows/bits.zig

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1;
1919
/// The standard error device. Initially, this is the active console screen buffer, CONOUT$.
2020
pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1;
2121

22-
pub const SHORT = c_short;
2322
pub const BOOL = c_int;
2423
pub const BOOLEAN = BYTE;
2524
pub const BYTE = u8;
@@ -54,6 +53,8 @@ pub const UNICODE = false;
5453
pub const WCHAR = u16;
5554
pub const WORD = u16;
5655
pub const LARGE_INTEGER = i64;
56+
pub const USHORT = u16;
57+
pub const SHORT = i16;
5758
pub const ULONG = u32;
5859
pub const LONG = i32;
5960
pub const ULONGLONG = u64;
@@ -236,7 +237,11 @@ pub const FILE_NAME_INFORMATION = extern struct {
236237
};
237238

238239
pub const IO_STATUS_BLOCK = extern struct {
239-
Status: usize,
240+
// "DUMMYUNIONNAME" expands to "u"
241+
u: extern union {
242+
Status: NTSTATUS,
243+
Pointer: ?*c_void,
244+
},
240245
Information: ULONG_PTR,
241246
};
242247

@@ -489,6 +494,13 @@ pub const FILE_ATTRIBUTE_SYSTEM = 0x4;
489494
pub const FILE_ATTRIBUTE_TEMPORARY = 0x100;
490495
pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000;
491496

497+
// flags for CreateEvent
498+
pub const CREATE_EVENT_INITIAL_SET = 0x00000002;
499+
pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;
500+
501+
pub const EVENT_ALL_ACCESS = 0x1F0003;
502+
pub const EVENT_MODIFY_STATE = 0x0002;
503+
492504
pub const PROCESS_INFORMATION = extern struct {
493505
hProcess: HANDLE,
494506
hThread: HANDLE,
@@ -534,7 +546,10 @@ pub const STARTF_USESTDHANDLES = 0x00000100;
534546

535547
pub const INFINITE = 4294967295;
536548

549+
pub const MAXIMUM_WAIT_OBJECTS = 64;
550+
537551
pub const WAIT_ABANDONED = 0x00000080;
552+
pub const WAIT_ABANDONED_0 = WAIT_ABANDONED + 0;
538553
pub const WAIT_OBJECT_0 = 0x00000000;
539554
pub const WAIT_TIMEOUT = 0x00000102;
540555
pub const WAIT_FAILED = 0xFFFFFFFF;

lib/std/os/windows/kernel32.zig

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
99

1010
pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL;
1111

12+
pub extern "kernel32" stdcallcc fn CreateEventExW(
13+
lpEventAttributes: ?*SECURITY_ATTRIBUTES,
14+
lpName: [*:0]const u16,
15+
dwFlags: DWORD,
16+
dwDesiredAccess: DWORD,
17+
) ?HANDLE;
18+
1219
pub extern "kernel32" stdcallcc fn CreateFileW(
1320
lpFileName: [*]const u16, // TODO null terminated pointer type
1421
dwDesiredAccess: DWORD,
@@ -52,7 +59,7 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl(
5259
nInBufferSize: DWORD,
5360
lpOutBuffer: ?LPVOID,
5461
nOutBufferSize: DWORD,
55-
lpBytesReturned: LPDWORD,
62+
lpBytesReturned: ?*DWORD,
5663
lpOverlapped: ?*OVERLAPPED,
5764
) BOOL;
5865

@@ -205,6 +212,18 @@ pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL;
205212

206213
pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
207214

215+
pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD;
216+
217+
pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll:BOOL, dwMilliseconds: DWORD) DWORD;
218+
219+
pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx(
220+
nCount: DWORD,
221+
lpHandle: [*]const HANDLE,
222+
bWaitAll:BOOL,
223+
dwMilliseconds: DWORD,
224+
bAlertable: BOOL,
225+
) DWORD;
226+
208227
pub extern "kernel32" stdcallcc fn WriteFile(
209228
in_hFile: HANDLE,
210229
in_lpBuffer: [*]const u8,

lib/std/os/windows/ntdll.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(
2424
pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
2525
FileHandle: HANDLE,
2626
Event: ?HANDLE,
27-
ApcRoutine: ?*IO_APC_ROUTINE,
28-
ApcContext: usize,
27+
ApcRoutine: ?IO_APC_ROUTINE,
28+
ApcContext: ?*c_void,
2929
IoStatusBlock: *IO_STATUS_BLOCK,
3030
IoControlCode: ULONG,
3131
InputBuffer: ?*const c_void,

lib/std/os/windows/status.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ pub const ABANDONED_WAIT_0 = 0x00000080;
1111
pub const ABANDONED_WAIT_63 = 0x000000BF;
1212
pub const USER_APC = 0x000000C0;
1313
pub const ALERTED = 0x00000101;
14+
15+
/// The given Timeout interval expired.
1416
pub const TIMEOUT = 0x00000102;
17+
18+
/// The operation that was requested is pending completion.
1519
pub const PENDING = 0x00000103;
20+
1621
pub const REPARSE = 0x00000104;
1722
pub const MORE_ENTRIES = 0x00000105;
1823
pub const NOT_ALL_ASSIGNED = 0x00000106;
@@ -128,6 +133,8 @@ pub const GUARD_PAGE_VIOLATION = 0x80000001;
128133
pub const DATATYPE_MISALIGNMENT = 0x80000002;
129134
pub const BREAKPOINT = 0x80000003;
130135
pub const SINGLE_STEP = 0x80000004;
136+
137+
/// The data was too large to fit into the specified buffer.
131138
pub const BUFFER_OVERFLOW = 0x80000005;
132139
pub const NO_MORE_FILES = 0x80000006;
133140
pub const WAKE_SYSTEM_DEBUGGER = 0x80000007;

0 commit comments

Comments
 (0)