diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2020-07-31 00:54:33 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2020-07-31 16:41:25 +0200 |
| commit | 4d9eff4bdb368dd4dad99b6b19c83468607cd1d2 (patch) | |
| tree | 49b95454ae4485624d4dc145255f7a6f586c6d3a /lib/std/os.zig | |
| parent | a694f575adbe4ca6852cc7c9022101ebcfc3a8d7 (diff) | |
| download | zig-4d9eff4bdb368dd4dad99b6b19c83468607cd1d2.tar.gz zig-4d9eff4bdb368dd4dad99b6b19c83468607cd1d2.zip | |
Add prelim `openW` and `openatW`
Added POSIX functions targeting Windows pass `open` and `openat`
smoke tests.
Diffstat (limited to 'lib/std/os.zig')
| -rw-r--r-- | lib/std/os.zig | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index 0a21c98808..7e4125e3a2 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1041,6 +1041,9 @@ pub const OpenError = error{ /// The underlying filesystem does not support file locks FileLocksNotSupported, + + BadPathName, + InvalidUtf8, } || UnexpectedError; /// Open and possibly create a file. Keeps trying if it gets interrupted. @@ -1092,18 +1095,65 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t } } +fn openOptionsFromFlags(flags: u32) windows.OpenFileOptions { + const w = windows; + + var access_mask: w.ULONG = w.READ_CONTROL | w.FILE_WRITE_ATTRIBUTES | w.SYNCHRONIZE; + if (flags & O_RDWR != 0) { + access_mask |= w.GENERIC_READ | w.GENERIC_WRITE; + } else if (flags & O_WRONLY != 0) { + access_mask |= w.GENERIC_WRITE; + } else { + access_mask |= w.GENERIC_READ | w.GENERIC_WRITE; + } + + const open_dir: bool = flags & O_DIRECTORY != 0; + const follow_symlinks: bool = flags & O_NOFOLLOW == 0; + + const creation: w.ULONG = blk: { + if (flags & O_CREAT != 0) { + if (flags & O_EXCL != 0) { + break :blk w.FILE_CREATE; + } + } + break :blk w.FILE_OPEN; + }; + + return .{ + .access_mask = access_mask, + .io_mode = .blocking, + .creation = creation, + .open_dir = open_dir, + .follow_symlinks = follow_symlinks, + }; +} + /// Windows-only. The path parameter is /// [WTF-16](https://simonsapin.github.io/wtf-8/#potentially-ill-formed-utf-16) encoded. /// Translates the POSIX open API call to a Windows API call. -pub fn openW(file_path_w: []const u16, flags: u32, perm: usize) OpenError!fd_t { - @compileError("TODO implement openW for windows"); +/// TODO currently, this function does not handle all flag combinations +/// or makes use of perm argument. +pub fn openW(file_path_w: []const u16, flags: u32, perm: mode_t) OpenError!fd_t { + var options = openOptionsFromFlags(flags); + options.dir = std.fs.cwd().fd; + return windows.OpenFile(file_path_w, options) catch |err| switch (err) { + error.WouldBlock => unreachable, + error.PipeBusy => unreachable, + else => |e| return e, + }; } /// Open and possibly create a file. Keeps trying if it gets interrupted. /// `file_path` is relative to the open directory handle `dir_fd`. /// See also `openatC`. -/// TODO support windows pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: mode_t) OpenError!fd_t { + if (builtin.os.tag == .wasi) { + @compileError("use openatWasi instead"); + } + if (builtin.os.tag == .windows) { + const file_path_w = try windows.sliceToPrefixedFileW(file_path); + return openatW(dir_fd, file_path_w.span(), flags, mode); + } const file_path_c = try toPosixPath(file_path); return openatZ(dir_fd, &file_path_c, flags, mode); } @@ -1145,8 +1195,11 @@ pub const openatC = @compileError("deprecated: renamed to openatZ"); /// Open and possibly create a file. Keeps trying if it gets interrupted. /// `file_path` is relative to the open directory handle `dir_fd`. /// See also `openat`. -/// TODO support windows pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t) OpenError!fd_t { + if (builtin.os.tag == .windows) { + const file_path_w = try windows.cStrToPrefixedFileW(file_path); + return openatW(dir_fd, file_path_w.span(), flags, mode); + } while (true) { const rc = system.openat(dir_fd, file_path, flags, mode); switch (errno(rc)) { @@ -1177,6 +1230,20 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t) } } +/// Windows-only. Similar to `openat` but with pathname argument null-terminated +/// WTF16 encoded. +/// TODO currently, this function does not handle all flag combinations +/// or makes use of perm argument. +pub fn openatW(dir_fd: fd_t, file_path_w: []const u16, flags: u32, mode: mode_t) OpenError!fd_t { + var options = openOptionsFromFlags(flags); + options.dir = dir_fd; + return windows.OpenFile(file_path_w, options) catch |err| switch (err) { + error.WouldBlock => unreachable, + error.PipeBusy => unreachable, + else => |e| return e, + }; +} + pub fn dup2(old_fd: fd_t, new_fd: fd_t) !void { while (true) { switch (errno(system.dup2(old_fd, new_fd))) { |
