aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2020-01-15 18:07:08 +1000
committerAndrew Kelley <andrew@ziglang.org>2020-03-03 13:25:40 -0500
commit88e27f01c8dbf4bda5726c93d12cc4a1d174989d (patch)
tree57428a44a7e5c7c50c4f1583d020f669e73568fd /lib
parent582db68a157520a0cf7777807f466d1f6a2e31e7 (diff)
downloadzig-88e27f01c8dbf4bda5726c93d12cc4a1d174989d.tar.gz
zig-88e27f01c8dbf4bda5726c93d12cc4a1d174989d.zip
std: add mkdirat
Diffstat (limited to 'lib')
-rw-r--r--lib/std/c.zig1
-rw-r--r--lib/std/os.zig35
2 files changed, 36 insertions, 0 deletions
diff --git a/lib/std/c.zig b/lib/std/c.zig
index 4eb271c87c..79a6c07c02 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 969e6407a6..f97676a821 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 {