fs: Use OpenMode enum instead of read/write flags.

This commit is contained in:
Sage Hane
2022-01-29 13:52:08 +00:00
committed by GitHub
parent 88edde4edc
commit e288148f60
8 changed files with 39 additions and 29 deletions

View File

@@ -45,7 +45,7 @@ pub fn main() !void {
}
}
var in_file = try fs.cwd().openFile(in_file_name, .{ .read = true });
var in_file = try fs.cwd().openFile(in_file_name, .{ .mode = .read_only });
defer in_file.close();
var out_file = try fs.cwd().createFile(out_file_name, .{});
@@ -1866,7 +1866,7 @@ test "shell parsed" {
// intentional space after "--build-option1 \"
const shell_out =
\\$ zig build test.zig \
\\ --build-option1 \
\\ --build-option1 \
\\ --build-option2
\\$ ./test
;

View File

@@ -79,7 +79,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
var buf: [32]u8 = undefined;
const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()});
const file = try std.fs.cwd().openFile(path, .{ .write = true });
const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only });
defer file.close();
try file.writer().writeAll(name);

View File

@@ -938,10 +938,10 @@ pub const Dir = struct {
const w = os.wasi;
var fdflags: w.fdflags_t = 0x0;
var base: w.rights_t = 0x0;
if (flags.read) {
if (flags.isRead()) {
base |= w.RIGHT.FD_READ | w.RIGHT.FD_TELL | w.RIGHT.FD_SEEK | w.RIGHT.FD_FILESTAT_GET;
}
if (flags.write) {
if (flags.isWrite()) {
fdflags |= w.FDFLAG.APPEND;
base |= w.RIGHT.FD_WRITE |
w.RIGHT.FD_TELL |
@@ -988,12 +988,11 @@ pub const Dir = struct {
if (!flags.allow_ctty) {
os_flags |= os.O.NOCTTY;
}
os_flags |= if (flags.write and flags.read)
@as(u32, os.O.RDWR)
else if (flags.write)
@as(u32, os.O.WRONLY)
else
@as(u32, os.O.RDONLY);
os_flags |= switch (flags.mode) {
.read_only => @as(u32, os.O.RDONLY),
.write_only => @as(u32, os.O.WRONLY),
.read_write => @as(u32, os.O.RDWR),
};
const fd = if (flags.intended_io_mode != .blocking)
try std.event.Loop.instance.?.openatZ(self.fd, sub_path, os_flags, 0)
else
@@ -1045,8 +1044,8 @@ pub const Dir = struct {
.handle = try w.OpenFile(sub_path_w, .{
.dir = self.fd,
.access_mask = w.SYNCHRONIZE |
(if (flags.read) @as(u32, w.GENERIC_READ) else 0) |
(if (flags.write) @as(u32, w.GENERIC_WRITE) else 0),
(if (flags.isRead()) @as(u32, w.GENERIC_READ) else 0) |
(if (flags.isWrite()) @as(u32, w.GENERIC_WRITE) else 0),
.creation = w.FILE_OPEN,
.io_mode = flags.intended_io_mode,
}),
@@ -2042,12 +2041,11 @@ pub const Dir = struct {
const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path);
return self.accessW(sub_path_w.span().ptr, flags);
}
const os_mode = if (flags.write and flags.read)
@as(u32, os.R_OK | os.W_OK)
else if (flags.write)
@as(u32, os.W_OK)
else
@as(u32, os.F_OK);
const os_mode = switch (flags.mode) {
.read_only => @as(u32, os.F_OK),
.write_only => @as(u32, os.W_OK),
.read_write => @as(u32, os.R_OK | os.W_OK),
};
const result = if (need_async_thread and flags.intended_io_mode != .blocking)
std.event.Loop.instance.?.faccessatZ(self.fd, sub_path, os_mode, 0)
else

View File

@@ -69,12 +69,17 @@ pub const File = struct {
Unexpected,
} || os.OpenError || os.FlockError;
pub const OpenMode = enum {
read_only,
write_only,
read_write,
};
pub const Lock = enum { None, Shared, Exclusive };
/// TODO https://github.com/ziglang/zig/issues/3802
pub const OpenFlags = struct {
read: bool = true,
write: bool = false,
mode: OpenMode = .read_only,
/// Open the file with an advisory lock to coordinate with other processes
/// accessing it at the same time. An exclusive lock will prevent other
@@ -118,6 +123,14 @@ pub const File = struct {
/// Set this to allow the opened file to automatically become the
/// controlling TTY for the current process.
allow_ctty: bool = false,
pub fn isRead(self: OpenFlags) bool {
return self.mode != .write_only;
}
pub fn isWrite(self: OpenFlags) bool {
return self.mode != .read_only;
}
};
/// TODO https://github.com/ziglang/zig/issues/3802

View File

@@ -319,9 +319,9 @@ test "file operations on directories" {
try testing.expectError(error.IsDir, tmp_dir.dir.readFileAlloc(testing.allocator, test_dir_name, std.math.maxInt(usize)));
},
}
// Note: The `.write = true` is necessary to ensure the error occurs on all platforms.
// Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms.
// TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732
try testing.expectError(error.IsDir, tmp_dir.dir.openFile(test_dir_name, .{ .write = true }));
try testing.expectError(error.IsDir, tmp_dir.dir.openFile(test_dir_name, .{ .mode = .read_write }));
switch (builtin.os.tag) {
.wasi, .freebsd, .netbsd, .openbsd, .dragonfly => {},

View File

@@ -678,7 +678,7 @@ fn testWriteWatchWriteDelete(allocator: Allocator) !void {
};
// overwrite line 2
const file = try std.fs.cwd().openFile(file_path, .{ .read = true, .write = true });
const file = try std.fs.cwd().openFile(file_path, .{ .mode = .read_write });
{
defer file.close();
const write_contents = "lorem ipsum";

View File

@@ -308,8 +308,7 @@ pub const Manifest = struct {
// comparing the hashes on the files used for the cached item
while (true) {
if (self.cache.manifest_dir.openFile(&manifest_file_path, .{
.read = true,
.write = true,
.mode = .read_write,
.lock = .Exclusive,
.lock_nonblocking = self.want_shared_lock,
})) |manifest_file| {
@@ -410,7 +409,7 @@ pub const Manifest = struct {
cache_hash_file.path = try self.cache.gpa.dupe(u8, file_path);
}
const this_file = fs.cwd().openFile(cache_hash_file.path.?, .{ .read = true }) catch |err| switch (err) {
const this_file = fs.cwd().openFile(cache_hash_file.path.?, .{ .mode = .read_only }) catch |err| switch (err) {
error.FileNotFound => {
try self.upgradeToExclusiveLock();
return false;

View File

@@ -958,14 +958,14 @@ pub const TestContext = struct {
switch (update.case) {
.Header => |expected_output| {
var file = try tmp.dir.openFile("test_case.h", .{ .read = true });
var file = try tmp.dir.openFile("test_case.h", .{ .mode = .read_only });
defer file.close();
const out = try file.reader().readAllAlloc(arena, 5 * 1024 * 1024);
try std.testing.expectEqualStrings(expected_output, out);
},
.CompareObjectFile => |expected_output| {
var file = try tmp.dir.openFile(bin_name, .{ .read = true });
var file = try tmp.dir.openFile(bin_name, .{ .mode = .read_only });
defer file.close();
const out = try file.reader().readAllAlloc(arena, 5 * 1024 * 1024);