aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorg-w1 <58830309+g-w1@users.noreply.github.com>2020-11-18 02:42:35 -0500
committerGitHub <noreply@github.com>2020-11-18 08:42:35 +0100
commita0226ab05b50341622ace8314bdad3da7cd7e35d (patch)
treef200ba0b5dd6aacde4428b13f19f5c6ab5743b45 /lib
parent238718b93abfe97bd5531103cf39714ec66fd86e (diff)
downloadzig-a0226ab05b50341622ace8314bdad3da7cd7e35d.tar.gz
zig-a0226ab05b50341622ace8314bdad3da7cd7e35d.zip
std: openDirAbsolute and accessAbsolute (#7082)
* add more abosolutes * added wrong files * adding 2 tests and changing the function signatures because of lazy analysis not checking them * fix a bug that got uncovered by lazy eval * Add compile error when using WASI with openDirAbsolute and accessAbsolute * typo
Diffstat (limited to 'lib')
-rw-r--r--lib/std/fs.zig64
-rw-r--r--lib/std/fs/test.zig34
-rw-r--r--lib/std/os.zig6
3 files changed, 99 insertions, 5 deletions
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
index 4258b7a72c..0b69c6e533 100644
--- a/lib/std/fs.zig
+++ b/lib/std/fs.zig
@@ -1883,11 +1883,41 @@ pub fn cwd() Dir {
}
}
+/// Opens a directory at the given path. The directory is a system resource that remains
+/// open until `close` is called on the result.
+/// See `openDirAbsoluteZ` for a function that accepts a null-terminated path.
+///
+/// Asserts that the path parameter has no null bytes.
+pub fn openDirAbsolute(absolute_path: []const u8, flags: Dir.OpenDirOptions) File.OpenError!Dir {
+ if (builtin.os.tag == .wasi) {
+ @compileError("WASI doesn't have the concept of an absolute directory; use openDir instead for WASI.");
+ }
+ assert(path.isAbsolute(absolute_path));
+ return cwd().openDir(absolute_path, flags);
+}
+
+/// Same as `openDirAbsolute` but the path parameter is null-terminated.
+pub fn openDirAbsoluteZ(absolute_path_c: [*:0]const u8, flags: Dir.OpenDirOptions) File.OpenError!Dir {
+ if (builtin.os.tag == .wasi) {
+ @compileError("WASI doesn't have the concept of an absolute directory; use openDir instead for WASI.");
+ }
+ assert(path.isAbsoluteZ(absolute_path_c));
+ return cwd().openDirZ(absolute_path_c, flags);
+}
+/// Same as `openDirAbsolute` but the path parameter is null-terminated.
+pub fn openDirAbsoluteW(absolute_path_c: [*:0]const u16, flags: Dir.OpenDirOptions) File.OpenError!Dir {
+ if (builtin.os.tag == .wasi) {
+ @compileError("WASI doesn't have the concept of an absolute directory; use openDir instead for WASI.");
+ }
+ assert(path.isAbsoluteWindowsW(absolute_path_c));
+ return cwd().openDirW(absolute_path_c, flags);
+}
+
/// Opens a file for reading or writing, without attempting to create a new file, based on an absolute path.
/// Call `File.close` to release the resource.
/// Asserts that the path is absolute. See `Dir.openFile` for a function that
/// operates on both absolute and relative paths.
-/// Asserts that the path parameter has no null bytes. See `openFileAbsoluteC` for a function
+/// Asserts that the path parameter has no null bytes. See `openFileAbsoluteZ` for a function
/// that accepts a null-terminated path.
pub fn openFileAbsolute(absolute_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
assert(path.isAbsolute(absolute_path));
@@ -1908,6 +1938,36 @@ pub fn openFileAbsoluteW(absolute_path_w: []const u16, flags: File.OpenFlags) Fi
return cwd().openFileW(absolute_path_w, flags);
}
+/// Test accessing `path`.
+/// `path` is UTF8-encoded.
+/// Be careful of Time-Of-Check-Time-Of-Use race conditions when using this function.
+/// For example, instead of testing if a file exists and then opening it, just
+/// open it and handle the error for file not found.
+/// See `accessAbsoluteZ` for a function that accepts a null-terminated path.
+pub fn accessAbsolute(absolute_path: []const u8, flags: File.OpenFlags) Dir.AccessError!void {
+ if (builtin.os.tag == .wasi) {
+ @compileError("WASI doesn't have the concept of an absolute path; use access instead for WASI.");
+ }
+ assert(path.isAbsolute(absolute_path));
+ try cwd().access(absolute_path, flags);
+}
+/// Same as `accessAbsolute` but the path parameter is null-terminated.
+pub fn accessAbsoluteZ(absolute_path: [*:0]const u8, flags: File.OpenFlags) Dir.AccessError!void {
+ if (builtin.os.tag == .wasi) {
+ @compileError("WASI doesn't have the concept of an absolute path; use access instead for WASI.");
+ }
+ assert(path.isAbsoluteZ(absolute_path));
+ try cwd().accessZ(absolute_path, flags);
+}
+/// Same as `accessAbsolute` but the path parameter is WTF-16 encoded.
+pub fn accessAbsoluteW(absolute_path: [*:0]const 16, flags: File.OpenFlags) Dir.AccessError!void {
+ if (builtin.os.tag == .wasi) {
+ @compileError("WASI doesn't have the concept of an absolute path; use access instead for WASI.");
+ }
+ assert(path.isAbsoluteWindowsW(absolute_path));
+ try cwd().accessW(absolute_path, flags);
+}
+
/// Creates, opens, or overwrites a file with write access, based on an absolute path.
/// Call `File.close` to release the resource.
/// Asserts that the path is absolute. See `Dir.createFile` for a function that
@@ -2252,7 +2312,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
const PATH = std.os.getenvZ("PATH") orelse return error.FileNotFound;
var path_it = mem.tokenize(PATH, &[_]u8{path.delimiter});
while (path_it.next()) |a_path| {
- var resolved_path_buf: [MAX_PATH_BYTES-1:0]u8 = undefined;
+ var resolved_path_buf: [MAX_PATH_BYTES - 1:0]u8 = undefined;
const resolved_path = std.fmt.bufPrintZ(&resolved_path_buf, "{s}/{s}", .{
a_path,
os.argv[0],
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
index 8c24265db8..5469192f6c 100644
--- a/lib/std/fs/test.zig
+++ b/lib/std/fs/test.zig
@@ -49,6 +49,40 @@ fn testReadLink(dir: Dir, target_path: []const u8, symlink_path: []const u8) !vo
testing.expect(mem.eql(u8, target_path, given));
}
+test "accessAbsolute" {
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
+
+ var tmp = tmpDir(.{});
+ defer tmp.cleanup();
+
+ var arena = ArenaAllocator.init(testing.allocator);
+ defer arena.deinit();
+ const base_path = blk: {
+ const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });
+ break :blk try fs.realpathAlloc(&arena.allocator, relative_path);
+ };
+
+ try fs.accessAbsolute(base_path, .{});
+}
+
+test "openDirAbsolute" {
+ if (builtin.os.tag == .wasi) return error.SkipZigTest;
+
+ var tmp = tmpDir(.{});
+ defer tmp.cleanup();
+
+ try tmp.dir.makeDir("subdir");
+ var arena = ArenaAllocator.init(testing.allocator);
+ defer arena.deinit();
+ const base_path = blk: {
+ const relative_path = try fs.path.join(&arena.allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..], "subdir" });
+ break :blk try fs.realpathAlloc(&arena.allocator, relative_path);
+ };
+
+ var dir = try fs.openDirAbsolute(base_path, .{});
+ defer dir.close();
+}
+
test "readLinkAbsolute" {
if (builtin.os.tag == .wasi) return error.SkipZigTest;
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 2ea26f8b1e..91b88304f7 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -4453,11 +4453,11 @@ pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
/// Used to convert a slice to a null terminated slice on the stack.
/// TODO https://github.com/ziglang/zig/issues/287
-pub fn toPosixPath(file_path: []const u8) ![PATH_MAX - 1:0]u8 {
+pub fn toPosixPath(file_path: []const u8) ![MAX_PATH_BYTES - 1:0]u8 {
if (std.debug.runtime_safety) assert(std.mem.indexOfScalar(u8, file_path, 0) == null);
- var path_with_null: [PATH_MAX - 1:0]u8 = undefined;
+ var path_with_null: [MAX_PATH_BYTES - 1:0]u8 = undefined;
// >= rather than > to make room for the null byte
- if (file_path.len >= PATH_MAX) return error.NameTooLong;
+ if (file_path.len >= MAX_PATH_BYTES) return error.NameTooLong;
mem.copy(u8, &path_with_null, file_path);
path_with_null[file_path.len] = 0;
return path_with_null;