diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-01-31 01:51:15 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-01-31 01:51:31 -0500 |
| commit | 5161d70620342749b1995fdaabb39220654cc941 (patch) | |
| tree | ba940c1a85386f1866cd75aab67809b4c0c95755 /std/os | |
| parent | 40ca39d3d5a556e3b5d7298e3a5182f4351bdd17 (diff) | |
| download | zig-5161d70620342749b1995fdaabb39220654cc941.tar.gz zig-5161d70620342749b1995fdaabb39220654cc941.zip | |
*WIP* error sets
Diffstat (limited to 'std/os')
| -rw-r--r-- | std/os/index.zig | 120 |
1 files changed, 43 insertions, 77 deletions
diff --git a/std/os/index.zig b/std/os/index.zig index 4451faf103..6592facf51 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -57,25 +57,10 @@ const ArrayList = std.ArrayList; const Buffer = std.Buffer; const math = std.math; -error SystemResources; -error AccessDenied; -error InvalidExe; -error FileSystem; -error IsDir; -error FileNotFound; -error FileBusy; -error PathAlreadyExists; -error SymLinkLoop; -error ReadOnlyFileSystem; -error LinkQuotaExceeded; -error RenameAcrossMountPoints; -error DirNotEmpty; -error WouldBlock; - /// Fills `buf` with random bytes. If linking against libc, this calls the /// appropriate OS-specific library call. Otherwise it uses the zig standard /// library implementation. -pub fn getRandomBytes(buf: []u8) %void { +pub fn getRandomBytes(buf: []u8) !void { switch (builtin.os) { Os.linux => while (true) { // TODO check libc version and potentially call c.getrandom. @@ -182,7 +167,7 @@ pub fn close(handle: FileHandle) void { } /// Calls POSIX read, and keeps trying if it gets interrupted. -pub fn posixRead(fd: i32, buf: []u8) %void { +pub fn posixRead(fd: i32, buf: []u8) !void { var index: usize = 0; while (index < buf.len) { const amt_written = posix.read(fd, &buf[index], buf.len - index); @@ -203,17 +188,8 @@ pub fn posixRead(fd: i32, buf: []u8) %void { } } -error WouldBlock; -error FileClosed; -error DestinationAddressRequired; -error DiskQuota; -error FileTooBig; -error InputOutput; -error NoSpaceLeft; -error BrokenPipe; - /// Calls POSIX write, and keeps trying if it gets interrupted. -pub fn posixWrite(fd: i32, bytes: []const u8) %void { +pub fn posixWrite(fd: i32, bytes: []const u8) !void { while (true) { const write_ret = posix.write(fd, bytes.ptr, bytes.len); const write_err = posix.getErrno(write_ret); @@ -243,7 +219,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) %void { /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. /// Calls POSIX open, keeps trying if it gets interrupted, and translates /// the return value into zig errors. -pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) %i32 { +pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) !i32 { var stack_buf: [max_noalloc_path_len]u8 = undefined; var path0: []u8 = undefined; var need_free = false; @@ -292,7 +268,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al } } -pub fn posixDup2(old_fd: i32, new_fd: i32) %void { +pub fn posixDup2(old_fd: i32, new_fd: i32) !void { while (true) { const err = posix.getErrno(posix.dup2(old_fd, new_fd)); if (err > 0) { @@ -307,7 +283,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) %void { } } -pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) %[]?&u8 { +pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) ![]?&u8 { const envp_count = env_map.count(); const envp_buf = try allocator.alloc(?&u8, envp_count + 1); mem.set(?&u8, envp_buf, null); @@ -344,7 +320,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) void { /// `argv[0]` is the executable path. /// This function also uses the PATH environment variable to get the full path to the executable. pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, - allocator: &Allocator) %void + allocator: &Allocator) !void { const argv_buf = try allocator.alloc(?&u8, argv.len + 1); mem.set(?&u8, argv_buf, null); @@ -419,7 +395,7 @@ fn posixExecveErrnoToErr(err: usize) error { pub var posix_environ_raw: []&u8 = undefined; /// Caller must free result when done. -pub fn getEnvMap(allocator: &Allocator) %BufMap { +pub fn getEnvMap(allocator: &Allocator) !BufMap { var result = BufMap.init(allocator); errdefer result.deinit(); @@ -480,10 +456,8 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 { return null; } -error EnvironmentVariableNotFound; - /// Caller must free returned memory. -pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) %[]u8 { +pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) ![]u8 { if (is_windows) { const key_with_null = try cstr.addNullByte(allocator, key); defer allocator.free(key_with_null); @@ -517,7 +491,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) %[]u8 { } /// Caller must free the returned memory. -pub fn getCwd(allocator: &Allocator) %[]u8 { +pub fn getCwd(allocator: &Allocator) ![]u8 { switch (builtin.os) { Os.windows => { var buf = try allocator.alloc(u8, 256); @@ -564,7 +538,7 @@ test "os.getCwd" { _ = getCwd(debug.global_allocator); } -pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void { +pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void { if (is_windows) { return symLinkWindows(allocator, existing_path, new_path); } else { @@ -572,7 +546,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con } } -pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void { +pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void { const existing_with_null = try cstr.addNullByte(allocator, existing_path); defer allocator.free(existing_with_null); const new_with_null = try cstr.addNullByte(allocator, new_path); @@ -586,7 +560,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path } } -pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void { +pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void { const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2); defer allocator.free(full_buf); @@ -623,7 +597,7 @@ const b64_fs_encoder = base64.Base64Encoder.init( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", base64.standard_pad_char); -pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void { +pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void { if (symLink(allocator, existing_path, new_path)) { return; } else |err| { @@ -652,7 +626,7 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: } -pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void { +pub fn deleteFile(allocator: &Allocator, file_path: []const u8) !void { if (builtin.os == Os.windows) { return deleteFileWindows(allocator, file_path); } else { @@ -660,10 +634,7 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void { } } -error FileNotFound; -error AccessDenied; - -pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void { +pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) !void { const buf = try allocator.alloc(u8, file_path.len + 1); defer allocator.free(buf); @@ -681,7 +652,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void { } } -pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void { +pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) !void { const buf = try allocator.alloc(u8, file_path.len + 1); defer allocator.free(buf); @@ -708,13 +679,13 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void { } /// Calls ::copyFileMode with 0o666 for the mode. -pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []const u8) %void { +pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []const u8) !void { return copyFileMode(allocator, source_path, dest_path, 0o666); } // TODO instead of accepting a mode argument, use the mode from fstat'ing the source path once open /// Guaranteed to be atomic. -pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) %void { +pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) !void { var rand_buf: [12]u8 = undefined; const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); defer allocator.free(tmp_path); @@ -738,7 +709,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [ } } -pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) %void { +pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) !void { const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2); defer allocator.free(full_buf); @@ -783,7 +754,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) } } -pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void { +pub fn makeDir(allocator: &Allocator, dir_path: []const u8) !void { if (is_windows) { return makeDirWindows(allocator, dir_path); } else { @@ -791,7 +762,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void { } } -pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void { +pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) !void { const path_buf = try cstr.addNullByte(allocator, dir_path); defer allocator.free(path_buf); @@ -805,7 +776,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void { } } -pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void { +pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) !void { const path_buf = try cstr.addNullByte(allocator, dir_path); defer allocator.free(path_buf); @@ -831,7 +802,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void { /// Calls makeDir recursively to make an entire path. Returns success if the path /// already exists and is a directory. -pub fn makePath(allocator: &Allocator, full_path: []const u8) %void { +pub fn makePath(allocator: &Allocator, full_path: []const u8) !void { const resolved_path = try path.resolve(allocator, full_path); defer allocator.free(resolved_path); @@ -869,7 +840,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) %void { /// Returns ::error.DirNotEmpty if the directory is not empty. /// To delete a directory recursively, see ::deleteTree -pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) %void { +pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void { const path_buf = try allocator.alloc(u8, dir_path.len + 1); defer allocator.free(path_buf); @@ -898,7 +869,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) %void { /// removes it. If it cannot be removed because it is a non-empty directory, /// this function recursively removes its entries and then tries again. // TODO non-recursive implementation -pub fn deleteTree(allocator: &Allocator, full_path: []const u8) %void { +pub fn deleteTree(allocator: &Allocator, full_path: []const u8) !void { start_over: while (true) { // First, try deleting the item as a file. This way we don't follow sym links. if (deleteFile(allocator, full_path)) { @@ -967,7 +938,7 @@ pub const Dir = struct { }; }; - pub fn open(allocator: &Allocator, dir_path: []const u8) %Dir { + pub fn open(allocator: &Allocator, dir_path: []const u8) !Dir { const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); return Dir { .allocator = allocator, @@ -985,7 +956,7 @@ pub const Dir = struct { /// Memory such as file names referenced in this returned entry becomes invalid /// with subsequent calls to next, as well as when this ::Dir is deinitialized. - pub fn next(self: &Dir) %?Entry { + pub fn next(self: &Dir) !?Entry { start_over: while (true) { if (self.index >= self.end_index) { if (self.buf.len == 0) { @@ -1042,7 +1013,7 @@ pub const Dir = struct { } }; -pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void { +pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) !void { const path_buf = try allocator.alloc(u8, dir_path.len + 1); defer allocator.free(path_buf); @@ -1066,7 +1037,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void { } /// Read value of a symbolic link. -pub fn readLink(allocator: &Allocator, pathname: []const u8) %[]u8 { +pub fn readLink(allocator: &Allocator, pathname: []const u8) ![]u8 { const path_buf = try allocator.alloc(u8, pathname.len + 1); defer allocator.free(path_buf); @@ -1143,11 +1114,7 @@ test "os.sleep" { sleep(0, 1); } -error ResourceLimitReached; -error InvalidUserId; -error PermissionDenied; - -pub fn posix_setuid(uid: u32) %void { +pub fn posix_setuid(uid: u32) !void { const err = posix.getErrno(posix.setuid(uid)); if (err == 0) return; return switch (err) { @@ -1158,7 +1125,7 @@ pub fn posix_setuid(uid: u32) %void { }; } -pub fn posix_setreuid(ruid: u32, euid: u32) %void { +pub fn posix_setreuid(ruid: u32, euid: u32) !void { const err = posix.getErrno(posix.setreuid(ruid, euid)); if (err == 0) return; return switch (err) { @@ -1169,7 +1136,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) %void { }; } -pub fn posix_setgid(gid: u32) %void { +pub fn posix_setgid(gid: u32) !void { const err = posix.getErrno(posix.setgid(gid)); if (err == 0) return; return switch (err) { @@ -1180,7 +1147,7 @@ pub fn posix_setgid(gid: u32) %void { }; } -pub fn posix_setregid(rgid: u32, egid: u32) %void { +pub fn posix_setregid(rgid: u32, egid: u32) !void { const err = posix.getErrno(posix.setregid(rgid, egid)); if (err == 0) return; return switch (err) { @@ -1191,8 +1158,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) %void { }; } -error NoStdHandles; -pub fn windowsGetStdHandle(handle_id: windows.DWORD) %windows.HANDLE { +pub fn windowsGetStdHandle(handle_id: windows.DWORD) !windows.HANDLE { if (windows.GetStdHandle(handle_id)) |handle| { if (handle == windows.INVALID_HANDLE_VALUE) { const err = windows.GetLastError(); @@ -1261,7 +1227,7 @@ pub const ArgIteratorWindows = struct { } /// You must free the returned memory when done. - pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?%[]u8 { + pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?internalNext.errors![]u8 { // march forward over whitespace while (true) : (self.index += 1) { const byte = self.cmd_line[self.index]; @@ -1314,7 +1280,7 @@ pub const ArgIteratorWindows = struct { } } - fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) %[]u8 { + fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) ![]u8 { var buf = try Buffer.initSize(allocator, 0); defer buf.deinit(); @@ -1358,7 +1324,7 @@ pub const ArgIteratorWindows = struct { } } - fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) %void { + fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) !void { var i: usize = 0; while (i < emit_count) : (i += 1) { try buf.appendByte('\\'); @@ -1397,7 +1363,7 @@ pub const ArgIterator = struct { } /// You must free the returned memory when done. - pub fn next(self: &ArgIterator, allocator: &Allocator) ?%[]u8 { + pub fn next(self: &ArgIterator, allocator: &Allocator) ?![]u8 { if (builtin.os == Os.windows) { return self.inner.next(allocator); } else { @@ -1422,7 +1388,7 @@ pub fn args() ArgIterator { } /// Caller must call freeArgs on result. -pub fn argsAlloc(allocator: &mem.Allocator) %[]const []u8 { +pub fn argsAlloc(allocator: &mem.Allocator) ![]const []u8 { // TODO refactor to only make 1 allocation. var it = args(); var contents = try Buffer.initSize(allocator, 0); @@ -1529,7 +1495,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) error { return error.Unexpected; } -pub fn openSelfExe() %io.File { +pub fn openSelfExe() !io.File { switch (builtin.os) { Os.linux => { return io.File.openRead("/proc/self/exe", null); @@ -1547,7 +1513,7 @@ pub fn openSelfExe() %io.File { /// This function may return an error if the current executable /// was deleted after spawning. /// Caller owns returned memory. -pub fn selfExePath(allocator: &mem.Allocator) %[]u8 { +pub fn selfExePath(allocator: &mem.Allocator) ![]u8 { switch (builtin.os) { Os.linux => { // If the currently executing binary has been deleted, @@ -1590,7 +1556,7 @@ pub fn selfExePath(allocator: &mem.Allocator) %[]u8 { /// Get the directory path that contains the current executable. /// Caller owns returned memory. -pub fn selfExeDirPath(allocator: &mem.Allocator) %[]u8 { +pub fn selfExeDirPath(allocator: &mem.Allocator) ![]u8 { switch (builtin.os) { Os.linux => { // If the currently executing binary has been deleted, |
