| ... | ... | @@ -1588,7 +1588,7 @@ pub const symlinkatC = @compileError("deprecated: renamed to symlinkatZ"); |
| 1588 | 1588 | /// WASI-only. The same as `symlinkat` but targeting WASI. |
| 1589 | 1589 | /// See also `symlinkat`. |
| 1590 | 1590 | pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void { |
| 1591 | | switch (wasi.path_symlink(sym_link_path.ptr, sym_link_path.len, newdirfd, target_path.ptr, target_path.len)) { |
| 1591 | switch (wasi.path_symlink(target_path.ptr, target_path.len, newdirfd, sym_link_path.ptr, sym_link_path.len)) { |
| 1592 | 1592 | wasi.ESUCCESS => {}, |
| 1593 | 1593 | wasi.EFAULT => unreachable, |
| 1594 | 1594 | wasi.EINVAL => unreachable, |
| ... | ... | @@ -2343,12 +2343,54 @@ pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 |
| 2343 | 2343 | } |
| 2344 | 2344 | } |
| 2345 | 2345 | |
| 2346 | /// Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle. |
| 2347 | /// The return value is a slice of `out_buffer` from index 0. |
| 2348 | /// See also `readlinkatWasi`, `realinkatZ` and `realinkatW`. |
| 2349 | pub fn readlinkat(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2350 | if (builtin.os.tag == .wasi) { |
| 2351 | return readlinkatWasi(dirfd, file_path, out_buffer); |
| 2352 | } |
| 2353 | if (builtin.os.tag == .windows) { |
| 2354 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 2355 | return readlinkatW(dirfd, file_path.span().ptr, out_buffer); |
| 2356 | } |
| 2357 | const file_path_c = try toPosixPath(file_path); |
| 2358 | return readlinkatZ(dirfd, &file_path_c, out_buffer); |
| 2359 | } |
| 2360 | |
| 2346 | 2361 | pub const readlinkatC = @compileError("deprecated: renamed to readlinkatZ"); |
| 2347 | 2362 | |
| 2363 | /// WASI-only. Same as `readlinkat` but targets WASI. |
| 2364 | /// See also `readlinkat`. |
| 2365 | pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2366 | var bufused: usize = undefined; |
| 2367 | switch (wasi.path_readlink(dirfd, file_path.ptr, file_path.len, out_buffer.ptr, out_buffer.len, &bufused)) { |
| 2368 | wasi.ESUCCESS => return out_buffer[0..bufused], |
| 2369 | wasi.EACCES => return error.AccessDenied, |
| 2370 | wasi.EFAULT => unreachable, |
| 2371 | wasi.EINVAL => unreachable, |
| 2372 | wasi.EIO => return error.FileSystem, |
| 2373 | wasi.ELOOP => return error.SymLinkLoop, |
| 2374 | wasi.ENAMETOOLONG => return error.NameTooLong, |
| 2375 | wasi.ENOENT => return error.FileNotFound, |
| 2376 | wasi.ENOMEM => return error.SystemResources, |
| 2377 | wasi.ENOTDIR => return error.NotDir, |
| 2378 | else => |err| return unexpectedErrno(err), |
| 2379 | } |
| 2380 | } |
| 2381 | |
| 2382 | /// Windows-only. Same as `readlinkat` except `file_path` is null-terminated, WTF16 encoded. |
| 2383 | /// See also `readlinkat`. |
| 2384 | pub fn readlinkatW(dirfd: fd_t, file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 { |
| 2385 | @compileError("TODO implement on Windows"); |
| 2386 | } |
| 2387 | |
| 2388 | /// Same as `readlinkat` except `file_path` is null-terminated. |
| 2389 | /// See also `readlinkat`. |
| 2348 | 2390 | pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2349 | 2391 | if (builtin.os.tag == .windows) { |
| 2350 | 2392 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 2351 | | @compileError("TODO implement readlink for Windows"); |
| 2393 | return readlinkatW(dirfd, file_path_w.span().ptr, out_buffer); |
| 2352 | 2394 | } |
| 2353 | 2395 | const rc = system.readlinkat(dirfd, file_path, out_buffer.ptr, out_buffer.len); |
| 2354 | 2396 | switch (errno(rc)) { |