| ... | ... | @@ -3635,7 +3635,7 @@ fn dirCreateFileWindows( |
| 3635 | 3635 | // after an executable file is closed. Here we work around the |
| 3636 | 3636 | // kernel bug with retry attempts. |
| 3637 | 3637 | syscall.finish(); |
| 3638 | | if (max_attempts - attempt == 0) return error.SharingViolation; |
| 3638 | if (max_attempts - attempt == 0) return error.FileBusy; |
| 3639 | 3639 | try parking_sleep.windowsRetrySleep((@as(u32, 1) << attempt) >> 1); |
| 3640 | 3640 | attempt += 1; |
| 3641 | 3641 | syscall = try .start(); |
| ... | ... | @@ -3648,7 +3648,7 @@ fn dirCreateFileWindows( |
| 3648 | 3648 | // call has failed. Here, we simulate the kernel bug being |
| 3649 | 3649 | // fixed by sleeping and retrying until the error goes away. |
| 3650 | 3650 | syscall.finish(); |
| 3651 | | if (max_attempts - attempt == 0) return error.SharingViolation; |
| 3651 | if (max_attempts - attempt == 0) return error.FileBusy; |
| 3652 | 3652 | try parking_sleep.windowsRetrySleep((@as(u32, 1) << attempt) >> 1); |
| 3653 | 3653 | attempt += 1; |
| 3654 | 3654 | syscall = try .start(); |
| ... | ... | @@ -3668,10 +3668,10 @@ fn dirCreateFileWindows( |
| 3668 | 3668 | .NOT_A_DIRECTORY => return syscall.fail(error.NotDir), |
| 3669 | 3669 | .USER_MAPPED_FILE => return syscall.fail(error.AccessDenied), |
| 3670 | 3670 | .VIRUS_INFECTED, .VIRUS_DELETED => return syscall.fail(error.AntivirusInterference), |
| 3671 | | .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), |
| 3672 | | .OBJECT_PATH_SYNTAX_BAD => |err| return syscall.ntstatusBug(err), |
| 3673 | | .INVALID_HANDLE => |err| return syscall.ntstatusBug(err), |
| 3674 | | else => |err| return syscall.unexpectedNtstatus(err), |
| 3671 | .INVALID_PARAMETER => |status| return syscall.ntstatusBug(status), |
| 3672 | .OBJECT_PATH_SYNTAX_BAD => |status| return syscall.ntstatusBug(status), |
| 3673 | .INVALID_HANDLE => |status| return syscall.ntstatusBug(status), |
| 3674 | else => |status| return syscall.unexpectedNtstatus(status), |
| 3675 | 3675 | }; |
| 3676 | 3676 | errdefer windows.CloseHandle(handle); |
| 3677 | 3677 | |
| ... | ... | @@ -3819,7 +3819,6 @@ fn dirCreateFileAtomic( |
| 3819 | 3819 | error.DiskQuota, |
| 3820 | 3820 | error.PathAlreadyExists, |
| 3821 | 3821 | error.LinkQuotaExceeded, |
| 3822 | | error.SharingViolation, |
| 3823 | 3822 | error.PipeBusy, |
| 3824 | 3823 | error.FileTooBig, |
| 3825 | 3824 | error.DeviceBusy, |
| ... | ... | @@ -3889,11 +3888,9 @@ fn dirCreateFileAtomic( |
| 3889 | 3888 | error.DiskQuota, |
| 3890 | 3889 | error.PathAlreadyExists, |
| 3891 | 3890 | error.LinkQuotaExceeded, |
| 3892 | | error.SharingViolation, |
| 3893 | 3891 | error.PipeBusy, |
| 3894 | 3892 | error.FileTooBig, |
| 3895 | 3893 | error.FileLocksUnsupported, |
| 3896 | | error.FileBusy, |
| 3897 | 3894 | error.DeviceBusy, |
| 3898 | 3895 | => return error.Unexpected, |
| 3899 | 3896 | |
| ... | ... | @@ -3926,7 +3923,6 @@ fn atomicFileInit( |
| 3926 | 3923 | error.PathAlreadyExists => continue, |
| 3927 | 3924 | error.DeviceBusy => continue, |
| 3928 | 3925 | error.FileBusy => continue, |
| 3929 | | error.SharingViolation => continue, |
| 3930 | 3926 | |
| 3931 | 3927 | error.IsDir => return error.Unexpected, // No path components. |
| 3932 | 3928 | error.FileTooBig => return error.Unexpected, // Creating, not opening. |
| ... | ... | @@ -4236,7 +4232,7 @@ pub fn dirOpenFileWtf16( |
| 4236 | 4232 | // after an executable file is closed. Here we work around the |
| 4237 | 4233 | // kernel bug with retry attempts. |
| 4238 | 4234 | syscall.finish(); |
| 4239 | | if (max_attempts - attempt == 0) return error.SharingViolation; |
| 4235 | if (max_attempts - attempt == 0) return error.FileBusy; |
| 4240 | 4236 | try parking_sleep.windowsRetrySleep((@as(u32, 1) << attempt) >> 1); |
| 4241 | 4237 | attempt += 1; |
| 4242 | 4238 | syscall = try .start(); |
| ... | ... | @@ -4258,7 +4254,7 @@ pub fn dirOpenFileWtf16( |
| 4258 | 4254 | // call has failed. Here, we simulate the kernel bug being |
| 4259 | 4255 | // fixed by sleeping and retrying until the error goes away. |
| 4260 | 4256 | syscall.finish(); |
| 4261 | | if (max_attempts - attempt == 0) return error.SharingViolation; |
| 4257 | if (max_attempts - attempt == 0) return error.FileBusy; |
| 4262 | 4258 | try parking_sleep.windowsRetrySleep((@as(u32, 1) << attempt) >> 1); |
| 4263 | 4259 | attempt += 1; |
| 4264 | 4260 | syscall = try .start(); |
| ... | ... | @@ -6353,8 +6349,7 @@ fn dirSymLinkWindows( |
| 6353 | 6349 | |
| 6354 | 6350 | // Target path does not use sliceToPrefixedFileW because certain paths |
| 6355 | 6351 | // are handled differently when creating a symlink than they would be |
| 6356 | | // when converting to an NT namespaced path. CreateSymbolicLink in |
| 6357 | | // symLinkW will handle the necessary conversion. |
| 6352 | // when converting to an NT namespaced path. |
| 6358 | 6353 | var target_path_w: w.PathSpace = undefined; |
| 6359 | 6354 | target_path_w.len = try w.wtf8ToWtf16Le(&target_path_w.data, target_path); |
| 6360 | 6355 | target_path_w.data[target_path_w.len] = 0; |
| ... | ... | @@ -6465,7 +6460,7 @@ fn dirSymLinkWindows( |
| 6465 | 6460 | @memcpy(buffer[@sizeOf(SYMLINK_DATA)..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path))); |
| 6466 | 6461 | const paths_start = @sizeOf(SYMLINK_DATA) + final_target_path.len * 2; |
| 6467 | 6462 | @memcpy(buffer[paths_start..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path))); |
| 6468 | | const rc = w.DeviceIoControl(symlink_handle, w.FSCTL.SET_REPARSE_POINT, .{ .in = buffer[0..buf_len] }); |
| 6463 | const rc = w.DeviceIoControl(symlink_handle, .SET_REPARSE_POINT, .{ .in = buffer[0..buf_len] }); |
| 6469 | 6464 | switch (rc) { |
| 6470 | 6465 | .SUCCESS => {}, |
| 6471 | 6466 | .PRIVILEGE_NOT_HELD => return error.PermissionDenied, |
| ... | ... | @@ -6572,44 +6567,189 @@ fn dirSymLinkPosix( |
| 6572 | 6567 | } |
| 6573 | 6568 | } |
| 6574 | 6569 | |
| 6575 | | const dirReadLink = switch (native_os) { |
| 6576 | | .windows => dirReadLinkWindows, |
| 6577 | | .wasi => dirReadLinkWasi, |
| 6578 | | else => dirReadLinkPosix, |
| 6579 | | }; |
| 6580 | | |
| 6581 | | fn dirReadLinkWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6570 | fn dirReadLink(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6582 | 6571 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 6583 | 6572 | _ = t; |
| 6584 | | const w = windows; |
| 6573 | switch (native_os) { |
| 6574 | .windows => return dirReadLinkWindows(dir, sub_path, buffer), |
| 6575 | .wasi => return dirReadLinkWasi(dir, sub_path, buffer), |
| 6576 | else => return dirReadLinkPosix(dir, sub_path, buffer), |
| 6577 | } |
| 6578 | } |
| 6585 | 6579 | |
| 6580 | fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6581 | // This gets used once for `sub_path` and then reused again temporarily |
| 6582 | // before converting back to `buffer`. |
| 6586 | 6583 | var sub_path_w_buf = try windows.sliceToPrefixedFileW(dir.handle, sub_path); |
| 6584 | const sub_path_w = sub_path_w_buf.span(); |
| 6585 | const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong; |
| 6586 | var nt_name: windows.UNICODE_STRING = .{ |
| 6587 | .Length = path_len_bytes, |
| 6588 | .MaximumLength = path_len_bytes, |
| 6589 | .Buffer = @constCast(sub_path_w.ptr), |
| 6590 | }; |
| 6591 | const attr: windows.OBJECT_ATTRIBUTES = .{ |
| 6592 | .Length = @sizeOf(windows.OBJECT_ATTRIBUTES), |
| 6593 | .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle, |
| 6594 | .Attributes = .{ |
| 6595 | .INHERIT = false, |
| 6596 | }, |
| 6597 | .ObjectName = &nt_name, |
| 6598 | .SecurityDescriptor = null, |
| 6599 | .SecurityQualityOfService = null, |
| 6600 | }; |
| 6601 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; |
| 6602 | var result_handle: windows.HANDLE = undefined; |
| 6587 | 6603 | |
| 6588 | | const syscall: Syscall = try .start(); |
| 6589 | | const result_w = while (true) { |
| 6590 | | if (w.ReadLink(dir.handle, sub_path_w_buf.span(), &sub_path_w_buf.data)) |res| { |
| 6604 | // There are multiple kernel bugs being worked around with retries. |
| 6605 | const max_attempts = 13; |
| 6606 | var attempt: u5 = 0; |
| 6607 | |
| 6608 | var syscall: Syscall = try .start(); |
| 6609 | while (true) switch (windows.ntdll.NtCreateFile( |
| 6610 | &result_handle, |
| 6611 | .{ |
| 6612 | .SPECIFIC = .{ .FILE = .{ |
| 6613 | .READ_ATTRIBUTES = true, |
| 6614 | } }, |
| 6615 | .STANDARD = .{ .SYNCHRONIZE = true }, |
| 6616 | }, |
| 6617 | &attr, |
| 6618 | &io_status_block, |
| 6619 | null, |
| 6620 | .{ .NORMAL = true }, |
| 6621 | .VALID_FLAGS, |
| 6622 | .OPEN, |
| 6623 | .{ |
| 6624 | .DIRECTORY_FILE = false, |
| 6625 | .NON_DIRECTORY_FILE = false, |
| 6626 | .IO = .ASYNCHRONOUS, |
| 6627 | .OPEN_REPARSE_POINT = true, |
| 6628 | }, |
| 6629 | null, |
| 6630 | 0, |
| 6631 | )) { |
| 6632 | .SUCCESS => { |
| 6591 | 6633 | syscall.finish(); |
| 6592 | | break res; |
| 6593 | | } else |err| switch (err) { |
| 6594 | | error.OperationCanceled => { |
| 6595 | | try syscall.checkCancel(); |
| 6596 | | continue; |
| 6597 | | }, |
| 6598 | | else => |e| return syscall.fail(e), |
| 6599 | | } |
| 6634 | break; |
| 6635 | }, |
| 6636 | .CANCELLED => { |
| 6637 | try syscall.checkCancel(); |
| 6638 | continue; |
| 6639 | }, |
| 6640 | .SHARING_VIOLATION => { |
| 6641 | // This occurs if the file attempting to be opened is a running |
| 6642 | // executable. However, there's a kernel bug: the error may be |
| 6643 | // incorrectly returned for an indeterminate amount of time |
| 6644 | // after an executable file is closed. Here we work around the |
| 6645 | // kernel bug with retry attempts. |
| 6646 | syscall.finish(); |
| 6647 | if (max_attempts - attempt == 0) return error.FileBusy; |
| 6648 | try parking_sleep.windowsRetrySleep((@as(u32, 1) << attempt) >> 1); |
| 6649 | attempt += 1; |
| 6650 | syscall = try .start(); |
| 6651 | continue; |
| 6652 | }, |
| 6653 | .DELETE_PENDING => { |
| 6654 | // This error means that there *was* a file in this location on |
| 6655 | // the file system, but it was deleted. However, the OS is not |
| 6656 | // finished with the deletion operation, and so this CreateFile |
| 6657 | // call has failed. Here, we simulate the kernel bug being |
| 6658 | // fixed by sleeping and retrying until the error goes away. |
| 6659 | syscall.finish(); |
| 6660 | if (max_attempts - attempt == 0) return error.FileBusy; |
| 6661 | try parking_sleep.windowsRetrySleep((@as(u32, 1) << attempt) >> 1); |
| 6662 | attempt += 1; |
| 6663 | syscall = try .start(); |
| 6664 | continue; |
| 6665 | }, |
| 6666 | .OBJECT_NAME_INVALID => return syscall.fail(error.BadPathName), |
| 6667 | .OBJECT_NAME_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| 6668 | .OBJECT_PATH_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| 6669 | .BAD_NETWORK_PATH => return syscall.fail(error.NetworkNotFound), // \\server was not found |
| 6670 | .BAD_NETWORK_NAME => return syscall.fail(error.NetworkNotFound), // \\server was found but \\server\share wasn't |
| 6671 | .NO_MEDIA_IN_DEVICE => return syscall.fail(error.FileNotFound), |
| 6672 | .ACCESS_DENIED => return syscall.fail(error.AccessDenied), |
| 6673 | .PIPE_BUSY => return syscall.fail(error.AccessDenied), |
| 6674 | .PIPE_NOT_AVAILABLE => return syscall.fail(error.FileNotFound), |
| 6675 | .USER_MAPPED_FILE => return syscall.fail(error.AccessDenied), |
| 6676 | .VIRUS_INFECTED, .VIRUS_DELETED => return syscall.fail(error.AntivirusInterference), |
| 6677 | .INVALID_PARAMETER => |status| return syscall.ntstatusBug(status), |
| 6678 | .OBJECT_PATH_SYNTAX_BAD => |status| return syscall.ntstatusBug(status), |
| 6679 | .INVALID_HANDLE => |status| return syscall.ntstatusBug(status), |
| 6680 | else => |status| return syscall.unexpectedNtstatus(status), |
| 6600 | 6681 | }; |
| 6682 | defer windows.CloseHandle(result_handle); |
| 6683 | |
| 6684 | var reparse_buf: [windows.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(windows.REPARSE_DATA_BUFFER)) = undefined; |
| 6601 | 6685 | |
| 6686 | syscall = try .start(); |
| 6687 | while (true) switch (windows.ntdll.NtFsControlFile( |
| 6688 | result_handle, |
| 6689 | null, // event |
| 6690 | null, // APC routine |
| 6691 | null, // APC context |
| 6692 | &io_status_block, |
| 6693 | .GET_REPARSE_POINT, |
| 6694 | null, // input buffer |
| 6695 | 0, // input buffer length |
| 6696 | &reparse_buf, |
| 6697 | reparse_buf.len, |
| 6698 | )) { |
| 6699 | .SUCCESS => { |
| 6700 | syscall.finish(); |
| 6701 | break; |
| 6702 | }, |
| 6703 | .CANCELLED => { |
| 6704 | try syscall.checkCancel(); |
| 6705 | continue; |
| 6706 | }, |
| 6707 | .NOT_A_REPARSE_POINT => return syscall.fail(error.NotLink), |
| 6708 | else => |status| return syscall.unexpectedNtstatus(status), |
| 6709 | }; |
| 6710 | |
| 6711 | const reparse_struct: *const windows.REPARSE_DATA_BUFFER = @ptrCast(@alignCast(&reparse_buf)); |
| 6712 | const IoReparseTagInt = @typeInfo(windows.IO_REPARSE_TAG).@"struct".backing_integer.?; |
| 6713 | const result_w = switch (@as(IoReparseTagInt, @bitCast(reparse_struct.ReparseTag))) { |
| 6714 | @as(IoReparseTagInt, @bitCast(windows.IO_REPARSE_TAG.SYMLINK)) => r: { |
| 6715 | const buf: *const windows.SYMBOLIC_LINK_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0])); |
| 6716 | const offset = buf.SubstituteNameOffset >> 1; |
| 6717 | const len = buf.SubstituteNameLength >> 1; |
| 6718 | const path_buf = @as([*]const u16, &buf.PathBuffer); |
| 6719 | const is_relative = buf.Flags & windows.SYMLINK_FLAG_RELATIVE != 0; |
| 6720 | break :r try parseReadLinkPath(path_buf[offset..][0..len], is_relative, &sub_path_w_buf.data); |
| 6721 | }, |
| 6722 | @as(IoReparseTagInt, @bitCast(windows.IO_REPARSE_TAG.MOUNT_POINT)) => r: { |
| 6723 | const buf: *const windows.MOUNT_POINT_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0])); |
| 6724 | const offset = buf.SubstituteNameOffset >> 1; |
| 6725 | const len = buf.SubstituteNameLength >> 1; |
| 6726 | const path_buf = @as([*]const u16, &buf.PathBuffer); |
| 6727 | break :r try parseReadLinkPath(path_buf[offset..][0..len], false, &sub_path_w_buf.data); |
| 6728 | }, |
| 6729 | else => return error.UnsupportedReparsePointType, |
| 6730 | }; |
| 6602 | 6731 | const len = std.unicode.calcWtf8Len(result_w); |
| 6603 | 6732 | if (len > buffer.len) return error.NameTooLong; |
| 6604 | 6733 | |
| 6605 | 6734 | return std.unicode.wtf16LeToWtf8(buffer, result_w); |
| 6606 | 6735 | } |
| 6607 | 6736 | |
| 6608 | | fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6609 | | if (builtin.link_libc) return dirReadLinkPosix(userdata, dir, sub_path, buffer); |
| 6737 | fn parseReadLinkPath(path: []const u16, is_relative: bool, out_buffer: []u16) error{NameTooLong}![]u16 { |
| 6738 | path: { |
| 6739 | if (is_relative) break :path; |
| 6740 | return windows.ntToWin32Namespace(path, out_buffer) catch |err| switch (err) { |
| 6741 | error.NameTooLong => |e| return e, |
| 6742 | error.NotNtPath => break :path, |
| 6743 | }; |
| 6744 | } |
| 6745 | if (out_buffer.len < path.len) return error.NameTooLong; |
| 6746 | const dest = out_buffer[0..path.len]; |
| 6747 | @memcpy(dest, path); |
| 6748 | return dest; |
| 6749 | } |
| 6610 | 6750 | |
| 6611 | | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 6612 | | _ = t; |
| 6751 | fn dirReadLinkWasi(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6752 | if (builtin.link_libc) return dirReadLinkPosix(dir, sub_path, buffer); |
| 6613 | 6753 | |
| 6614 | 6754 | var n: usize = undefined; |
| 6615 | 6755 | const syscall: Syscall = try .start(); |
| ... | ... | @@ -6644,10 +6784,7 @@ fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer |
| 6644 | 6784 | } |
| 6645 | 6785 | } |
| 6646 | 6786 | |
| 6647 | | fn dirReadLinkPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6648 | | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 6649 | | _ = t; |
| 6650 | | |
| 6787 | fn dirReadLinkPosix(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize { |
| 6651 | 6788 | var sub_path_buffer: [posix.PATH_MAX]u8 = undefined; |
| 6652 | 6789 | const sub_path_posix = try pathToPosix(sub_path, &sub_path_buffer); |
| 6653 | 6790 | |
| ... | ... | @@ -8709,45 +8846,41 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut |
| 8709 | 8846 | const symlink_path = std.mem.sliceTo(&symlink_path_buf, 0); |
| 8710 | 8847 | return Io.Dir.realPathFileAbsolute(ioBasic(t), symlink_path, out_buffer) catch |err| switch (err) { |
| 8711 | 8848 | error.NetworkNotFound => unreachable, // Windows-only |
| 8849 | error.FileBusy => unreachable, // Windows-only |
| 8712 | 8850 | else => |e| return e, |
| 8713 | 8851 | }; |
| 8714 | 8852 | }, |
| 8715 | 8853 | .linux, .serenity => return Io.Dir.readLinkAbsolute(ioBasic(t), "/proc/self/exe", out_buffer) catch |err| switch (err) { |
| 8716 | 8854 | error.UnsupportedReparsePointType => unreachable, // Windows-only |
| 8717 | 8855 | error.NetworkNotFound => unreachable, // Windows-only |
| 8856 | error.FileBusy => unreachable, // Windows-only |
| 8718 | 8857 | else => |e| return e, |
| 8719 | 8858 | }, |
| 8720 | 8859 | .illumos => return Io.Dir.readLinkAbsolute(ioBasic(t), "/proc/self/path/a.out", out_buffer) catch |err| switch (err) { |
| 8721 | 8860 | error.UnsupportedReparsePointType => unreachable, // Windows-only |
| 8722 | 8861 | error.NetworkNotFound => unreachable, // Windows-only |
| 8862 | error.FileBusy => unreachable, // Windows-only |
| 8723 | 8863 | else => |e| return e, |
| 8724 | 8864 | }, |
| 8725 | 8865 | .freebsd, .dragonfly => { |
| 8726 | 8866 | var mib: [4]c_int = .{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_PATHNAME, -1 }; |
| 8727 | 8867 | var out_len: usize = out_buffer.len; |
| 8728 | 8868 | const syscall: Syscall = try .start(); |
| 8729 | | while (true) { |
| 8730 | | switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) { |
| 8731 | | .SUCCESS => { |
| 8732 | | syscall.finish(); |
| 8733 | | return out_len - 1; // discard terminating NUL |
| 8734 | | }, |
| 8735 | | .INTR => { |
| 8736 | | try syscall.checkCancel(); |
| 8737 | | continue; |
| 8738 | | }, |
| 8739 | | else => |e| { |
| 8740 | | syscall.finish(); |
| 8741 | | switch (e) { |
| 8742 | | .FAULT => |err| return errnoBug(err), |
| 8743 | | .PERM => return error.PermissionDenied, |
| 8744 | | .NOMEM => return error.SystemResources, |
| 8745 | | .NOENT => |err| return errnoBug(err), |
| 8746 | | else => |err| return posix.unexpectedErrno(err), |
| 8747 | | } |
| 8748 | | }, |
| 8749 | | } |
| 8750 | | } |
| 8869 | while (true) switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) { |
| 8870 | .SUCCESS => { |
| 8871 | syscall.finish(); |
| 8872 | return out_len - 1; // discard terminating NUL |
| 8873 | }, |
| 8874 | .INTR => { |
| 8875 | try syscall.checkCancel(); |
| 8876 | continue; |
| 8877 | }, |
| 8878 | .PERM => return syscall.fail(error.PermissionDenied), |
| 8879 | .NOMEM => return syscall.fail(error.SystemResources), |
| 8880 | .FAULT => |err| return syscall.errnoBug(err), |
| 8881 | .NOENT => |err| return syscall.errnoBug(err), |
| 8882 | else => |err| return syscall.unexpectedErrno(err), |
| 8883 | }; |
| 8751 | 8884 | }, |
| 8752 | 8885 | .netbsd => { |
| 8753 | 8886 | var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC_ARGS, -1, posix.KERN.PROC_PATHNAME }; |
| ... | ... | @@ -8763,16 +8896,11 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut |
| 8763 | 8896 | try syscall.checkCancel(); |
| 8764 | 8897 | continue; |
| 8765 | 8898 | }, |
| 8766 | | else => |e| { |
| 8767 | | syscall.finish(); |
| 8768 | | switch (e) { |
| 8769 | | .FAULT => |err| return errnoBug(err), |
| 8770 | | .PERM => return error.PermissionDenied, |
| 8771 | | .NOMEM => return error.SystemResources, |
| 8772 | | .NOENT => |err| return errnoBug(err), |
| 8773 | | else => |err| return posix.unexpectedErrno(err), |
| 8774 | | } |
| 8775 | | }, |
| 8899 | .PERM => return syscall.fail(error.PermissionDenied), |
| 8900 | .NOMEM => return syscall.fail(error.SystemResources), |
| 8901 | .FAULT => |err| return syscall.errnoBug(err), |
| 8902 | .NOENT => |err| return syscall.errnoBug(err), |
| 8903 | else => |err| return syscall.unexpectedErrno(err), |
| 8776 | 8904 | } |
| 8777 | 8905 | } |
| 8778 | 8906 | }, |