diff --git a/lib/std/c.zig b/lib/std/c.zig index 4eb271c87cdf60b08a934b5e41249fb2ed808fbb..79a6c07c02f8e549cbcb00ed642eeab8a530e3b4 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -101,6 +101,7 @@ pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flag pub extern "c" fn pipe(fds: *[2]fd_t) c_int; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int; +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; diff --git a/lib/std/os.zig b/lib/std/os.zig index 969e6407a6c15aeec7abac6d321083d077bd9991..f97676a821d9e69c9036d93945adf731974783a6 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1542,6 +1542,41 @@ pub const MakeDirError = error{ BadPathName, } || UnexpectedError; +pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void { + if (builtin.os == .windows) { + const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path); + @compileError("TODO implement mkdirat for Windows"); + } else { + const sub_dir_path_c = try toPosixPath(sub_dir_path); + return mkdiratC(dir_fd, &sub_dir_path_c, mode); + } +} + +pub fn mkdiratC(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void { + if (builtin.os == .windows) { + const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path); + @compileError("TODO implement mkdiratC for Windows"); + } + switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) { + 0 => return, + EACCES => return error.AccessDenied, + EBADF => unreachable, + EPERM => return error.AccessDenied, + EDQUOT => return error.DiskQuota, + EEXIST => return error.PathAlreadyExists, + EFAULT => unreachable, + ELOOP => return error.SymLinkLoop, + EMLINK => return error.LinkQuotaExceeded, + ENAMETOOLONG => return error.NameTooLong, + ENOENT => return error.FileNotFound, + ENOMEM => return error.SystemResources, + ENOSPC => return error.NoSpaceLeft, + ENOTDIR => return error.NotDir, + EROFS => return error.ReadOnlyFileSystem, + else => |err| return unexpectedErrno(err), + } +} + /// Create a directory. /// `mode` is ignored on Windows. pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {