authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-27 15:34:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-27 15:55:15-04:00
log86bb7e5984c248f37aaa465c7acb0bf97c13b39e
tree8ad3aecb9d378451c3a66914c3b6e0a66ddf1189
parent5de07ab721380c39130a0bd3277a272673e3d644

fixes for windows to build self hosted compiler


7 files changed, 68 insertions(+), 50 deletions(-)

std/c.zig+2-2
......@@ -13,9 +13,9 @@ pub use switch (builtin.os) {
1313 else => struct {},
1414};
1515
16pub fn getErrno(rc: var) u12 {
16pub fn getErrno(rc: var) u16 {
1717 if (rc == -1) {
18 return @intCast(u12, _errno().*);
18 return @intCast(u16, _errno().*);
1919 } else {
2020 return 0;
2121 }
std/child_process.zig+1-1
......@@ -412,7 +412,7 @@ pub const ChildProcess = struct {
412412 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
413413
414414 const nul_handle = if (any_ignore) blk: {
415 break :blk try windows.CreateFile("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
415 break :blk try windows.CreateFile("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, null, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null);
416416 } else blk: {
417417 break :blk undefined;
418418 };
std/event/fs.zig+29-28
......@@ -147,14 +147,14 @@ pub async fn pwriteWindows(loop: *Loop, fd: fd_t, data: []const u8, offset: u64)
147147 errdefer loop.finishOneEvent();
148148
149149 errdefer {
150 _ = windows.CancelIoEx(fd, &resume_node.base.overlapped);
150 _ = windows.kernel32.CancelIoEx(fd, &resume_node.base.overlapped);
151151 }
152152 suspend {
153 _ = windows.WriteFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
153 _ = windows.kernel32.WriteFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
154154 }
155155 var bytes_transferred: windows.DWORD = undefined;
156 if (windows.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
157 switch (windows.GetLastError()) {
156 if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
157 switch (windows.kernel32.GetLastError()) {
158158 windows.ERROR.IO_PENDING => unreachable,
159159 windows.ERROR.INVALID_USER_BUFFER => return error.SystemResources,
160160 windows.ERROR.NOT_ENOUGH_MEMORY => return error.SystemResources,
......@@ -247,7 +247,7 @@ pub async fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PR
247247}
248248
249249/// data must outlive the returned promise
250pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u64) os.WindowsReadError!usize {
250pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u64) !usize {
251251 assert(data.len != 0);
252252 if (data.len == 1) return await (async preadWindows(loop, fd, data[0], offset) catch unreachable);
253253
......@@ -291,19 +291,19 @@ pub async fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize
291291 },
292292 };
293293 // TODO only call create io completion port once per fd
294 _ = windows.CreateIoCompletionPort(fd, loop.os_data.io_port, undefined, undefined);
294 _ = windows.CreateIoCompletionPort(fd, loop.os_data.io_port, undefined, undefined) catch undefined;
295295 loop.beginOneEvent();
296296 errdefer loop.finishOneEvent();
297297
298298 errdefer {
299 _ = windows.CancelIoEx(fd, &resume_node.base.overlapped);
299 _ = windows.kernel32.CancelIoEx(fd, &resume_node.base.overlapped);
300300 }
301301 suspend {
302 _ = windows.ReadFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
302 _ = windows.kernel32.ReadFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
303303 }
304304 var bytes_transferred: windows.DWORD = undefined;
305 if (windows.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
306 switch (windows.GetLastError()) {
305 if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
306 switch (windows.kernel32.GetLastError()) {
307307 windows.ERROR.IO_PENDING => unreachable,
308308 windows.ERROR.OPERATION_ABORTED => return error.OperationAborted,
309309 windows.ERROR.BROKEN_PIPE => return error.BrokenPipe,
......@@ -408,12 +408,14 @@ pub async fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t {
408408 return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable);
409409 },
410410
411 builtin.Os.windows => return os.windowsOpen(
411 builtin.Os.windows => return windows.CreateFile(
412412 path,
413413 windows.GENERIC_READ,
414414 windows.FILE_SHARE_READ,
415 null,
415416 windows.OPEN_EXISTING,
416417 windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
418 null,
417419 ),
418420
419421 else => @compileError("Unsupported OS"),
......@@ -437,12 +439,14 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.
437439 const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;
438440 return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable);
439441 },
440 builtin.Os.windows => return os.windowsOpen(
442 builtin.Os.windows => return windows.CreateFile(
441443 path,
442444 windows.GENERIC_WRITE,
443445 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
446 null,
444447 windows.CREATE_ALWAYS,
445448 windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
449 null,
446450 ),
447451 else => @compileError("Unsupported OS"),
448452 }
......@@ -460,12 +464,14 @@ pub async fn openReadWrite(
460464 return await (async openPosix(loop, path, flags, mode) catch unreachable);
461465 },
462466
463 builtin.Os.windows => return os.windowsOpen(
467 builtin.Os.windows => return windows.CreateFile(
464468 path,
465469 windows.GENERIC_WRITE | windows.GENERIC_READ,
466470 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
471 null,
467472 windows.OPEN_ALWAYS,
468473 windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
474 null,
469475 ),
470476
471477 else => @compileError("Unsupported OS"),
......@@ -622,12 +628,14 @@ pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8,
622628}
623629
624630async fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) !void {
625 const handle = try os.windowsOpen(
631 const handle = try windows.CreateFile(
626632 path,
627633 windows.GENERIC_WRITE,
628634 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
635 null,
629636 windows.CREATE_ALWAYS,
630637 windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
638 null,
631639 );
632640 defer os.close(handle);
633641
......@@ -1028,7 +1036,7 @@ pub fn Watch(comptime V: type) type {
10281036 defer if (!basename_utf16le_null_consumed) self.channel.loop.allocator.free(basename_utf16le_null);
10291037 const basename_utf16le_no_null = basename_utf16le_null[0 .. basename_utf16le_null.len - 1];
10301038
1031 const dir_handle = windows.CreateFileW(
1039 const dir_handle = try windows.CreateFileW(
10321040 dirname_utf16le.ptr,
10331041 windows.FILE_LIST_DIRECTORY,
10341042 windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE | windows.FILE_SHARE_WRITE,
......@@ -1037,15 +1045,8 @@ pub fn Watch(comptime V: type) type {
10371045 windows.FILE_FLAG_BACKUP_SEMANTICS | windows.FILE_FLAG_OVERLAPPED,
10381046 null,
10391047 );
1040 if (dir_handle == windows.INVALID_HANDLE_VALUE) {
1041 switch (windows.GetLastError()) {
1042 windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound,
1043 windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound,
1044 else => |err| return windows.unexpectedError(err),
1045 }
1046 }
10471048 var dir_handle_consumed = false;
1048 defer if (!dir_handle_consumed) os.close(dir_handle);
1049 defer if (!dir_handle_consumed) windows.CloseHandle(dir_handle);
10491050
10501051 const held = await (async self.os_data.table_lock.acquire() catch unreachable);
10511052 defer held.release();
......@@ -1124,7 +1125,7 @@ pub fn Watch(comptime V: type) type {
11241125 var event_buf: [4096]u8 align(@alignOf(windows.FILE_NOTIFY_INFORMATION)) = undefined;
11251126
11261127 // TODO handle this error not in the channel but in the setup
1127 _ = os.windowsCreateIoCompletionPort(
1128 _ = windows.CreateIoCompletionPort(
11281129 dir_handle,
11291130 self.channel.loop.os_data.io_port,
11301131 undefined,
......@@ -1140,10 +1141,10 @@ pub fn Watch(comptime V: type) type {
11401141 self.channel.loop.beginOneEvent();
11411142 errdefer self.channel.loop.finishOneEvent();
11421143 errdefer {
1143 _ = windows.CancelIoEx(dir_handle, &resume_node.base.overlapped);
1144 _ = windows.kernel32.CancelIoEx(dir_handle, &resume_node.base.overlapped);
11441145 }
11451146 suspend {
1146 _ = windows.ReadDirectoryChangesW(
1147 _ = windows.kernel32.ReadDirectoryChangesW(
11471148 dir_handle,
11481149 &event_buf,
11491150 @intCast(windows.DWORD, event_buf.len),
......@@ -1159,8 +1160,8 @@ pub fn Watch(comptime V: type) type {
11591160 }
11601161 }
11611162 var bytes_transferred: windows.DWORD = undefined;
1162 if (windows.GetOverlappedResult(dir_handle, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
1163 const err = switch (windows.GetLastError()) {
1163 if (windows.kernel32.GetOverlappedResult(dir_handle, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
1164 const err = switch (windows.kernel32.GetLastError()) {
11641165 else => |err| windows.unexpectedError(err),
11651166 };
11661167 await (async self.channel.put(err) catch unreachable);
std/fs/file.zig+14-8
......@@ -27,7 +27,7 @@ pub const File = struct {
2727
2828 /// Call close to clean up.
2929 pub fn openRead(path: []const u8) OpenError!File {
30 if (windows.is_the_target and !builtin.link_libc) {
30 if (windows.is_the_target) {
3131 const path_w = try windows.sliceToPrefixedFileW(path);
3232 return openReadW(&path_w);
3333 }
......@@ -37,7 +37,7 @@ pub const File = struct {
3737
3838 /// `openRead` except with a null terminated path
3939 pub fn openReadC(path: [*]const u8) OpenError!File {
40 if (windows.is_the_target and !builtin.link_libc) {
40 if (windows.is_the_target) {
4141 const path_w = try windows.cStrToPrefixedFileW(path);
4242 return openReadW(&path_w);
4343 }
......@@ -52,8 +52,10 @@ pub const File = struct {
5252 path_w,
5353 windows.GENERIC_READ,
5454 windows.FILE_SHARE_READ,
55 null,
5556 windows.OPEN_EXISTING,
5657 windows.FILE_ATTRIBUTE_NORMAL,
58 null,
5759 );
5860 return openHandle(handle);
5961 }
......@@ -67,7 +69,7 @@ pub const File = struct {
6769 /// If a file already exists in the destination it will be truncated.
6870 /// Call close to clean up.
6971 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {
70 if (windows.is_the_target and !builtin.link_libc) {
72 if (windows.is_the_target) {
7173 const path_w = try windows.sliceToPrefixedFileW(path);
7274 return openWriteModeW(&path_w, file_mode);
7375 }
......@@ -77,7 +79,7 @@ pub const File = struct {
7779
7880 /// Same as `openWriteMode` except `path` is null-terminated.
7981 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {
80 if (windows.is_the_target and !builtin.link_libc) {
82 if (windows.is_the_target) {
8183 const path_w = try windows.cStrToPrefixedFileW(path);
8284 return openWriteModeW(&path_w, file_mode);
8385 }
......@@ -92,8 +94,10 @@ pub const File = struct {
9294 path_w,
9395 windows.GENERIC_WRITE,
9496 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
97 null,
9598 windows.CREATE_ALWAYS,
9699 windows.FILE_ATTRIBUTE_NORMAL,
100 null,
97101 );
98102 return openHandle(handle);
99103 }
......@@ -102,7 +106,7 @@ pub const File = struct {
102106 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists
103107 /// Call close to clean up.
104108 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {
105 if (windows.is_the_target and !builtin.link_libc) {
109 if (windows.is_the_target) {
106110 const path_w = try windows.sliceToPrefixedFileW(path);
107111 return openWriteNoClobberW(&path_w, file_mode);
108112 }
......@@ -111,7 +115,7 @@ pub const File = struct {
111115 }
112116
113117 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {
114 if (windows.is_the_target and !builtin.link_libc) {
118 if (windows.is_the_target) {
115119 const path_w = try windows.cStrToPrefixedFileW(path);
116120 return openWriteNoClobberW(&path_w, file_mode);
117121 }
......@@ -125,8 +129,10 @@ pub const File = struct {
125129 path_w,
126130 windows.GENERIC_WRITE,
127131 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
132 null,
128133 windows.CREATE_NEW,
129134 windows.FILE_ATTRIBUTE_NORMAL,
135 null,
130136 );
131137 return openHandle(handle);
132138 }
......@@ -198,7 +204,7 @@ pub const File = struct {
198204 }
199205
200206 pub fn getEndPos(self: File) GetPosError!u64 {
201 if (windows.is_the_target and !builtin.link_libc) {
207 if (windows.is_the_target) {
202208 return windows.GetFileSizeEx(self.handle);
203209 }
204210 const stat = try os.fstat(self.handle);
......@@ -208,7 +214,7 @@ pub const File = struct {
208214 pub const ModeError = os.FStatError;
209215
210216 pub fn mode(self: File) ModeError!Mode {
211 if (windows.is_the_target and !builtin.link_libc) {
217 if (windows.is_the_target) {
212218 return {};
213219 }
214220 const stat = try os.fstat(self.handle);
std/os.zig+9-7
......@@ -70,7 +70,7 @@ pub const errno = system.getErrno;
7070/// must call `fsync` before `close`.
7171/// Note: The Zig standard library does not support POSIX thread cancellation.
7272pub fn close(fd: fd_t) void {
73 if (windows.is_the_target and !builtin.link_libc) {
73 if (windows.is_the_target) {
7474 return windows.CloseHandle(fd);
7575 }
7676 if (wasi.is_the_target) {
......@@ -236,7 +236,7 @@ pub const ReadError = error{
236236/// This function is for blocking file descriptors only. For non-blocking, see
237237/// `readAsync`.
238238pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
239 if (windows.is_the_target and !builtin.link_libc) {
239 if (windows.is_the_target) {
240240 return windows.ReadFile(fd, buf);
241241 }
242242
......@@ -363,7 +363,7 @@ pub const WriteError = error{
363363/// This function is for blocking file descriptors only. For non-blocking, see
364364/// `writeAsync`.
365365pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
366 if (windows.is_the_target and !builtin.link_libc) {
366 if (windows.is_the_target) {
367367 return windows.WriteFile(fd, bytes);
368368 }
369369
......@@ -1736,7 +1736,7 @@ pub const FStatError = error{
17361736pub fn fstat(fd: fd_t) FStatError!Stat {
17371737 var stat: Stat = undefined;
17381738 if (darwin.is_the_target) {
1739 switch (errno(system.@"fstat$INODE64"(fd, &stat))) {
1739 switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) {
17401740 0 => return stat,
17411741 EBADF => unreachable, // Always a race condition.
17421742 ENOMEM => return error.SystemResources,
......@@ -2265,7 +2265,7 @@ pub const RealPathError = error{
22652265/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.
22662266/// See also `realpathC` and `realpathW`.
22672267pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2268 if (windows.is_the_target and !builtin.link_libc) {
2268 if (windows.is_the_target) {
22692269 const pathname_w = try windows.sliceToPrefixedFileW(pathname);
22702270 return realpathW(&pathname_w, out_buffer);
22712271 }
......@@ -2275,12 +2275,12 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
22752275
22762276/// Same as `realpath` except `pathname` is null-terminated.
22772277pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2278 if (windows.is_the_target and !builtin.link_libc) {
2278 if (windows.is_the_target) {
22792279 const pathname_w = try windows.cStrToPrefixedFileW(pathname);
22802280 return realpathW(&pathname_w, out_buffer);
22812281 }
22822282 if (linux.is_the_target and !builtin.link_libc) {
2283 const fd = try openC(pathname, O_PATH | O_NONBLOCK | O_CLOEXEC, 0);
2283 const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);
22842284 defer close(fd);
22852285
22862286 var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
......@@ -2310,8 +2310,10 @@ pub fn realpathW(pathname: [*]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPa
23102310 pathname,
23112311 windows.GENERIC_READ,
23122312 windows.FILE_SHARE_READ,
2313 null,
23132314 windows.OPEN_EXISTING,
23142315 windows.FILE_ATTRIBUTE_NORMAL,
2316 null,
23152317 );
23162318 defer windows.CloseHandle(h_file);
23172319
std/os/bits/windows.zig+7-2
......@@ -5,6 +5,8 @@ use @import("../windows/bits.zig");
55pub const fd_t = HANDLE;
66pub const pid_t = HANDLE;
77
8pub const PATH_MAX = 260;
9
810pub const time_t = c_longlong;
911
1012pub const timespec = extern struct {
......@@ -153,10 +155,13 @@ pub const ETIME = 137;
153155pub const ETIMEDOUT = 138;
154156pub const ETXTBSY = 139;
155157pub const EWOULDBLOCK = 140;
158pub const EDQUOT = 10069;
159
160pub const F_OK = 0;
156161
157162// These are workarounds for "use of undeclared identifier" compile errors
158163// TODO make the compiler even more lazy. don't emit "use of undeclared identifier" errors
159164// for if branches that aren't taken.
160165pub const SIGKILL = @compileError("Windows libc does not have this");
161pub const EDQUOT = @compileError("Windows libc does not have this");
162pub const F_OK = 0;
166
167
std/os/windows.zig+6-2
......@@ -48,21 +48,25 @@ pub fn CreateFile(
4848 file_path: []const u8,
4949 desired_access: DWORD,
5050 share_mode: DWORD,
51 lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
5152 creation_disposition: DWORD,
5253 flags_and_attrs: DWORD,
54 hTemplateFile: ?HANDLE,
5355) CreateFileError!HANDLE {
5456 const file_path_w = try sliceToPrefixedFileW(file_path);
55 return CreateFileW(&file_path_w, desired_access, share_mode, creation_disposition, flags_and_attrs);
57 return CreateFileW(&file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile);
5658}
5759
5860pub fn CreateFileW(
5961 file_path_w: [*]const u16,
6062 desired_access: DWORD,
6163 share_mode: DWORD,
64 lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
6265 creation_disposition: DWORD,
6366 flags_and_attrs: DWORD,
67 hTemplateFile: ?HANDLE,
6468) CreateFileError!HANDLE {
65 const result = kernel32.CreateFileW(file_path_w, desired_access, share_mode, null, creation_disposition, flags_and_attrs, null);
69 const result = kernel32.CreateFileW(file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile);
6670
6771 if (result == INVALID_HANDLE_VALUE) {
6872 switch (kernel32.GetLastError()) {