| ... | ... | @@ -51,7 +51,6 @@ const ArrayList = @import("../array_list.zig").ArrayList; |
| 51 | 51 | const Buffer = @import("../buffer.zig").Buffer; |
| 52 | 52 | const math = @import("../index.zig").math; |
| 53 | 53 | |
| 54 | | error Unexpected; |
| 55 | 54 | error SystemResources; |
| 56 | 55 | error AccessDenied; |
| 57 | 56 | error InvalidExe; |
| ... | ... | @@ -81,7 +80,7 @@ pub fn getRandomBytes(buf: []u8) -> %void { |
| 81 | 80 | posix.EINVAL => unreachable, |
| 82 | 81 | posix.EFAULT => unreachable, |
| 83 | 82 | posix.EINTR => continue, |
| 84 | | else => error.Unexpected, |
| 83 | else => unexpectedErrorPosix(err), |
| 85 | 84 | } |
| 86 | 85 | } |
| 87 | 86 | return; |
| ... | ... | @@ -96,12 +95,18 @@ pub fn getRandomBytes(buf: []u8) -> %void { |
| 96 | 95 | Os.windows => { |
| 97 | 96 | var hCryptProv: windows.HCRYPTPROV = undefined; |
| 98 | 97 | if (windows.CryptAcquireContextA(&hCryptProv, null, null, windows.PROV_RSA_FULL, 0) == 0) { |
| 99 | | return error.Unexpected; |
| 98 | const err = windows.GetLastError(); |
| 99 | return switch (err) { |
| 100 | else => unexpectedErrorWindows(err), |
| 101 | }; |
| 100 | 102 | } |
| 101 | 103 | defer _ = windows.CryptReleaseContext(hCryptProv, 0); |
| 102 | 104 | |
| 103 | 105 | if (windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr) == 0) { |
| 104 | | return error.Unexpected; |
| 106 | const err = windows.GetLastError(); |
| 107 | return switch (err) { |
| 108 | else => unexpectedErrorWindows(err), |
| 109 | }; |
| 105 | 110 | } |
| 106 | 111 | }, |
| 107 | 112 | else => @compileError("Unsupported OS"), |
| ... | ... | @@ -187,8 +192,8 @@ pub fn posixRead(fd: i32, buf: []u8) -> %void { |
| 187 | 192 | posix.EIO => error.InputOutput, |
| 188 | 193 | posix.EISDIR => error.IsDir, |
| 189 | 194 | posix.ENOBUFS, posix.ENOMEM => error.SystemResources, |
| 190 | | else => return error.Unexpected, |
| 191 | | } |
| 195 | else => unexpectedErrorPosix(err), |
| 196 | }; |
| 192 | 197 | } |
| 193 | 198 | index += amt_written; |
| 194 | 199 | } |
| ... | ... | @@ -202,7 +207,6 @@ error FileTooBig; |
| 202 | 207 | error InputOutput; |
| 203 | 208 | error NoSpaceLeft; |
| 204 | 209 | error BrokenPipe; |
| 205 | | error Unexpected; |
| 206 | 210 | |
| 207 | 211 | /// Calls POSIX write, and keeps trying if it gets interrupted. |
| 208 | 212 | pub fn posixWrite(fd: i32, bytes: []const u8) -> %void { |
| ... | ... | @@ -222,8 +226,8 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void { |
| 222 | 226 | posix.ENOSPC => error.NoSpaceLeft, |
| 223 | 227 | posix.EPERM => error.AccessDenied, |
| 224 | 228 | posix.EPIPE => error.BrokenPipe, |
| 225 | | else => error.Unexpected, |
| 226 | | } |
| 229 | else => unexpectedErrorPosix(write_err), |
| 230 | }; |
| 227 | 231 | } |
| 228 | 232 | return; |
| 229 | 233 | } |
| ... | ... | @@ -277,7 +281,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al |
| 277 | 281 | posix.ENOTDIR => error.NotDir, |
| 278 | 282 | posix.EPERM => error.AccessDenied, |
| 279 | 283 | posix.EEXIST => error.PathAlreadyExists, |
| 280 | | else => error.Unexpected, |
| 284 | else => unexpectedErrorPosix(err), |
| 281 | 285 | } |
| 282 | 286 | } |
| 283 | 287 | return i32(result); |
| ... | ... | @@ -292,7 +296,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void { |
| 292 | 296 | posix.EBUSY, posix.EINTR => continue, |
| 293 | 297 | posix.EMFILE => error.ProcessFdQuotaExceeded, |
| 294 | 298 | posix.EINVAL => unreachable, |
| 295 | | else => error.Unexpected, |
| 299 | else => unexpectedErrorPosix(err), |
| 296 | 300 | }; |
| 297 | 301 | } |
| 298 | 302 | return; |
| ... | ... | @@ -404,7 +408,7 @@ fn posixExecveErrnoToErr(err: usize) -> error { |
| 404 | 408 | posix.ENOENT => error.FileNotFound, |
| 405 | 409 | posix.ENOTDIR => error.NotDir, |
| 406 | 410 | posix.ETXTBSY => error.FileBusy, |
| 407 | | else => error.Unexpected, |
| 411 | else => unexpectedErrorPosix(err), |
| 408 | 412 | }; |
| 409 | 413 | } |
| 410 | 414 | |
| ... | ... | @@ -491,7 +495,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 491 | 495 | const err = windows.GetLastError(); |
| 492 | 496 | return switch (err) { |
| 493 | 497 | windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound, |
| 494 | | else => error.Unexpected, |
| 498 | else => unexpectedErrorWindows(err), |
| 495 | 499 | }; |
| 496 | 500 | } |
| 497 | 501 | |
| ... | ... | @@ -519,7 +523,10 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 519 | 523 | const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr); |
| 520 | 524 | |
| 521 | 525 | if (result == 0) { |
| 522 | | return error.Unexpected; |
| 526 | const err = windows.GetLastError(); |
| 527 | return switch (err) { |
| 528 | else => unexpectedErrorWindows(err), |
| 529 | }; |
| 523 | 530 | } |
| 524 | 531 | |
| 525 | 532 | if (result > buf.len) { |
| ... | ... | @@ -539,7 +546,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 539 | 546 | buf = %return allocator.realloc(u8, buf, buf.len * 2); |
| 540 | 547 | continue; |
| 541 | 548 | } else if (err > 0) { |
| 542 | | return error.Unexpected; |
| 549 | return unexpectedErrorPosix(err); |
| 543 | 550 | } |
| 544 | 551 | |
| 545 | 552 | return allocator.shrink(u8, buf, cstr.len(buf.ptr)); |
| ... | ... | @@ -570,7 +577,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path |
| 570 | 577 | if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) { |
| 571 | 578 | const err = windows.GetLastError(); |
| 572 | 579 | return switch (err) { |
| 573 | | else => error.Unexpected, |
| 580 | else => unexpectedErrorWindows(err), |
| 574 | 581 | }; |
| 575 | 582 | } |
| 576 | 583 | } |
| ... | ... | @@ -602,7 +609,7 @@ pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: |
| 602 | 609 | posix.ENOMEM => error.SystemResources, |
| 603 | 610 | posix.ENOSPC => error.NoSpaceLeft, |
| 604 | 611 | posix.EROFS => error.ReadOnlyFileSystem, |
| 605 | | else => error.Unexpected, |
| 612 | else => unexpectedErrorPosix(err), |
| 606 | 613 | }; |
| 607 | 614 | } |
| 608 | 615 | } |
| ... | ... | @@ -663,7 +670,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void |
| 663 | 670 | windows.ERROR.FILE_NOT_FOUND => error.FileNotFound, |
| 664 | 671 | windows.ERROR.ACCESS_DENIED => error.AccessDenied, |
| 665 | 672 | windows.ERROR.FILENAME_EXCED_RANGE, windows.ERROR.INVALID_PARAMETER => error.NameTooLong, |
| 666 | | else => error.Unexpected, |
| 673 | else => unexpectedErrorWindows(err), |
| 667 | 674 | } |
| 668 | 675 | } |
| 669 | 676 | } |
| ... | ... | @@ -689,7 +696,7 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void { |
| 689 | 696 | posix.ENOTDIR => error.NotDir, |
| 690 | 697 | posix.ENOMEM => error.SystemResources, |
| 691 | 698 | posix.EROFS => error.ReadOnlyFileSystem, |
| 692 | | else => error.Unexpected, |
| 699 | else => unexpectedErrorPosix(err), |
| 693 | 700 | }; |
| 694 | 701 | } |
| 695 | 702 | } |
| ... | ... | @@ -743,7 +750,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) |
| 743 | 750 | if (windows.MoveFileExA(old_buf.ptr, new_buf.ptr, flags) == 0) { |
| 744 | 751 | const err = windows.GetLastError(); |
| 745 | 752 | return switch (err) { |
| 746 | | else => return error.Unexpected, |
| 753 | else => unexpectedErrorWindows(err), |
| 747 | 754 | }; |
| 748 | 755 | } |
| 749 | 756 | } else { |
| ... | ... | @@ -765,7 +772,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) |
| 765 | 772 | posix.EEXIST, posix.ENOTEMPTY => error.PathAlreadyExists, |
| 766 | 773 | posix.EROFS => error.ReadOnlyFileSystem, |
| 767 | 774 | posix.EXDEV => error.RenameAcrossMountPoints, |
| 768 | | else => error.Unexpected, |
| 775 | else => unexpectedErrorPosix(err), |
| 769 | 776 | }; |
| 770 | 777 | } |
| 771 | 778 | } |
| ... | ... | @@ -788,7 +795,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 788 | 795 | return switch (err) { |
| 789 | 796 | windows.ERROR.ALREADY_EXISTS => error.PathAlreadyExists, |
| 790 | 797 | windows.ERROR.PATH_NOT_FOUND => error.FileNotFound, |
| 791 | | else => error.Unexpected, |
| 798 | else => unexpectedErrorWindows(err), |
| 792 | 799 | }; |
| 793 | 800 | } |
| 794 | 801 | } |
| ... | ... | @@ -812,7 +819,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 812 | 819 | posix.ENOSPC => error.NoSpaceLeft, |
| 813 | 820 | posix.ENOTDIR => error.NotDir, |
| 814 | 821 | posix.EROFS => error.ReadOnlyFileSystem, |
| 815 | | else => error.Unexpected, |
| 822 | else => unexpectedErrorPosix(err), |
| 816 | 823 | }; |
| 817 | 824 | } |
| 818 | 825 | } |
| ... | ... | @@ -877,7 +884,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 877 | 884 | posix.ENOTDIR => error.NotDir, |
| 878 | 885 | posix.EEXIST, posix.ENOTEMPTY => error.DirNotEmpty, |
| 879 | 886 | posix.EROFS => error.ReadOnlyFileSystem, |
| 880 | | else => error.Unexpected, |
| 887 | else => unexpectedErrorPosix(err), |
| 881 | 888 | }; |
| 882 | 889 | } |
| 883 | 890 | } |
| ... | ... | @@ -988,7 +995,7 @@ pub const Dir = struct { |
| 988 | 995 | self.buf = %return self.allocator.realloc(u8, self.buf, self.buf.len * 2); |
| 989 | 996 | continue; |
| 990 | 997 | }, |
| 991 | | else => return error.Unexpected, |
| 998 | else => return unexpectedErrorPosix(err), |
| 992 | 999 | }; |
| 993 | 1000 | } |
| 994 | 1001 | if (result == 0) |
| ... | ... | @@ -1045,7 +1052,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 1045 | 1052 | posix.ENOENT => error.FileNotFound, |
| 1046 | 1053 | posix.ENOMEM => error.SystemResources, |
| 1047 | 1054 | posix.ENOTDIR => error.NotDir, |
| 1048 | | else => error.Unexpected, |
| 1055 | else => unexpectedErrorPosix(err), |
| 1049 | 1056 | }; |
| 1050 | 1057 | } |
| 1051 | 1058 | } |
| ... | ... | @@ -1073,7 +1080,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1073 | 1080 | posix.ENOENT => error.FileNotFound, |
| 1074 | 1081 | posix.ENOMEM => error.SystemResources, |
| 1075 | 1082 | posix.ENOTDIR => error.NotDir, |
| 1076 | | else => error.Unexpected, |
| 1083 | else => unexpectedErrorPosix(err), |
| 1077 | 1084 | }; |
| 1078 | 1085 | } |
| 1079 | 1086 | if (ret_val == result_buf.len) { |
| ... | ... | @@ -1132,7 +1139,6 @@ test "os.sleep" { |
| 1132 | 1139 | error ResourceLimitReached; |
| 1133 | 1140 | error InvalidUserId; |
| 1134 | 1141 | error PermissionDenied; |
| 1135 | | error Unexpected; |
| 1136 | 1142 | |
| 1137 | 1143 | pub fn posix_setuid(uid: u32) -> %void { |
| 1138 | 1144 | const err = posix.getErrno(posix.setuid(uid)); |
| ... | ... | @@ -1141,7 +1147,7 @@ pub fn posix_setuid(uid: u32) -> %void { |
| 1141 | 1147 | posix.EAGAIN => error.ResourceLimitReached, |
| 1142 | 1148 | posix.EINVAL => error.InvalidUserId, |
| 1143 | 1149 | posix.EPERM => error.PermissionDenied, |
| 1144 | | else => error.Unexpected, |
| 1150 | else => unexpectedErrorPosix(err), |
| 1145 | 1151 | }; |
| 1146 | 1152 | } |
| 1147 | 1153 | |
| ... | ... | @@ -1152,7 +1158,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) -> %void { |
| 1152 | 1158 | posix.EAGAIN => error.ResourceLimitReached, |
| 1153 | 1159 | posix.EINVAL => error.InvalidUserId, |
| 1154 | 1160 | posix.EPERM => error.PermissionDenied, |
| 1155 | | else => error.Unexpected, |
| 1161 | else => unexpectedErrorPosix(err), |
| 1156 | 1162 | }; |
| 1157 | 1163 | } |
| 1158 | 1164 | |
| ... | ... | @@ -1163,7 +1169,7 @@ pub fn posix_setgid(gid: u32) -> %void { |
| 1163 | 1169 | posix.EAGAIN => error.ResourceLimitReached, |
| 1164 | 1170 | posix.EINVAL => error.InvalidUserId, |
| 1165 | 1171 | posix.EPERM => error.PermissionDenied, |
| 1166 | | else => error.Unexpected, |
| 1172 | else => unexpectedErrorPosix(err), |
| 1167 | 1173 | }; |
| 1168 | 1174 | } |
| 1169 | 1175 | |
| ... | ... | @@ -1174,7 +1180,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) -> %void { |
| 1174 | 1180 | posix.EAGAIN => error.ResourceLimitReached, |
| 1175 | 1181 | posix.EINVAL => error.InvalidUserId, |
| 1176 | 1182 | posix.EPERM => error.PermissionDenied, |
| 1177 | | else => error.Unexpected, |
| 1183 | else => unexpectedErrorPosix(err), |
| 1178 | 1184 | }; |
| 1179 | 1185 | } |
| 1180 | 1186 | |
| ... | ... | @@ -1417,3 +1423,29 @@ test "std.os" { |
| 1417 | 1423 | _ = @import("path.zig"); |
| 1418 | 1424 | _ = @import("windows/index.zig"); |
| 1419 | 1425 | } |
| 1426 | |
| 1427 | |
| 1428 | error Unexpected; |
| 1429 | |
| 1430 | // TODO make this a build variable that you can set |
| 1431 | const unexpected_error_tracing = false; |
| 1432 | |
| 1433 | /// Call this when you made a syscall or something that sets errno |
| 1434 | /// and you get an unexpected error. |
| 1435 | pub fn unexpectedErrorPosix(errno: c_int) -> error { |
| 1436 | if (unexpected_error_tracing) { |
| 1437 | io.stderr.printf("unexpected errno: {}\n", errno) %% return; |
| 1438 | debug.printStackTrace() %% return; |
| 1439 | } |
| 1440 | return error.Unexpected; |
| 1441 | } |
| 1442 | |
| 1443 | /// Call this when you made a windows DLL call or something that does SetLastError |
| 1444 | /// and you get an unexpected error. |
| 1445 | pub fn unexpectedErrorWindows(err: windows.DWORD) -> error { |
| 1446 | if (unexpected_error_tracing) { |
| 1447 | io.stderr.printf("unexpected GetLastError(): {}\n", err) %% return; |
| 1448 | debug.printStackTrace() %% return; |
| 1449 | } |
| 1450 | return error.Unexpected; |
| 1451 | } |