commit 627618a38d291d9cc76c8e30e33cad60dc26cf11 (tree)
parent dfb420e6d779b9b6d60a277401aadba2800e3572
Author: daurnimator <quae@daurnimator.com>
Date: Wed, 15 Jan 2020 18:11:54 +1000
std: add Dir.changeDir as wrapper around fchdir
Diffstat:
4 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/lib/std/c.zig b/lib/std/c.zig
@@ -105,6 +105,7 @@ pub extern "c" fn mkdirat(dirfd: fd_t, path: [*:0]const u8, mode: u32) c_int;
pub extern "c" fn symlink(existing: [*:0]const u8, new: [*:0]const u8) c_int;
pub extern "c" fn rename(old: [*:0]const u8, new: [*:0]const u8) c_int;
pub extern "c" fn chdir(path: [*:0]const u8) c_int;
+pub extern "c" fn fchdir(fd: fd_t) c_int;
pub extern "c" fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) c_int;
pub extern "c" fn dup(fd: fd_t) c_int;
pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int;
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
@@ -890,6 +890,10 @@ pub const Dir = struct {
try os.mkdiratC(self.fd, sub_path, default_new_dir_mode);
}
+ pub fn changeTo(self: Dir) !void {
+ try os.fchdir(self.fd);
+ }
+
/// Deprecated; call `openDirList` directly.
pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {
return self.openDirList(sub_path);
diff --git a/lib/std/os.zig b/lib/std/os.zig
@@ -1706,6 +1706,20 @@ pub fn chdirC(dir_path: [*:0]const u8) ChangeCurDirError!void {
}
}
+pub fn fchdir(dirfd: fd_t) ChangeCurDirError!void {
+ while (true) {
+ switch (errno(system.fchdir(dirfd))) {
+ 0 => return,
+ EACCES => return error.AccessDenied,
+ EBADF => unreachable,
+ ENOTDIR => return error.NotDir,
+ EINTR => continue,
+ EIO => return error.FileSystem,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+}
+
pub const ReadLinkError = error{
AccessDenied,
FileSystem,
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
@@ -76,6 +76,10 @@ pub fn chdir(path: [*:0]const u8) usize {
return syscall1(SYS_chdir, @ptrToInt(path));
}
+pub fn fchdir(fd: fd_t) usize {
+ return syscall1(SYS_fchdir, @bitCast(usize, @as(isize, fd)));
+}
+
pub fn chroot(path: [*:0]const u8) usize {
return syscall1(SYS_chroot, @ptrToInt(path));
}