diff --git a/lib/std/c.zig b/lib/std/c.zig index 79a6c07c02f8e549cbcb00ed642eeab8a530e3b4..84a9e92dee5e6a3ac721ac5dc813047321eb401c 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 f245ab348d3e5a4b0b5267f88f92665d8956b269..f9c7071abfd1226e0149dde8e2c308376e4e9092 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 f97676a821d9e69c9036d93945adf731974783a6..7563a34f21cfbbcda7daa884ca93f7a726859b0d 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 de2ff5871b3ef4e429baaac2b987e58e015ac115..719e541846f1435c845b4bed795b74b20280e164 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)); }