From 44a049e01eef654fee82a1ee4e1aaf37447319ce Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 26 May 2019 13:37:34 -0400 Subject: [PATCH] more cleanup. down to just the `@hasDecl` builtin --- build.zig | 2 +- std/build.zig | 2 +- std/child_process.zig | 32 ++++------------------------- std/fs.zig | 7 +++++-- std/fs/file.zig | 6 +++--- std/os.zig | 3 ++- std/os/bits/linux/errno.zig | 1 + std/os/linux.zig | 4 ++-- std/os/windows.zig | 40 +++++++++++++++++++++++++++++++++++++ std/rand.zig | 6 +++--- test/tests.zig | 2 +- 11 files changed, 63 insertions(+), 42 deletions(-) diff --git a/build.zig b/build.zig index ec0bd9c02c..bb23502d82 100644 --- a/build.zig +++ b/build.zig @@ -166,7 +166,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void { } fn fileExists(filename: []const u8) !bool { - fs.File.access(filename) catch |err| switch (err) { + fs.File.exists(filename) catch |err| switch (err) { error.PermissionDenied, error.FileNotFound, => return false, diff --git a/std/build.zig b/std/build.zig index 115cb2c999..d427521251 100644 --- a/std/build.zig +++ b/std/build.zig @@ -846,7 +846,7 @@ pub const Target = union(enum) { } pub fn oFileExt(self: Target) []const u8 { - const abi = switch (self.*) { + const abi = switch (self) { Target.Native => builtin.abi, Target.Cross => |t| t.abi, }; diff --git a/std/child_process.zig b/std/child_process.zig index 6305f10344..f870f5e083 100644 --- a/std/child_process.zig +++ b/std/child_process.zig @@ -50,24 +50,8 @@ pub const ChildProcess = struct { err_pipe: if (os.windows.is_the_target) void else [2]i32, llnode: if (os.windows.is_the_target) void else LinkedList(*ChildProcess).Node, - pub const SpawnError = error{ - ProcessFdQuotaExceeded, - Unexpected, - NotDir, - SystemResources, - FileNotFound, - NameTooLong, - SymLinkLoop, - FileSystem, - OutOfMemory, - AccessDenied, - PermissionDenied, - InvalidUserId, - ResourceLimitReached, - InvalidExe, - IsDir, - FileBusy, - }; + pub const SpawnError = error{OutOfMemory} || os.ExecveError || os.SetIdError || + os.ChangeCurDirError || windows.CreateProcessError; pub const Term = union(enum) { Exited: i32, @@ -640,7 +624,7 @@ fn windowsCreateProcess(app_name: [*]u16, cmd_line: [*]u16, envp_ptr: ?[*]u16, c // However this would imply that programs compiled with -DUNICODE could not pass // environment variables to programs that were not, which seems unlikely. // More investigation is needed. - if (windows.CreateProcessW( + return windows.CreateProcessW( app_name, cmd_line, null, @@ -651,15 +635,7 @@ fn windowsCreateProcess(app_name: [*]u16, cmd_line: [*]u16, envp_ptr: ?[*]u16, c cwd_ptr, lpStartupInfo, lpProcessInformation, - ) == 0) { - switch (windows.GetLastError()) { - windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound, - windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound, - windows.ERROR.INVALID_PARAMETER => unreachable, - windows.ERROR.INVALID_NAME => return error.InvalidName, - else => |err| return windows.unexpectedError(err), - } - } + ); } /// Caller must dealloc. diff --git a/std/fs.zig b/std/fs.zig index b81bc38a75..dcb3143f79 100644 --- a/std/fs.zig +++ b/std/fs.zig @@ -2,7 +2,10 @@ const builtin = @import("builtin"); const std = @import("std.zig"); const os = std.os; const mem = std.mem; +const base64 = std.base64; +const crypto = std.crypto; const Allocator = std.mem.Allocator; +const assert = std.debug.assert; pub const path = @import("fs/path.zig"); pub const File = @import("fs/file.zig").File; @@ -73,7 +76,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: mem.copy(u8, tmp_path[0..], dirname); tmp_path[dirname.len] = path.sep; while (true) { - try getRandomBytes(rand_buf[0..]); + try crypto.randomBytes(rand_buf[0..]); b64_fs_encoder.encode(tmp_path[dirname.len + 1 ..], rand_buf); if (symLink(existing_path, tmp_path)) { @@ -159,7 +162,7 @@ pub const AtomicFile = struct { tmp_path_buf[tmp_path_len] = 0; while (true) { - try getRandomBytes(rand_buf[0..]); + try crypto.randomBytes(rand_buf[0..]); b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], rand_buf); const file = File.openWriteNoClobberC(&tmp_path_buf, mode) catch |err| switch (err) { diff --git a/std/fs/file.zig b/std/fs/file.zig index 7cbbd4a4f0..915dae331f 100644 --- a/std/fs/file.zig +++ b/std/fs/file.zig @@ -137,17 +137,17 @@ pub const File = struct { /// Test for the existence of `path`. /// `path` is UTF8-encoded. - pub fn exists(path: []const u8) AccessError!void { + pub fn exists(path: []const u8) !void { return os.access(path, os.F_OK); } /// Same as `exists` except the parameter is null-terminated. - pub fn existsC(path: [*]const u8) AccessError!void { + pub fn existsC(path: [*]const u8) !void { return os.accessC(path, os.F_OK); } /// Same as `exists` except the parameter is null-terminated UTF16LE-encoded. - pub fn existsW(path: [*]const u16) AccessError!void { + pub fn existsW(path: [*]const u16) !void { return os.accessW(path, os.F_OK); } diff --git a/std/os.zig b/std/os.zig index ef4d695aff..0efc2ebca7 100644 --- a/std/os.zig +++ b/std/os.zig @@ -86,7 +86,7 @@ pub fn close(fd: fd_t) void { } } -pub const GetRandomError = error{}; +pub const GetRandomError = OpenError; /// Obtain a series of random bytes. These bytes can be used to seed user-space /// random number generators or for cryptographic purposes. @@ -641,6 +641,7 @@ pub const ExecveError = error{ NotDir, FileBusy, ProcessFdQuotaExceeded, + SystemFdQuotaExceeded, NameTooLong, Unexpected, diff --git a/std/os/bits/linux/errno.zig b/std/os/bits/linux/errno.zig index 5ad8777f92..741f76fdee 100644 --- a/std/os/bits/linux/errno.zig +++ b/std/os/bits/linux/errno.zig @@ -279,6 +279,7 @@ pub const ESOCKTNOSUPPORT = 94; /// Operation not supported on transport endpoint pub const EOPNOTSUPP = 95; +pub const ENOTSUP = EOPNOTSUPP; /// Protocol family not supported pub const EPFNOSUPPORT = 96; diff --git a/std/os/linux.zig b/std/os/linux.zig index 958c699dc5..4b00433b6c 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -382,8 +382,8 @@ pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize { return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags); } -pub fn waitpid(pid: i32, status: *i32, options: i32) usize { - return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0); +pub fn waitpid(pid: i32, status: *i32, flags: u32) usize { + return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), flags, 0); } var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime); diff --git a/std/os/windows.zig b/std/os/windows.zig index fbb8ff42c5..9bfeee9fe1 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -1140,6 +1140,46 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) G return rc; } +pub const CreateProcessError = error{ + FileNotFound, + InvalidName, + Unexpected, +}; + +pub fn CreateProcessW( + lpApplicationName: ?LPWSTR, + lpCommandLine: LPWSTR, + lpProcessAttributes: ?*SECURITY_ATTRIBUTES, + lpThreadAttributes: ?*SECURITY_ATTRIBUTES, + bInheritHandles: BOOL, + dwCreationFlags: DWORD, + lpEnvironment: ?*c_void, + lpCurrentDirectory: ?LPWSTR, + lpStartupInfo: *STARTUPINFOW, + lpProcessInformation: *PROCESS_INFORMATION, +) CreateProcessError!void { + if (kernel32.CreateProcessW( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandle, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation, + ) == 0) { + switch (kernel32.GetLastError()) { + ERROR.FILE_NOT_FOUND => return error.FileNotFound, + ERROR.PATH_NOT_FOUND => return error.FileNotFound, + ERROR.INVALID_PARAMETER => unreachable, + ERROR.INVALID_NAME => return error.InvalidName, + else => |err| return unexpectedError(err), + } + } +} + pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 { return sliceToPrefixedFileW(mem.toSliceConst(u8, s)); } diff --git a/std/rand.zig b/std/rand.zig index 4a6563f65a..770ae1b0a8 100644 --- a/std/rand.zig +++ b/std/rand.zig @@ -1,10 +1,10 @@ -// The engines provided here should be initialized from an external source. For now, getRandomBytes -// from the os package is the most suitable. Be sure to use a CSPRNG when required, otherwise using +// The engines provided here should be initialized from an external source. For now, randomBytes +// from the crypto package is the most suitable. Be sure to use a CSPRNG when required, otherwise using // a normal PRNG will be faster and use substantially less stack space. // // ``` // var buf: [8]u8 = undefined; -// try std.os.getRandomBytes(buf[0..]); +// try std.crypto.randomBytes(buf[0..]); // const seed = mem.readIntSliceLittle(u64, buf[0..8]); // // var r = DefaultPrng.init(seed); diff --git a/test/tests.zig b/test/tests.zig index 061d4cb55f..9bd9292b84 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -112,7 +112,7 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M const exe = b.addExecutable("test-cli", "test/cli.zig"); const run_cmd = exe.run(); run_cmd.addArgs([][]const u8{ - fs.path.realAlloc(b.allocator, b.zig_exe) catch unreachable, + fs.realpathAlloc(b.allocator, b.zig_exe) catch unreachable, b.pathFromRoot(b.cache_root), });