Commit 0307dc0b77

Andrew Kelley <superjoe30@gmail.com>
2017-10-14 22:59:43
organize windows utility functions
1 parent a68dc65
Changed files (3)
std/os/windows/util.zig
@@ -0,0 +1,112 @@
+const std = @import("../../index.zig");
+const windows = std.os.windows;
+const assert = std.debug.assert;
+const mem = std.mem;
+
+error WaitAbandoned;
+error WaitTimeOut;
+
+pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) -> %void {
+    const result = windows.WaitForSingleObject(handle, milliseconds);
+    return switch (result) {
+        windows.WAIT_ABANDONED => error.WaitAbandoned,
+        windows.WAIT_OBJECT_0 => {},
+        windows.WAIT_TIMEOUT => error.WaitTimeOut,
+        windows.WAIT_FAILED => switch (windows.GetLastError()) {
+            else => error.Unexpected,
+        },
+        else => error.Unexpected,
+    };
+}
+
+pub fn windowsClose(handle: windows.HANDLE) {
+    assert(windows.CloseHandle(handle));
+}
+
+error SystemResources;
+error OperationAborted;
+error IoPending;
+error BrokenPipe;
+
+pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {
+    if (!windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null)) {
+        return switch (windows.GetLastError()) {
+            windows.ERROR.INVALID_USER_BUFFER => error.SystemResources,
+            windows.ERROR.NOT_ENOUGH_MEMORY => error.SystemResources,
+            windows.ERROR.OPERATION_ABORTED => error.OperationAborted,
+            windows.ERROR.NOT_ENOUGH_QUOTA => error.SystemResources,
+            windows.ERROR.IO_PENDING => error.IoPending,
+            windows.ERROR.BROKEN_PIPE => error.BrokenPipe,
+            else => error.Unexpected,
+        };
+    }
+}
+
+pub fn windowsIsTty(handle: windows.HANDLE) -> bool {
+    if (windowsIsCygwinPty(handle))
+        return true;
+
+    var out: windows.DWORD = undefined;
+    return windows.GetConsoleMode(handle, &out);
+}
+
+pub fn windowsIsCygwinPty(handle: windows.HANDLE) -> bool {
+    const size = @sizeOf(windows.FILE_NAME_INFO);
+    var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
+
+    if (!windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo,
+        @ptrCast(&c_void, &name_info_bytes[0]), u32(name_info_bytes.len)))
+    {
+        return true;
+    }
+
+    const name_info = @ptrCast(&const windows.FILE_NAME_INFO, &name_info_bytes[0]);
+    const name_bytes = name_info_bytes[size..size + usize(name_info.FileNameLength)];
+    const name_wide  = ([]u16)(name_bytes);
+    return mem.indexOf(u16, name_wide, []u16{'m','s','y','s','-'}) != null or
+           mem.indexOf(u16, name_wide, []u16{'-','p','t','y'}) != null;
+}
+
+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;
+}
std/os/index.zig
@@ -25,6 +25,14 @@ pub const page_size = 4 * 1024;
 pub const UserInfo = @import("get_user_id.zig").UserInfo;
 pub const getUserInfo = @import("get_user_id.zig").getUserInfo;
 
+const windows_util = @import("windows/util.zig");
+pub const windowsClose = windows_util.windowsClose;
+pub const windowsWaitSingle = windows_util.windowsWaitSingle;
+pub const windowsWrite = windows_util.windowsWrite;
+pub const windowsIsTty = windows_util.windowsIsTty;
+pub const windowsIsCygwinPty = windows_util.windowsIsCygwinPty;
+pub const windowsOpen = windows_util.windowsOpen;
+
 const debug = @import("../debug.zig");
 const assert = debug.assert;
 
@@ -162,10 +170,6 @@ 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;
@@ -223,50 +227,6 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {
     }
 }
 
-error SystemResources;
-error OperationAborted;
-error IoPending;
-error BrokenPipe;
-
-pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {
-    if (!windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null)) {
-        return switch (windows.GetLastError()) {
-            windows.ERROR.INVALID_USER_BUFFER => error.SystemResources,
-            windows.ERROR.NOT_ENOUGH_MEMORY => error.SystemResources,
-            windows.ERROR.OPERATION_ABORTED => error.OperationAborted,
-            windows.ERROR.NOT_ENOUGH_QUOTA => error.SystemResources,
-            windows.ERROR.IO_PENDING => error.IoPending,
-            windows.ERROR.BROKEN_PIPE => error.BrokenPipe,
-            else => error.Unexpected,
-        };
-    }
-}
-
-pub fn windowsIsTty(handle: windows.HANDLE) -> bool {
-    if (windowsIsCygwinPty(handle))
-        return true;
-
-    var out: windows.DWORD = undefined;
-    return windows.GetConsoleMode(handle, &out);
-}
-
-pub fn windowsIsCygwinPty(handle: windows.HANDLE) -> bool {
-    const size = @sizeOf(windows.FILE_NAME_INFO);
-    var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
-
-    if (!windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo,
-        @ptrCast(&c_void, &name_info_bytes[0]), u32(name_info_bytes.len)))
-    {
-        return true;
-    }
-
-    const name_info = @ptrCast(&const windows.FILE_NAME_INFO, &name_info_bytes[0]);
-    const name_bytes = name_info_bytes[size..size + usize(name_info.FileNameLength)];
-    const name_wide  = ([]u16)(name_bytes);
-    return mem.indexOf(u16, name_wide, []u16{'m','s','y','s','-'}) != null or
-           mem.indexOf(u16, name_wide, []u16{'-','p','t','y'}) != null;
-}
-
 /// ::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.
@@ -322,51 +282,6 @@ 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));
@@ -1394,22 +1309,6 @@ fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const
     assert(it.next(&debug.global_allocator) == null);
 }
 
-error WaitAbandoned;
-error WaitTimeOut;
-
-pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) -> %void {
-    const result = windows.WaitForSingleObject(handle, milliseconds);
-    return switch (result) {
-        windows.WAIT_ABANDONED => error.WaitAbandoned,
-        windows.WAIT_OBJECT_0 => {},
-        windows.WAIT_TIMEOUT => error.WaitTimeOut,
-        windows.WAIT_FAILED => switch (windows.GetLastError()) {
-            else => error.Unexpected,
-        },
-        else => error.Unexpected,
-    };
-}
-
 test "std.os" {
     _ = @import("child_process.zig");
     _ = @import("darwin_errno.zig");
CMakeLists.txt
@@ -581,6 +581,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_x86_64.zig" DESTINATION "${ZIG_S
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/path.zig" DESTINATION "${ZIG_STD_DEST}/os")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/error.zig" DESTINATION "${ZIG_STD_DEST}/os/windows")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/index.zig" DESTINATION "${ZIG_STD_DEST}/os/windows")
+install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/util.zig" DESTINATION "${ZIG_STD_DEST}/os/windows")
 install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")