Skip to content

Commit

Permalink
self-hosted compiler works on windows
Browse files Browse the repository at this point in the history
 * better error message for realpath failing
 * fix bug in std.io.readFileAllocExtra incorrectly returning
   error.EndOfStream
 * implement std.os.selfExePath and std.os.selfExeDirPath for windows
  • Loading branch information
andrewrk committed Jan 4, 2018
1 parent 0cd63b2 commit e1c03d9
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src-self-hosted/module.zig
Expand Up @@ -208,7 +208,7 @@ pub const Module = struct {

const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path");
const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| {
%return printError("unable to open '{}': {}", root_src_path, err);
%return printError("unable to get real path '{}': {}", root_src_path, err);
return err;
};
%defer self.allocator.free(root_src_real_path);
Expand Down
2 changes: 1 addition & 1 deletion std/io.zig
Expand Up @@ -513,7 +513,7 @@ pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len
%defer allocator.free(buf);

var adapter = FileInStream.init(&file);
%return adapter.stream.readNoEof(buf);
%return adapter.stream.readNoEof(buf[0..size]);
return buf;
}

Expand Down
51 changes: 38 additions & 13 deletions std/os/index.zig
Expand Up @@ -1544,6 +1544,40 @@ pub fn openSelfExe() -> %io.File {
}
}

/// Get the path to the current executable.
/// If you only need the directory, use selfExeDirPath.
/// If you only want an open file handle, use openSelfExe.
/// This function may return an error if the current executable
/// was deleted after spawning.
/// Caller owns returned memory.
pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
switch (builtin.os) {
Os.linux => {
@compileError("TODO: selfExePath for linux");
},
Os.windows => {
var out_path = %return Buffer.initSize(allocator, 256);
%defer out_path.deinit();
while (true) {
const dword_len = %return math.cast(windows.DWORD, out_path.len());
const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len);
if (copied_amt <= 0) {
const err = windows.GetLastError();
return switch (err) {
else => unexpectedErrorWindows(err),
};
}
if (copied_amt < out_path.len()) {
out_path.shrink(copied_amt);
return out_path.toOwnedSlice();
}
%return out_path.resize(out_path.len() * 2);
}
},
else => @compileError("Unsupported OS"),
}
}

/// Get the directory path that contains the current executable.
/// Caller owns returned memory.
pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
Expand All @@ -1559,19 +1593,10 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
return allocator.shrink(u8, full_exe_path, dir.len);
},
Os.windows => {
@panic("TODO windows std.os.selfExeDirPath");
//buf_resize(out_path, 256);
//for (;;) {
// DWORD copied_amt = GetModuleFileName(nullptr, buf_ptr(out_path), buf_len(out_path));
// if (copied_amt <= 0) {
// return ErrorFileNotFound;
// }
// if (copied_amt < buf_len(out_path)) {
// buf_resize(out_path, copied_amt);
// return 0;
// }
// buf_resize(out_path, buf_len(out_path) * 2);
//}
const self_exe_path = %return selfExePath(allocator);
%defer allocator.free(self_exe_path);
const dirname = os.path.dirname(self_exe_path);
return allocator.shrink(u8, self_exe_path, dirname.len);
},
else => @compileError("unimplemented: std.os.selfExeDirPath for " ++ @tagName(builtin.os)),
}
Expand Down
2 changes: 2 additions & 0 deletions std/os/windows/index.zig
Expand Up @@ -48,6 +48,8 @@ pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCo

pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: &LARGE_INTEGER) -> BOOL;

pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) -> DWORD;

pub extern "kernel32" stdcallcc fn GetLastError() -> DWORD;

pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,
Expand Down

0 comments on commit e1c03d9

Please sign in to comment.