| ... | ... | @@ -832,123 +832,10 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 { |
| 832 | 832 | } |
| 833 | 833 | } |
| 834 | 834 | |
| 835 | | /// On Windows, `sub_dir_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 836 | | /// On WASI, `sub_dir_path` should be encoded as valid UTF-8. |
| 837 | | /// On other platforms, `sub_dir_path` is an opaque sequence of bytes with no particular encoding. |
| 838 | | pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: mode_t) MakeDirError!void { |
| 839 | | if (native_os == .windows) { |
| 840 | | @compileError("use std.Io instead"); |
| 841 | | } else if (native_os == .wasi and !builtin.link_libc) { |
| 842 | | @compileError("use std.Io instead"); |
| 843 | | } else { |
| 844 | | const sub_dir_path_c = try toPosixPath(sub_dir_path); |
| 845 | | return mkdiratZ(dir_fd, &sub_dir_path_c, mode); |
| 846 | | } |
| 847 | | } |
| 848 | | |
| 849 | | /// Same as `mkdirat` except the parameters are null-terminated. |
| 850 | | pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void { |
| 851 | | if (native_os == .windows) { |
| 852 | | @compileError("use std.Io instead"); |
| 853 | | } else if (native_os == .wasi and !builtin.link_libc) { |
| 854 | | @compileError("use std.Io instead"); |
| 855 | | } |
| 856 | | switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) { |
| 857 | | .SUCCESS => return, |
| 858 | | .ACCES => return error.AccessDenied, |
| 859 | | .BADF => unreachable, |
| 860 | | .PERM => return error.PermissionDenied, |
| 861 | | .DQUOT => return error.DiskQuota, |
| 862 | | .EXIST => return error.PathAlreadyExists, |
| 863 | | .FAULT => unreachable, |
| 864 | | .LOOP => return error.SymLinkLoop, |
| 865 | | .MLINK => return error.LinkQuotaExceeded, |
| 866 | | .NAMETOOLONG => return error.NameTooLong, |
| 867 | | .NOENT => return error.FileNotFound, |
| 868 | | .NOMEM => return error.SystemResources, |
| 869 | | .NOSPC => return error.NoSpaceLeft, |
| 870 | | .NOTDIR => return error.NotDir, |
| 871 | | .ROFS => return error.ReadOnlyFileSystem, |
| 872 | | // dragonfly: when dir_fd is unlinked from filesystem |
| 873 | | .NOTCONN => return error.FileNotFound, |
| 874 | | .ILSEQ => return error.BadPathName, |
| 875 | | else => |err| return unexpectedErrno(err), |
| 876 | | } |
| 877 | | } |
| 878 | | |
| 879 | | pub const MakeDirError = std.Io.Dir.CreateDirError; |
| 880 | | |
| 881 | | /// Create a directory. |
| 882 | | /// `mode` is ignored on Windows and WASI. |
| 883 | | /// On Windows, `dir_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 884 | | /// On WASI, `dir_path` should be encoded as valid UTF-8. |
| 885 | | /// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding. |
| 886 | | pub fn mkdir(dir_path: []const u8, mode: mode_t) MakeDirError!void { |
| 887 | | if (native_os == .wasi and !builtin.link_libc) { |
| 888 | | return mkdirat(AT.FDCWD, dir_path, mode); |
| 889 | | } else if (native_os == .windows) { |
| 890 | | const dir_path_w = try windows.sliceToPrefixedFileW(null, dir_path); |
| 891 | | return mkdirW(dir_path_w.span(), mode); |
| 892 | | } else { |
| 893 | | const dir_path_c = try toPosixPath(dir_path); |
| 894 | | return mkdirZ(&dir_path_c, mode); |
| 895 | | } |
| 896 | | } |
| 897 | | |
| 898 | 835 | /// Same as `mkdir` but the parameter is null-terminated. |
| 899 | 836 | /// On Windows, `dir_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 900 | 837 | /// On WASI, `dir_path` should be encoded as valid UTF-8. |
| 901 | 838 | /// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding. |
| 902 | | pub fn mkdirZ(dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void { |
| 903 | | if (native_os == .windows) { |
| 904 | | const dir_path_w = try windows.cStrToPrefixedFileW(null, dir_path); |
| 905 | | return mkdirW(dir_path_w.span(), mode); |
| 906 | | } else if (native_os == .wasi and !builtin.link_libc) { |
| 907 | | return mkdir(mem.sliceTo(dir_path, 0), mode); |
| 908 | | } |
| 909 | | switch (errno(system.mkdir(dir_path, mode))) { |
| 910 | | .SUCCESS => return, |
| 911 | | .ACCES => return error.AccessDenied, |
| 912 | | .PERM => return error.PermissionDenied, |
| 913 | | .DQUOT => return error.DiskQuota, |
| 914 | | .EXIST => return error.PathAlreadyExists, |
| 915 | | .FAULT => unreachable, |
| 916 | | .LOOP => return error.SymLinkLoop, |
| 917 | | .MLINK => return error.LinkQuotaExceeded, |
| 918 | | .NAMETOOLONG => return error.NameTooLong, |
| 919 | | .NOENT => return error.FileNotFound, |
| 920 | | .NOMEM => return error.SystemResources, |
| 921 | | .NOSPC => return error.NoSpaceLeft, |
| 922 | | .NOTDIR => return error.NotDir, |
| 923 | | .ROFS => return error.ReadOnlyFileSystem, |
| 924 | | .ILSEQ => return error.BadPathName, |
| 925 | | else => |err| return unexpectedErrno(err), |
| 926 | | } |
| 927 | | } |
| 928 | | |
| 929 | | /// Windows-only. Same as `mkdir` but the parameters is WTF16LE encoded. |
| 930 | | pub fn mkdirW(dir_path_w: []const u16, mode: mode_t) MakeDirError!void { |
| 931 | | _ = mode; |
| 932 | | const sub_dir_handle = windows.OpenFile(dir_path_w, .{ |
| 933 | | .dir = Io.Dir.cwd().handle, |
| 934 | | .access_mask = .{ |
| 935 | | .STANDARD = .{ .SYNCHRONIZE = true }, |
| 936 | | .GENERIC = .{ .READ = true }, |
| 937 | | }, |
| 938 | | .creation = .CREATE, |
| 939 | | .filter = .dir_only, |
| 940 | | }) catch |err| switch (err) { |
| 941 | | error.IsDir => return error.Unexpected, |
| 942 | | error.PipeBusy => return error.Unexpected, |
| 943 | | error.NoDevice => return error.Unexpected, |
| 944 | | error.WouldBlock => return error.Unexpected, |
| 945 | | error.AntivirusInterference => return error.Unexpected, |
| 946 | | error.OperationCanceled => return error.Unexpected, |
| 947 | | else => |e| return e, |
| 948 | | }; |
| 949 | | windows.CloseHandle(sub_dir_handle); |
| 950 | | } |
| 951 | | |
| 952 | 839 | pub const ChangeCurDirError = error{ |
| 953 | 840 | AccessDenied, |
| 954 | 841 | FileSystem, |