aboutsummaryrefslogtreecommitdiff
path: root/std/os
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-10-09 15:59:10 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-10-09 15:59:10 -0400
commite6334fe46d29f3f9d488b80453cc5bd12ffb97ea (patch)
tree58dd5a7bd39dffaaa80a21379054d7354ffb6066 /std/os
parent055b856f13ce527a92b2b28760daabce41edd440 (diff)
downloadzig-e6334fe46d29f3f9d488b80453cc5bd12ffb97ea.tar.gz
zig-e6334fe46d29f3f9d488b80453cc5bd12ffb97ea.zip
implement std.io.InStream for windows
See #302
Diffstat (limited to 'std/os')
-rw-r--r--std/os/index.zig50
-rw-r--r--std/os/windows/index.zig2
2 files changed, 50 insertions, 2 deletions
diff --git a/std/os/index.zig b/std/os/index.zig
index 0a1b39d66d..be96f7f776 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -151,6 +151,10 @@ pub fn posixClose(fd: i32) {
}
}
+pub fn windowsClose(handle: windows.HANDLE) {
+ assert(windows.CloseHandle(handle));
+}
+
/// Calls POSIX read, and keeps trying if it gets interrupted.
pub fn posixRead(fd: i32, buf: []u8) -> %void {
var index: usize = 0;
@@ -299,6 +303,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
posix.ENOSPC => error.NoSpaceLeft,
posix.ENOTDIR => error.NotDir,
posix.EPERM => error.AccessDenied,
+ posix.EEXIST => error.PathAlreadyExists,
else => error.Unexpected,
}
}
@@ -306,6 +311,51 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
}
}
+
+error SharingViolation;
+error PipeBusy;
+
+/// `file_path` may need to be copied in memory to add a null terminating byte. In this case
+/// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed
+/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned.
+/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
+pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD,
+ creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD, allocator: ?&Allocator) -> %windows.HANDLE
+{
+ var stack_buf: [max_noalloc_path_len]u8 = undefined;
+ var path0: []u8 = undefined;
+ var need_free = false;
+ defer if (need_free) (??allocator).free(path0);
+
+ if (file_path.len < stack_buf.len) {
+ path0 = stack_buf[0..file_path.len + 1];
+ } else if (allocator) |a| {
+ path0 = %return a.alloc(u8, file_path.len + 1);
+ need_free = true;
+ } else {
+ return error.NameTooLong;
+ }
+ mem.copy(u8, path0, file_path);
+ path0[file_path.len] = 0;
+
+ const result = windows.CreateFileA(path0.ptr, desired_access, share_mode, null, creation_disposition,
+ flags_and_attrs, null);
+
+ if (result == windows.INVALID_HANDLE_VALUE) {
+ const err = windows.GetLastError();
+ return switch (err) {
+ windows.ERROR.SHARING_VIOLATION => error.SharingViolation,
+ windows.ERROR.ALREADY_EXISTS, windows.ERROR.FILE_EXISTS => error.PathAlreadyExists,
+ windows.ERROR.FILE_NOT_FOUND => error.FileNotFound,
+ windows.ERROR.ACCESS_DENIED => error.AccessDenied,
+ windows.ERROR.PIPE_BUSY => error.PipeBusy,
+ else => error.Unexpected,
+ };
+ }
+
+ return result;
+}
+
pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {
while (true) {
const err = posix.getErrno(posix.dup2(old_fd, new_fd));
diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig
index bf230a2a0d..a7ba338bf7 100644
--- a/std/os/windows/index.zig
+++ b/std/os/windows/index.zig
@@ -38,8 +38,6 @@ pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(hFile: HANDLE, lpsz
/// Retrieves a handle to the specified standard device (standard input, standard output, or standard error).
pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) -> ?HANDLE;
-/// Reads data from the specified file or input/output (I/O) device. Reads occur at the position specified by the file pointer if supported by the device.
-/// This function is designed for both synchronous and asynchronous operations. For a similar function designed solely for asynchronous operation, see ReadFileEx.
pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVOID,
in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD,
in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL;