| ... | ... | @@ -1520,15 +1520,17 @@ pub const SymLinkError = error{ |
| 1520 | 1520 | /// If `sym_link_path` exists, it will not be overwritten. |
| 1521 | 1521 | /// See also `symlinkC` and `symlinkW`. |
| 1522 | 1522 | pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void { |
| 1523 | if (builtin.os.tag == .wasi) { |
| 1524 | @compileError("symlink is not supported in WASI; use symlinkat instead"); |
| 1525 | } |
| 1523 | 1526 | if (builtin.os.tag == .windows) { |
| 1524 | 1527 | const target_path_w = try windows.sliceToPrefixedFileW(target_path); |
| 1525 | 1528 | const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path); |
| 1526 | 1529 | return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0); |
| 1527 | | } else { |
| 1528 | | const target_path_c = try toPosixPath(target_path); |
| 1529 | | const sym_link_path_c = try toPosixPath(sym_link_path); |
| 1530 | | return symlinkZ(&target_path_c, &sym_link_path_c); |
| 1531 | 1530 | } |
| 1531 | const target_path_c = try toPosixPath(target_path); |
| 1532 | const sym_link_path_c = try toPosixPath(sym_link_path); |
| 1533 | return symlinkZ(&target_path_c, &sym_link_path_c); |
| 1532 | 1534 | } |
| 1533 | 1535 | |
| 1534 | 1536 | pub const symlinkC = @compileError("deprecated: renamed to symlinkZ"); |
| ... | ... | @@ -1561,15 +1563,65 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin |
| 1561 | 1563 | } |
| 1562 | 1564 | } |
| 1563 | 1565 | |
| 1566 | /// Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string |
| 1567 | /// `target_path` **relative** to `newdirfd` directory handle. |
| 1568 | /// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent |
| 1569 | /// one; the latter case is known as a dangling link. |
| 1570 | /// If `sym_link_path` exists, it will not be overwritten. |
| 1571 | /// See also `symlinkatWasi`, `symlinkatZ` and `symlinkatW`. |
| 1564 | 1572 | pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void { |
| 1573 | if (builtin.os.tag == .wasi) { |
| 1574 | return symlinkatWasi(target_path, newdirfd, sym_link_path); |
| 1575 | } |
| 1576 | if (builtin.os.tag == .windows) { |
| 1577 | const target_path_w = try windows.sliceToPrefixedFileW(target_path); |
| 1578 | const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path); |
| 1579 | return symlinkatW(target_path_w.span().ptr, newdirfd, sym_link_path_w.span().ptr); |
| 1580 | } |
| 1565 | 1581 | const target_path_c = try toPosixPath(target_path); |
| 1566 | 1582 | const sym_link_path_c = try toPosixPath(sym_link_path); |
| 1567 | | return symlinkatZ(target_path_c, newdirfd, sym_link_path_c); |
| 1583 | return symlinkatZ(&target_path_c, newdirfd, &sym_link_path_c); |
| 1568 | 1584 | } |
| 1569 | 1585 | |
| 1570 | 1586 | pub const symlinkatC = @compileError("deprecated: renamed to symlinkatZ"); |
| 1571 | 1587 | |
| 1588 | /// WASI-only. The same as `symlinkat` but targeting WASI. |
| 1589 | /// See also `symlinkat`. |
| 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)) { |
| 1592 | wasi.ESUCCESS => {}, |
| 1593 | wasi.EFAULT => unreachable, |
| 1594 | wasi.EINVAL => unreachable, |
| 1595 | wasi.EACCES => return error.AccessDenied, |
| 1596 | wasi.EPERM => return error.AccessDenied, |
| 1597 | wasi.EDQUOT => return error.DiskQuota, |
| 1598 | wasi.EEXIST => return error.PathAlreadyExists, |
| 1599 | wasi.EIO => return error.FileSystem, |
| 1600 | wasi.ELOOP => return error.SymLinkLoop, |
| 1601 | wasi.ENAMETOOLONG => return error.NameTooLong, |
| 1602 | wasi.ENOENT => return error.FileNotFound, |
| 1603 | wasi.ENOTDIR => return error.NotDir, |
| 1604 | wasi.ENOMEM => return error.SystemResources, |
| 1605 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 1606 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 1607 | else => |err| return unexpectedErrno(err), |
| 1608 | } |
| 1609 | } |
| 1610 | |
| 1611 | /// Windows-only. The same as `symlinkat` except the paths are null-terminated, WTF-16 encoded. |
| 1612 | /// See also `symlinkat`. |
| 1613 | pub fn symlinkatW(target_path: [*:0]const u16, newdirfd: fd_t, sym_link_path: [*:0]const u16) SymlinkError!void { |
| 1614 | @compileError("TODO implement on Windows"); |
| 1615 | } |
| 1616 | |
| 1617 | /// The same as `symlinkat` except the parameters are null-terminated pointers. |
| 1618 | /// See also `symlinkat`. |
| 1572 | 1619 | pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:0]const u8) SymLinkError!void { |
| 1620 | if (builtin.os.tag == .windows) { |
| 1621 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); |
| 1622 | const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); |
| 1623 | return symlinkatW(target_path_w.span().ptr, newdirfd, sym_link_path.span().ptr); |
| 1624 | } |
| 1573 | 1625 | switch (errno(system.symlinkat(target_path, newdirfd, sym_link_path))) { |
| 1574 | 1626 | 0 => return, |
| 1575 | 1627 | EFAULT => unreachable, |