Commit 44a049e01e

Andrew Kelley <andrew@ziglang.org>
2019-05-26 19:37:34
more cleanup. down to just the `@hasDecl` builtin
1 parent 2f040a2
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);
     }
 
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;
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);
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));
 }
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,
         };
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.
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) {
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,
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);
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),
     });
 
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,