From 627618a38d291d9cc76c8e30e33cad60dc26cf11 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 15 Jan 2020 18:11:54 +1000 Subject: [PATCH] std: add Dir.changeDir as wrapper around fchdir --- lib/std/c.zig | 1 + lib/std/fs.zig | 4 ++++ lib/std/os.zig | 14 ++++++++++++++ lib/std/os/linux.zig | 4 ++++ 4 files changed, 23 insertions(+) diff --git a/lib/std/c.zig b/lib/std/c.zig index 79a6c07c0..84a9e92de 100644 --- 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 index f245ab348..f9c7071ab 100644 --- 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 index f97676a82..7563a34f2 100644 --- 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 index de2ff5871..719e54184 100644 --- 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)); }