Commit 627618a38d

daurnimator <quae@daurnimator.com>
2020-01-15 09:11:54
std: add Dir.changeDir as wrapper around fchdir
1 parent dfb420e
Changed files (4)
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));
 }
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;
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);
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,