| ... | ... | @@ -1665,7 +1665,9 @@ pub const UnlinkError = error{ |
| 1665 | 1665 | /// Delete a name and possibly the file it refers to. |
| 1666 | 1666 | /// See also `unlinkC`. |
| 1667 | 1667 | pub fn unlink(file_path: []const u8) UnlinkError!void { |
| 1668 | | if (builtin.os.tag == .windows) { |
| 1668 | if (builtin.os.tag == .wasi) { |
| 1669 | @compileError("unlink is not supported in WASI; use unlinkat instead"); |
| 1670 | } else if (builtin.os.tag == .windows) { |
| 1669 | 1671 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); |
| 1670 | 1672 | return windows.DeleteFileW(file_path_w.span().ptr); |
| 1671 | 1673 | } else { |
| ... | ... | @@ -1722,6 +1724,8 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo |
| 1722 | 1724 | |
| 1723 | 1725 | pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ"); |
| 1724 | 1726 | |
| 1727 | /// WASI-only. Same as `unlinkat` but targeting WASI. |
| 1728 | /// See also `unlinkat`. |
| 1725 | 1729 | pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void { |
| 1726 | 1730 | const remove_dir = (flags & AT_REMOVEDIR) != 0; |
| 1727 | 1731 | const res = if (remove_dir) |
| ... | ... | @@ -1868,7 +1872,9 @@ const RenameError = error{ |
| 1868 | 1872 | |
| 1869 | 1873 | /// Change the name or location of a file. |
| 1870 | 1874 | pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { |
| 1871 | | if (builtin.os.tag == .windows) { |
| 1875 | if (builtin.os.tag == .wasi) { |
| 1876 | @compileError("rename is not supported in WASI; use renameat instead"); |
| 1877 | } else if (builtin.os.tag == .windows) { |
| 1872 | 1878 | const old_path_w = try windows.sliceToPrefixedFileW(old_path); |
| 1873 | 1879 | const new_path_w = try windows.sliceToPrefixedFileW(new_path); |
| 1874 | 1880 | return renameW(old_path_w.span().ptr, new_path_w.span().ptr); |
| ... | ... | @@ -1939,7 +1945,8 @@ pub fn renameat( |
| 1939 | 1945 | } |
| 1940 | 1946 | } |
| 1941 | 1947 | |
| 1942 | | /// Same as `renameat` expect only WASI. |
| 1948 | /// WASI-only. Same as `renameat` expect targeting WASI. |
| 1949 | /// See also `renameat`. |
| 1943 | 1950 | pub fn renameatWasi(old_dir_fd: fd_t, old_path: []const u8, new_dir_fd: fd_t, new_path: []const u8) RenameError!void { |
| 1944 | 1951 | switch (wasi.path_rename(old_dir_fd, old_path.ptr, old_path.len, new_dir_fd, new_path.ptr, new_path.len)) { |
| 1945 | 1952 | wasi.ESUCCESS => return, |
| ... | ... | @@ -2144,7 +2151,9 @@ pub fn mkdiratW(dir_fd: fd_t, sub_path_w: [*:0]const u16, mode: u32) MakeDirErro |
| 2144 | 2151 | /// Create a directory. |
| 2145 | 2152 | /// `mode` is ignored on Windows. |
| 2146 | 2153 | pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { |
| 2147 | | if (builtin.os.tag == .windows) { |
| 2154 | if (builtin.os.tag == .wasi) { |
| 2155 | @compileError("mkdir is not supported in WASI; use mkdirat instead"); |
| 2156 | } else if (builtin.os.tag == .windows) { |
| 2148 | 2157 | const sub_dir_handle = try windows.CreateDirectory(null, dir_path, null); |
| 2149 | 2158 | windows.CloseHandle(sub_dir_handle); |
| 2150 | 2159 | return; |
| ... | ... | @@ -2197,7 +2206,9 @@ pub const DeleteDirError = error{ |
| 2197 | 2206 | |
| 2198 | 2207 | /// Deletes an empty directory. |
| 2199 | 2208 | pub fn rmdir(dir_path: []const u8) DeleteDirError!void { |
| 2200 | | if (builtin.os.tag == .windows) { |
| 2209 | if (builtin.os.tag == .wasi) { |
| 2210 | @compileError("rmdir is not supported in WASI; use unlinkat instead"); |
| 2211 | } else if (builtin.os.tag == .windows) { |
| 2201 | 2212 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); |
| 2202 | 2213 | return windows.RemoveDirectoryW(dir_path_w.span().ptr); |
| 2203 | 2214 | } else { |
| ... | ... | @@ -2246,7 +2257,9 @@ pub const ChangeCurDirError = error{ |
| 2246 | 2257 | /// Changes the current working directory of the calling process. |
| 2247 | 2258 | /// `dir_path` is recommended to be a UTF-8 encoded string. |
| 2248 | 2259 | pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { |
| 2249 | | if (builtin.os.tag == .windows) { |
| 2260 | if (builtin.os.tag == .wasi) { |
| 2261 | @compileError("chdir is not supported in WASI"); |
| 2262 | } else if (builtin.os.tag == .windows) { |
| 2250 | 2263 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); |
| 2251 | 2264 | @compileError("TODO implement chdir for Windows"); |
| 2252 | 2265 | } else { |
| ... | ... | @@ -2310,9 +2323,11 @@ pub const ReadLinkError = error{ |
| 2310 | 2323 | /// Read value of a symbolic link. |
| 2311 | 2324 | /// The return value is a slice of `out_buffer` from index 0. |
| 2312 | 2325 | pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2313 | | if (builtin.os.tag == .windows) { |
| 2326 | if (builtin.os.tag == .wasi) { |
| 2327 | @compileError("readlink is not supported in WASI; use readlinkat instead"); |
| 2328 | } else if (builtin.os.tag == .windows) { |
| 2314 | 2329 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); |
| 2315 | | @compileError("TODO implement readlink for Windows"); |
| 2330 | return readlinkW(file_path_w.span().ptr, out_buffer); |
| 2316 | 2331 | } else { |
| 2317 | 2332 | const file_path_c = try toPosixPath(file_path); |
| 2318 | 2333 | return readlinkZ(&file_path_c, out_buffer); |
| ... | ... | @@ -2321,11 +2336,17 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2321 | 2336 | |
| 2322 | 2337 | pub const readlinkC = @compileError("deprecated: renamed to readlinkZ"); |
| 2323 | 2338 | |
| 2339 | /// Windows-only. Same as `readlink` expecte `file_path` is null-terminated, WTF16 encoded. |
| 2340 | /// Seel also `readlinkZ`. |
| 2341 | pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 { |
| 2342 | @compileError("TODO implement readlink for Windows"); |
| 2343 | } |
| 2344 | |
| 2324 | 2345 | /// Same as `readlink` except `file_path` is null-terminated. |
| 2325 | 2346 | pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2326 | 2347 | if (builtin.os.tag == .windows) { |
| 2327 | 2348 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 2328 | | @compileError("TODO implement readlink for Windows"); |
| 2349 | return readlinkW(file_path_w.span().ptr, out_buffer); |
| 2329 | 2350 | } |
| 2330 | 2351 | const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len); |
| 2331 | 2352 | switch (errno(rc)) { |
| ... | ... | @@ -3055,6 +3076,7 @@ pub const FStatError = error{ |
| 3055 | 3076 | AccessDenied, |
| 3056 | 3077 | } || UnexpectedError; |
| 3057 | 3078 | |
| 3079 | /// Return information about a file descriptor. |
| 3058 | 3080 | pub fn fstat(fd: fd_t) FStatError!Stat { |
| 3059 | 3081 | if (builtin.os.tag == .wasi) { |
| 3060 | 3082 | var stat: wasi.filestat_t = undefined; |
| ... | ... | @@ -3067,6 +3089,9 @@ pub fn fstat(fd: fd_t) FStatError!Stat { |
| 3067 | 3089 | else => |err| return unexpectedErrno(err), |
| 3068 | 3090 | } |
| 3069 | 3091 | } |
| 3092 | if (builtin.os.tag == .windows) { |
| 3093 | @compileError("fstat is not yet implemented on Windows"); |
| 3094 | } |
| 3070 | 3095 | |
| 3071 | 3096 | var stat: Stat = undefined; |
| 3072 | 3097 | switch (errno(system.fstat(fd, &stat))) { |
| ... | ... | @@ -3081,13 +3106,42 @@ pub fn fstat(fd: fd_t) FStatError!Stat { |
| 3081 | 3106 | |
| 3082 | 3107 | pub const FStatAtError = FStatError || error{ NameTooLong, FileNotFound }; |
| 3083 | 3108 | |
| 3109 | /// Similar to `fstat`, but returns stat of a resource pointed to by `pathname` |
| 3110 | /// which is relative to `dirfd` handle. |
| 3111 | /// See also `fstatatZ` and `fstatatWasi`. |
| 3084 | 3112 | pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat { |
| 3085 | | const pathname_c = try toPosixPath(pathname); |
| 3086 | | return fstatatZ(dirfd, &pathname_c, flags); |
| 3113 | if (builtin.os.tag == .wasi) { |
| 3114 | return fstatatWasi(dirfd, pathname, flags); |
| 3115 | } else if (builtin.os.tag == .windows) { |
| 3116 | @compileError("fstatat is not yet implemented on Windows"); |
| 3117 | } else { |
| 3118 | const pathname_c = try toPosixPath(pathname); |
| 3119 | return fstatatZ(dirfd, &pathname_c, flags); |
| 3120 | } |
| 3087 | 3121 | } |
| 3088 | 3122 | |
| 3089 | 3123 | pub const fstatatC = @compileError("deprecated: renamed to fstatatZ"); |
| 3090 | 3124 | |
| 3125 | /// WASI-only. Same as `fstatat` but targeting WASI. |
| 3126 | /// See also `fstatat`. |
| 3127 | pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat { |
| 3128 | var stat: wasi.filestat_t = undefined; |
| 3129 | switch (wasi.path_filestat_get(dirfd, flags, pathname.ptr, pathname.len, &stat)) { |
| 3130 | wasi.ESUCCESS => return Stat.fromFilestat(stat), |
| 3131 | wasi.EINVAL => unreachable, |
| 3132 | wasi.EBADF => unreachable, // Always a race condition. |
| 3133 | wasi.ENOMEM => return error.SystemResources, |
| 3134 | wasi.EACCES => return error.AccessDenied, |
| 3135 | wasi.EFAULT => unreachable, |
| 3136 | wasi.ENAMETOOLONG => return error.NameTooLong, |
| 3137 | wasi.ENOENT => return error.FileNotFound, |
| 3138 | wasi.ENOTDIR => return error.FileNotFound, |
| 3139 | else => |err| return unexpectedErrno(err), |
| 3140 | } |
| 3141 | } |
| 3142 | |
| 3143 | /// Same as `fstatat` but `pathname` is null-terminated. |
| 3144 | /// See also `fstatat`. |
| 3091 | 3145 | pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat { |
| 3092 | 3146 | var stat: Stat = undefined; |
| 3093 | 3147 | switch (errno(system.fstatat(dirfd, pathname, &stat, flags))) { |