Commit 2f040a23c8

Andrew Kelley <andrew@ziglang.org>
2019-05-26 19:17:34
clean up references to os
1 parent 7cb6279
doc/docgen.zig
@@ -1,7 +1,9 @@
 const builtin = @import("builtin");
 const std = @import("std");
 const io = std.io;
-const os = std.os;
+const fs = std.fs;
+const process = std.process;
+const ChildProcess = std.ChildProcess;
 const warn = std.debug.warn;
 const mem = std.mem;
 const testing = std.testing;
@@ -11,7 +13,7 @@ const max_doc_file_size = 10 * 1024 * 1024;
 const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
 const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
 const tmp_dir_name = "docgen_tmp";
-const test_out_path = tmp_dir_name ++ os.path.sep_str ++ "test" ++ exe_ext;
+const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;
 
 pub fn main() !void {
     var direct_allocator = std.heap.DirectAllocator.init();
@@ -22,7 +24,7 @@ pub fn main() !void {
 
     const allocator = &arena.allocator;
 
-    var args_it = os.args();
+    var args_it = process.args();
 
     if (!args_it.skip()) @panic("expected self arg");
 
@@ -35,10 +37,10 @@ pub fn main() !void {
     const out_file_name = try (args_it.next(allocator) orelse @panic("expected output arg"));
     defer allocator.free(out_file_name);
 
-    var in_file = try os.File.openRead(in_file_name);
+    var in_file = try fs.File.openRead(in_file_name);
     defer in_file.close();
 
-    var out_file = try os.File.openWrite(out_file_name);
+    var out_file = try fs.File.openWrite(out_file_name);
     defer out_file.close();
 
     var file_in_stream = in_file.inStream();
@@ -46,13 +48,13 @@ pub fn main() !void {
     const input_file_bytes = try file_in_stream.stream.readAllAlloc(allocator, max_doc_file_size);
 
     var file_out_stream = out_file.outStream();
-    var buffered_out_stream = io.BufferedOutStream(os.File.WriteError).init(&file_out_stream.stream);
+    var buffered_out_stream = io.BufferedOutStream(fs.File.WriteError).init(&file_out_stream.stream);
 
     var tokenizer = Tokenizer.init(in_file_name, input_file_bytes);
     var toc = try genToc(allocator, &tokenizer);
 
-    try os.makePath(allocator, tmp_dir_name);
-    defer os.deleteTree(allocator, tmp_dir_name) catch {};
+    try fs.makePath(allocator, tmp_dir_name);
+    defer fs.deleteTree(allocator, tmp_dir_name) catch {};
 
     try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);
     try buffered_out_stream.flush();
@@ -950,7 +952,7 @@ fn tokenizeAndPrint(docgen_tokenizer: *Tokenizer, out: var, source_token: Token)
 fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
     var code_progress_index: usize = 0;
 
-    var env_map = try os.getEnvMap(allocator);
+    var env_map = try process.getEnvMap(allocator);
     try env_map.set("ZIG_DEBUG_COLOR", "1");
 
     const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe);
@@ -1012,7 +1014,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                 try tokenizeAndPrint(tokenizer, out, code.source_token);
                 try out.write("</pre>");
                 const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
-                const tmp_source_file_name = try os.path.join(
+                const tmp_source_file_name = try fs.path.join(
                     allocator,
                     [][]const u8{ tmp_dir_name, name_plus_ext },
                 );
@@ -1021,7 +1023,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                 switch (code.id) {
                     Code.Id.Exe => |expected_outcome| code_block: {
                         const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
-                        const tmp_bin_file_name = try os.path.join(
+                        const tmp_bin_file_name = try fs.path.join(
                             allocator,
                             [][]const u8{ tmp_dir_name, name_plus_bin_ext },
                         );
@@ -1056,7 +1058,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                         }
                         for (code.link_objects) |link_object| {
                             const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext);
-                            const full_path_object = try os.path.join(
+                            const full_path_object = try fs.path.join(
                                 allocator,
                                 [][]const u8{ tmp_dir_name, name_with_ext },
                             );
@@ -1076,7 +1078,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                             }
                         }
                         if (expected_outcome == .BuildFail) {
-                            const result = try os.ChildProcess.exec(
+                            const result = try ChildProcess.exec(
                                 allocator,
                                 build_args.toSliceConst(),
                                 null,
@@ -1084,7 +1086,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                                 max_doc_file_size,
                             );
                             switch (result.term) {
-                                os.ChildProcess.Term.Exited => |exit_code| {
+                                .Exited => |exit_code| {
                                     if (exit_code == 0) {
                                         warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
                                         for (build_args.toSliceConst()) |arg|
@@ -1113,7 +1115,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                         if (code.target_str) |triple| {
                             if (mem.startsWith(u8, triple, "wasm32") or
                                 mem.startsWith(u8, triple, "x86_64-linux") and
-                                (builtin.os != builtin.Os.linux or builtin.arch != builtin.Arch.x86_64))
+                                (builtin.os != .linux or builtin.arch != .x86_64))
                             {
                                 // skip execution
                                 try out.print("</code></pre>\n");
@@ -1124,9 +1126,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                         const run_args = [][]const u8{tmp_bin_file_name};
 
                         const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
-                            const result = try os.ChildProcess.exec(allocator, run_args, null, &env_map, max_doc_file_size);
+                            const result = try ChildProcess.exec(allocator, run_args, null, &env_map, max_doc_file_size);
                             switch (result.term) {
-                                os.ChildProcess.Term.Exited => |exit_code| {
+                                .Exited => |exit_code| {
                                     if (exit_code == 0) {
                                         warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
                                         for (run_args) |arg|
@@ -1216,9 +1218,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                                 try out.print(" --release-small");
                             },
                         }
-                        const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
+                        const result = try ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
                         switch (result.term) {
-                            os.ChildProcess.Term.Exited => |exit_code| {
+                            .Exited => |exit_code| {
                                 if (exit_code == 0) {
                                     warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
                                     for (test_args.toSliceConst()) |arg|
@@ -1274,9 +1276,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                             },
                         }
 
-                        const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
+                        const result = try ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
                         switch (result.term) {
-                            os.ChildProcess.Term.Exited => |exit_code| {
+                            .Exited => |exit_code| {
                                 if (exit_code == 0) {
                                     warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
                                     for (test_args.toSliceConst()) |arg|
@@ -1310,7 +1312,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                     },
                     Code.Id.Obj => |maybe_error_match| {
                         const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, obj_ext);
-                        const tmp_obj_file_name = try os.path.join(
+                        const tmp_obj_file_name = try fs.path.join(
                             allocator,
                             [][]const u8{ tmp_dir_name, name_plus_obj_ext },
                         );
@@ -1318,7 +1320,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                         defer build_args.deinit();
 
                         const name_plus_h_ext = try std.fmt.allocPrint(allocator, "{}.h", code.name);
-                        const output_h_file_name = try os.path.join(
+                        const output_h_file_name = try fs.path.join(
                             allocator,
                             [][]const u8{ tmp_dir_name, name_plus_h_ext },
                         );
@@ -1367,9 +1369,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
                         }
 
                         if (maybe_error_match) |error_match| {
-                            const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, &env_map, max_doc_file_size);
+                            const result = try ChildProcess.exec(allocator, build_args.toSliceConst(), null, &env_map, max_doc_file_size);
                             switch (result.term) {
-                                os.ChildProcess.Term.Exited => |exit_code| {
+                                .Exited => |exit_code| {
                                     if (exit_code == 0) {
                                         warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
                                         for (build_args.toSliceConst()) |arg|
@@ -1448,10 +1450,10 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
     }
 }
 
-fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult {
-    const result = try os.ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size);
+fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {
+    const result = try ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size);
     switch (result.term) {
-        os.ChildProcess.Term.Exited => |exit_code| {
+        .Exited => |exit_code| {
             if (exit_code != 0) {
                 warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
                 for (args) |arg|
doc/langref.html.in
@@ -195,7 +195,7 @@ const std = @import("std");
 
 pub fn main() !void {
     // If this program is run without stdout attached, exit with an error.
-    const stdout_file = try std.os.File.stdout();
+    const stdout_file = try std.io.getStdOut();
     // If this program encounters pipe failure when printing to stdout, exit
     // with an error.
     try stdout_file.write("Hello, world!\n");
src-self-hosted/compilation.zig
@@ -1,5 +1,4 @@
 const std = @import("std");
-const os = std.os;
 const io = std.io;
 const mem = std.mem;
 const Allocator = mem.Allocator;
@@ -54,7 +53,7 @@ pub const ZigCompiler = struct {
         };
 
         var seed_bytes: [@sizeOf(u64)]u8 = undefined;
-        try std.os.getRandomBytes(seed_bytes[0..]);
+        try std.crypto.randomBytes(seed_bytes[0..]);
         const seed = mem.readIntNative(u64, &seed_bytes);
 
         return ZigCompiler{
@@ -487,7 +486,7 @@ pub const Compilation = struct {
         comp.name = try Buffer.init(comp.arena(), name);
         comp.llvm_triple = try target.getTriple(comp.arena());
         comp.llvm_target = try Target.llvmTargetFromTriple(comp.llvm_triple);
-        comp.zig_std_dir = try std.os.path.join(comp.arena(), [][]const u8{ zig_lib_dir, "std" });
+        comp.zig_std_dir = try std.fs.path.join(comp.arena(), [][]const u8{ zig_lib_dir, "std" });
 
         const opt_level = switch (build_mode) {
             builtin.Mode.Debug => llvm.CodeGenLevelNone,
@@ -529,8 +528,8 @@ pub const Compilation = struct {
         defer comp.events.destroy();
 
         if (root_src_path) |root_src| {
-            const dirname = std.os.path.dirname(root_src) orelse ".";
-            const basename = std.os.path.basename(root_src);
+            const dirname = std.fs.path.dirname(root_src) orelse ".";
+            const basename = std.fs.path.basename(root_src);
 
             comp.root_package = try Package.create(comp.arena(), dirname, basename);
             comp.std_package = try Package.create(comp.arena(), comp.zig_std_dir, "std.zig");
@@ -558,7 +557,7 @@ pub const Compilation = struct {
 
         if (comp.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
             // TODO evented I/O?
-            os.deleteTree(comp.arena(), tmp_dir) catch {};
+            std.fs.deleteTree(comp.arena(), tmp_dir) catch {};
         } else |_| {};
     }
 
@@ -970,8 +969,8 @@ pub const Compilation = struct {
     async fn initialCompile(self: *Compilation) !void {
         if (self.root_src_path) |root_src_path| {
             const root_scope = blk: {
-                // TODO async/await os.path.real
-                const root_src_real_path = os.path.realAlloc(self.gpa(), root_src_path) catch |err| {
+                // TODO async/await std.fs.realpath
+                const root_src_real_path = std.fs.realpathAlloc(self.gpa(), root_src_path) catch |err| {
                     try self.addCompileErrorCli(root_src_path, "unable to open: {}", @errorName(err));
                     return;
                 };
@@ -1196,7 +1195,7 @@ pub const Compilation = struct {
         const file_name = try std.fmt.allocPrint(self.gpa(), "{}{}", file_prefix[0..], suffix);
         defer self.gpa().free(file_name);
 
-        const full_path = try os.path.join(self.gpa(), [][]const u8{ tmp_dir, file_name[0..] });
+        const full_path = try std.fs.path.join(self.gpa(), [][]const u8{ tmp_dir, file_name[0..] });
         errdefer self.gpa().free(full_path);
 
         return Buffer.fromOwnedSlice(self.gpa(), full_path);
@@ -1217,8 +1216,8 @@ pub const Compilation = struct {
         const zig_dir_path = try getZigDir(self.gpa());
         defer self.gpa().free(zig_dir_path);
 
-        const tmp_dir = try os.path.join(self.arena(), [][]const u8{ zig_dir_path, comp_dir_name[0..] });
-        try os.makePath(self.gpa(), tmp_dir);
+        const tmp_dir = try std.fs.path.join(self.arena(), [][]const u8{ zig_dir_path, comp_dir_name[0..] });
+        try std.fs.makePath(self.gpa(), tmp_dir);
         return tmp_dir;
     }
 
@@ -1384,7 +1383,7 @@ async fn addFnToLinkSet(comp: *Compilation, fn_val: *Value.Fn) void {
 }
 
 fn getZigDir(allocator: *mem.Allocator) ![]u8 {
-    return os.getAppDataDir(allocator, "zig");
+    return std.fs.getAppDataDir(allocator, "zig");
 }
 
 async fn analyzeFnType(
src-self-hosted/errmsg.zig
@@ -1,6 +1,7 @@
 const std = @import("std");
 const mem = std.mem;
-const os = std.os;
+const fs = std.fs;
+const process = std.process;
 const Token = std.zig.Token;
 const ast = std.zig.ast;
 const TokenIndex = std.zig.ast.TokenIndex;
@@ -239,10 +240,10 @@ pub const Msg = struct {
         const allocator = msg.getAllocator();
         const tree = msg.getTree();
 
-        const cwd = try os.getCwdAlloc(allocator);
+        const cwd = try process.getCwdAlloc(allocator);
         defer allocator.free(cwd);
 
-        const relpath = try os.path.relative(allocator, cwd, msg.realpath);
+        const relpath = try fs.path.relative(allocator, cwd, msg.realpath);
         defer allocator.free(relpath);
 
         const path = if (relpath.len < msg.realpath.len) relpath else msg.realpath;
@@ -276,7 +277,7 @@ pub const Msg = struct {
         try stream.write("\n");
     }
 
-    pub fn printToFile(msg: *const Msg, file: os.File, color: Color) !void {
+    pub fn printToFile(msg: *const Msg, file: fs.File, color: Color) !void {
         const color_on = switch (color) {
             Color.Auto => file.isTty(),
             Color.On => true,
src-self-hosted/introspect.zig
@@ -2,19 +2,19 @@
 
 const std = @import("std");
 const mem = std.mem;
-const os = std.os;
+const fs = std.fs;
 
 const warn = std.debug.warn;
 
 /// Caller must free result
 pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
-    const test_zig_dir = try os.path.join(allocator, [][]const u8{ test_path, "lib", "zig" });
+    const test_zig_dir = try fs.path.join(allocator, [][]const u8{ test_path, "lib", "zig" });
     errdefer allocator.free(test_zig_dir);
 
-    const test_index_file = try os.path.join(allocator, [][]const u8{ test_zig_dir, "std", "std.zig" });
+    const test_index_file = try fs.path.join(allocator, [][]const u8{ test_zig_dir, "std", "std.zig" });
     defer allocator.free(test_index_file);
 
-    var file = try os.File.openRead(test_index_file);
+    var file = try fs.File.openRead(test_index_file);
     file.close();
 
     return test_zig_dir;
@@ -22,12 +22,12 @@ pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![
 
 /// Caller must free result
 pub fn findZigLibDir(allocator: *mem.Allocator) ![]u8 {
-    const self_exe_path = try os.selfExeDirPathAlloc(allocator);
+    const self_exe_path = try fs.selfExeDirPathAlloc(allocator);
     defer allocator.free(self_exe_path);
 
     var cur_path: []const u8 = self_exe_path;
     while (true) {
-        const test_dir = os.path.dirname(cur_path) orelse ".";
+        const test_dir = fs.path.dirname(cur_path) orelse ".";
 
         if (mem.eql(u8, test_dir, cur_path)) {
             break;
src-self-hosted/libc_installation.zig
@@ -3,6 +3,7 @@ const builtin = @import("builtin");
 const event = std.event;
 const Target = @import("target.zig").Target;
 const c = @import("c.zig");
+const fs = std.fs;
 
 /// See the render function implementation for documentation of the fields.
 pub const LibCInstallation = struct {
@@ -30,7 +31,7 @@ pub const LibCInstallation = struct {
         self: *LibCInstallation,
         allocator: *std.mem.Allocator,
         libc_file: []const u8,
-        stderr: *std.io.OutStream(std.os.File.WriteError),
+        stderr: *std.io.OutStream(fs.File.WriteError),
     ) !void {
         self.initEmpty();
 
@@ -100,7 +101,7 @@ pub const LibCInstallation = struct {
         }
     }
 
-    pub fn render(self: *const LibCInstallation, out: *std.io.OutStream(std.os.File.WriteError)) !void {
+    pub fn render(self: *const LibCInstallation, out: *std.io.OutStream(fs.File.WriteError)) !void {
         @setEvalBranchQuota(4000);
         try out.print(
             \\# The directory that contains `stdlib.h`.
@@ -148,7 +149,7 @@ pub const LibCInstallation = struct {
         errdefer if (windows_sdk) |sdk| c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk));
 
         switch (builtin.os) {
-            builtin.Os.windows => {
+            .windows => {
                 var sdk: *c.ZigWindowsSDK = undefined;
                 switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) {
                     c.ZigFindWindowsSdkError.None => {
@@ -166,13 +167,13 @@ pub const LibCInstallation = struct {
                     c.ZigFindWindowsSdkError.PathTooLong => return error.NotFound,
                 }
             },
-            builtin.Os.linux => {
+            .linux => {
                 try group.call(findNativeIncludeDirLinux, self, loop);
                 try group.call(findNativeLibDirLinux, self, loop);
                 try group.call(findNativeStaticLibDir, self, loop);
                 try group.call(findNativeDynamicLinker, self, loop);
             },
-            builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
+            .macosx, .freebsd, .netbsd => {
                 self.include_dir = try std.mem.dupe(loop.allocator, u8, "/usr/include");
             },
             else => @compileError("unimplemented: find libc for this OS"),
@@ -181,7 +182,7 @@ pub const LibCInstallation = struct {
     }
 
     async fn findNativeIncludeDirLinux(self: *LibCInstallation, loop: *event.Loop) !void {
-        const cc_exe = std.os.getEnvPosix("CC") orelse "cc";
+        const cc_exe = std.process.getEnvPosix("CC") orelse "cc";
         const argv = []const []const u8{
             cc_exe,
             "-E",
@@ -190,7 +191,7 @@ pub const LibCInstallation = struct {
             "/dev/null",
         };
         // TODO make this use event loop
-        const errorable_result = std.os.ChildProcess.exec(loop.allocator, argv, null, null, 1024 * 1024);
+        const errorable_result = std.ChildProcess.exec(loop.allocator, argv, null, null, 1024 * 1024);
         const exec_result = if (std.debug.runtime_safety) blk: {
             break :blk errorable_result catch unreachable;
         } else blk: {
@@ -205,7 +206,7 @@ pub const LibCInstallation = struct {
         }
 
         switch (exec_result.term) {
-            std.os.ChildProcess.Term.Exited => |code| {
+            std.ChildProcess.Term.Exited => |code| {
                 if (code != 0) return error.CCompilerExitCode;
             },
             else => {
@@ -230,7 +231,7 @@ pub const LibCInstallation = struct {
         while (path_i < search_paths.len) : (path_i += 1) {
             const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1);
             const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");
-            const stdlib_path = try std.os.path.join(loop.allocator, [][]const u8{ search_path, "stdlib.h" });
+            const stdlib_path = try fs.path.join(loop.allocator, [][]const u8{ search_path, "stdlib.h" });
             defer loop.allocator.free(stdlib_path);
 
             if (try fileExists(stdlib_path)) {
@@ -254,7 +255,7 @@ pub const LibCInstallation = struct {
             const stream = &std.io.BufferOutStream.init(&result_buf).stream;
             try stream.print("{}\\Include\\{}\\ucrt", search.path, search.version);
 
-            const stdlib_path = try std.os.path.join(
+            const stdlib_path = try fs.path.join(
                 loop.allocator,
                 [][]const u8{ result_buf.toSliceConst(), "stdlib.h" },
             );
@@ -286,7 +287,7 @@ pub const LibCInstallation = struct {
                 builtin.Arch.aarch64 => try stream.write("arm"),
                 else => return error.UnsupportedArchitecture,
             }
-            const ucrt_lib_path = try std.os.path.join(
+            const ucrt_lib_path = try fs.path.join(
                 loop.allocator,
                 [][]const u8{ result_buf.toSliceConst(), "ucrt.lib" },
             );
@@ -364,7 +365,7 @@ pub const LibCInstallation = struct {
                 builtin.Arch.aarch64 => try stream.write("arm\\"),
                 else => return error.UnsupportedArchitecture,
             }
-            const kernel32_path = try std.os.path.join(
+            const kernel32_path = try fs.path.join(
                 loop.allocator,
                 [][]const u8{ result_buf.toSliceConst(), "kernel32.lib" },
             );
@@ -391,14 +392,14 @@ pub const LibCInstallation = struct {
 
 /// caller owns returned memory
 async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bool) ![]u8 {
-    const cc_exe = std.os.getEnvPosix("CC") orelse "cc";
+    const cc_exe = std.process.getEnvPosix("CC") orelse "cc";
     const arg1 = try std.fmt.allocPrint(loop.allocator, "-print-file-name={}", o_file);
     defer loop.allocator.free(arg1);
     const argv = []const []const u8{ cc_exe, arg1 };
 
     // TODO This simulates evented I/O for the child process exec
     await (async loop.yield() catch unreachable);
-    const errorable_result = std.os.ChildProcess.exec(loop.allocator, argv, null, null, 1024 * 1024);
+    const errorable_result = std.ChildProcess.exec(loop.allocator, argv, null, null, 1024 * 1024);
     const exec_result = if (std.debug.runtime_safety) blk: {
         break :blk errorable_result catch unreachable;
     } else blk: {
@@ -412,7 +413,7 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo
         loop.allocator.free(exec_result.stderr);
     }
     switch (exec_result.term) {
-        std.os.ChildProcess.Term.Exited => |code| {
+        .Exited => |code| {
             if (code != 0) return error.CCompilerExitCode;
         },
         else => {
@@ -421,7 +422,7 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo
     }
     var it = std.mem.tokenize(exec_result.stdout, "\n\r");
     const line = it.next() orelse return error.LibCRuntimeNotFound;
-    const dirname = std.os.path.dirname(line) orelse return error.LibCRuntimeNotFound;
+    const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
 
     if (want_dirname) {
         return std.mem.dupe(loop.allocator, u8, dirname);
@@ -459,7 +460,7 @@ fn fillSearch(search_buf: *[2]Search, sdk: *c.ZigWindowsSDK) []Search {
 }
 
 fn fileExists(path: []const u8) !bool {
-    if (std.os.File.access(path)) |_| {
+    if (fs.File.access(path)) |_| {
         return true;
     } else |err| switch (err) {
         error.FileNotFound, error.PermissionDenied => return false,
src-self-hosted/link.zig
@@ -302,7 +302,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
         try ctx.args.append(c"--allow-shlib-undefined");
     }
 
-    if (ctx.comp.target.getOs() == builtin.Os.zen) {
+    if (ctx.comp.target.getOs() == .zen) {
         try ctx.args.append(c"-e");
         try ctx.args.append(c"_start");
 
@@ -311,7 +311,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
 }
 
 fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void {
-    const full_path = try std.os.path.join(&ctx.arena.allocator, [][]const u8{ dirname, basename });
+    const full_path = try std.fs.path.join(&ctx.arena.allocator, [][]const u8{ dirname, basename });
     const full_path_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, full_path);
     try ctx.args.append(full_path_with_null.ptr);
 }
@@ -668,7 +668,7 @@ const DarwinPlatform = struct {
                 break :blk ver;
             },
             Compilation.DarwinVersionMin.None => blk: {
-                assert(comp.target.getOs() == builtin.Os.macosx);
+                assert(comp.target.getOs() == .macosx);
                 result.kind = Kind.MacOS;
                 break :blk "10.10";
             },
src-self-hosted/main.zig
@@ -4,7 +4,9 @@ const builtin = @import("builtin");
 const event = std.event;
 const os = std.os;
 const io = std.io;
+const fs = std.fs;
 const mem = std.mem;
+const process = std.process;
 const Allocator = mem.Allocator;
 const ArrayList = std.ArrayList;
 const Buffer = std.Buffer;
@@ -20,9 +22,9 @@ const Target = @import("target.zig").Target;
 const errmsg = @import("errmsg.zig");
 const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
 
-var stderr_file: os.File = undefined;
-var stderr: *io.OutStream(os.File.WriteError) = undefined;
-var stdout: *io.OutStream(os.File.WriteError) = undefined;
+var stderr_file: fs.File = undefined;
+var stderr: *io.OutStream(fs.File.WriteError) = undefined;
+var stdout: *io.OutStream(fs.File.WriteError) = undefined;
 
 pub const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB
 
@@ -62,14 +64,14 @@ pub fn main() !void {
     var stderr_out_stream = stderr_file.outStream();
     stderr = &stderr_out_stream.stream;
 
-    const args = try os.argsAlloc(allocator);
+    const args = try process.argsAlloc(allocator);
     // TODO I'm getting  unreachable code here, which shouldn't happen
-    //defer os.argsFree(allocator, args);
+    //defer process.argsFree(allocator, args);
 
     if (args.len <= 1) {
         try stderr.write("expected command argument\n\n");
         try stderr.write(usage);
-        os.exit(1);
+        process.exit(1);
     }
 
     const commands = []Command{
@@ -125,7 +127,7 @@ pub fn main() !void {
 
     try stderr.print("unknown command: {}\n\n", args[1]);
     try stderr.write(usage);
-    os.exit(1);
+    process.exit(1);
 }
 
 const usage_build_generic =
@@ -256,7 +258,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
 
     if (flags.present("help")) {
         try stdout.write(usage_build_generic);
-        os.exit(0);
+        process.exit(0);
     }
 
     const build_mode = blk: {
@@ -324,14 +326,14 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
                 cur_pkg = parent;
             } else {
                 try stderr.print("encountered --pkg-end with no matching --pkg-begin\n");
-                os.exit(1);
+                process.exit(1);
             }
         }
     }
 
     if (cur_pkg.parent != null) {
         try stderr.print("unmatched --pkg-begin\n");
-        os.exit(1);
+        process.exit(1);
     }
 
     const provided_name = flags.single("name");
@@ -340,18 +342,18 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
         1 => flags.positionals.at(0),
         else => {
             try stderr.print("unexpected extra parameter: {}\n", flags.positionals.at(1));
-            os.exit(1);
+            process.exit(1);
         },
     };
 
     const root_name = if (provided_name) |n| n else blk: {
         if (root_source_file) |file| {
-            const basename = os.path.basename(file);
+            const basename = fs.path.basename(file);
             var it = mem.separate(basename, ".");
             break :blk it.next() orelse basename;
         } else {
             try stderr.write("--name [name] not provided and unable to infer\n");
-            os.exit(1);
+            process.exit(1);
         }
     };
 
@@ -361,12 +363,12 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
     const link_objects = flags.many("object");
     if (root_source_file == null and link_objects.len == 0 and assembly_files.len == 0) {
         try stderr.write("Expected source file argument or at least one --object or --assembly argument\n");
-        os.exit(1);
+        process.exit(1);
     }
 
     if (out_type == Compilation.Kind.Obj and link_objects.len != 0) {
         try stderr.write("When building an object file, --object arguments are invalid\n");
-        os.exit(1);
+        process.exit(1);
     }
 
     var clang_argv_buf = ArrayList([]const u8).init(allocator);
@@ -379,7 +381,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
     }
     try ZigCompiler.setLlvmArgv(allocator, mllvm_flags);
 
-    const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);
+    const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch process.exit(1);
     defer allocator.free(zig_lib_dir);
 
     var override_libc: LibCInstallation = undefined;
@@ -448,7 +450,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
 
     if (flags.single("mmacosx-version-min") != null and flags.single("mios-version-min") != null) {
         try stderr.write("-mmacosx-version-min and -mios-version-min options not allowed together\n");
-        os.exit(1);
+        process.exit(1);
     }
 
     if (flags.single("mmacosx-version-min")) |ver| {
@@ -478,16 +480,16 @@ async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
 
         switch (build_event) {
             Compilation.Event.Ok => {
-                stderr.print("Build {} succeeded\n", count) catch os.exit(1);
+                stderr.print("Build {} succeeded\n", count) catch process.exit(1);
             },
             Compilation.Event.Error => |err| {
-                stderr.print("Build {} failed: {}\n", count, @errorName(err)) catch os.exit(1);
+                stderr.print("Build {} failed: {}\n", count, @errorName(err)) catch process.exit(1);
             },
             Compilation.Event.Fail => |msgs| {
-                stderr.print("Build {} compile errors:\n", count) catch os.exit(1);
+                stderr.print("Build {} compile errors:\n", count) catch process.exit(1);
                 for (msgs) |msg| {
                     defer msg.destroy();
-                    msg.printToFile(stderr_file, color) catch os.exit(1);
+                    msg.printToFile(stderr_file, color) catch process.exit(1);
                 }
             },
         }
@@ -550,8 +552,8 @@ fn parseLibcPaths(allocator: *Allocator, libc: *LibCInstallation, libc_paths_fil
                 "Try running `zig libc` to see an example for the native target.\n",
             libc_paths_file,
             @errorName(err),
-        ) catch os.exit(1);
-        os.exit(1);
+        ) catch process.exit(1);
+        process.exit(1);
     };
 }
 
@@ -565,7 +567,7 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
         },
         else => {
             try stderr.print("unexpected extra parameter: {}\n", args[1]);
-            os.exit(1);
+            process.exit(1);
         },
     }
 
@@ -584,10 +586,10 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
 
 async fn findLibCAsync(zig_compiler: *ZigCompiler) void {
     const libc = (await (async zig_compiler.getNativeLibC() catch unreachable)) catch |err| {
-        stderr.print("unable to find libc: {}\n", @errorName(err)) catch os.exit(1);
-        os.exit(1);
+        stderr.print("unable to find libc: {}\n", @errorName(err)) catch process.exit(1);
+        process.exit(1);
     };
-    libc.render(stdout) catch os.exit(1);
+    libc.render(stdout) catch process.exit(1);
 }
 
 fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
@@ -596,7 +598,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
 
     if (flags.present("help")) {
         try stdout.write(usage_fmt);
-        os.exit(0);
+        process.exit(0);
     }
 
     const color = blk: {
@@ -616,7 +618,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
     if (flags.present("stdin")) {
         if (flags.positionals.len != 0) {
             try stderr.write("cannot use --stdin with positional arguments\n");
-            os.exit(1);
+            process.exit(1);
         }
 
         var stdin_file = try io.getStdIn();
@@ -627,7 +629,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
 
         const tree = std.zig.parse(allocator, source_code) catch |err| {
             try stderr.print("error parsing stdin: {}\n", err);
-            os.exit(1);
+            process.exit(1);
         };
         defer tree.deinit();
 
@@ -639,12 +641,12 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
             try msg.printToFile(stderr_file, color);
         }
         if (tree.errors.len != 0) {
-            os.exit(1);
+            process.exit(1);
         }
         if (flags.present("check")) {
             const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
             const code = if (anything_changed) u8(1) else u8(0);
-            os.exit(code);
+            process.exit(code);
         }
 
         _ = try std.zig.render(allocator, stdout, tree);
@@ -653,7 +655,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
 
     if (flags.positionals.len == 0) {
         try stderr.write("expected at least one source file argument\n");
-        os.exit(1);
+        process.exit(1);
     }
 
     var loop: event.Loop = undefined;
@@ -700,7 +702,7 @@ const FmtError = error{
     ReadOnlyFileSystem,
     LinkQuotaExceeded,
     FileBusy,
-} || os.File.OpenError;
+} || fs.File.OpenError;
 
 async fn asyncFmtMain(
     loop: *event.Loop,
@@ -725,7 +727,7 @@ async fn asyncFmtMain(
     }
     try await (async group.wait() catch unreachable);
     if (fmt.any_error) {
-        os.exit(1);
+        process.exit(1);
     }
 }
 
@@ -747,13 +749,13 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
     )) catch |err| switch (err) {
         error.IsDir, error.AccessDenied => {
             // TODO make event based (and dir.next())
-            var dir = try std.os.Dir.open(fmt.loop.allocator, file_path);
+            var dir = try fs.Dir.open(fmt.loop.allocator, file_path);
             defer dir.close();
 
             var group = event.Group(FmtError!void).init(fmt.loop);
             while (try dir.next()) |entry| {
-                if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
-                    const full_path = try os.path.join(fmt.loop.allocator, [][]const u8{ file_path, entry.name });
+                if (entry.kind == fs.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
+                    const full_path = try fs.path.join(fmt.loop.allocator, [][]const u8{ file_path, entry.name });
                     try group.call(fmtPath, fmt, full_path, check_mode);
                 }
             }
@@ -891,7 +893,7 @@ const usage_internal =
 fn cmdInternal(allocator: *Allocator, args: []const []const u8) !void {
     if (args.len == 0) {
         try stderr.write(usage_internal);
-        os.exit(1);
+        process.exit(1);
     }
 
     const sub_commands = []Command{Command{
src-self-hosted/stage1.zig
@@ -1,8 +1,24 @@
 // This is Zig code that is used by both stage1 and stage2.
 // The prototypes in src/userland.h must match these definitions.
 
-const std = @import("std");
 const builtin = @import("builtin");
+const std = @import("std");
+const io = std.io;
+const mem = std.mem;
+const fs = std.fs;
+const process = std.process;
+const Allocator = mem.Allocator;
+const ArrayList = std.ArrayList;
+const Buffer = std.Buffer;
+const arg = @import("arg.zig");
+const self_hosted_main = @import("main.zig");
+const Args = arg.Args;
+const Flag = arg.Flag;
+const errmsg = @import("errmsg.zig");
+
+var stderr_file: fs.File = undefined;
+var stderr: *io.OutStream(fs.File.WriteError) = undefined;
+var stdout: *io.OutStream(fs.File.WriteError) = undefined;
 
 // ABI warning
 export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
@@ -157,7 +173,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
 
     if (flags.present("help")) {
         try stdout.write(self_hosted_main.usage_fmt);
-        os.exit(0);
+        process.exit(0);
     }
 
     const color = blk: {
@@ -177,7 +193,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
     if (flags.present("stdin")) {
         if (flags.positionals.len != 0) {
             try stderr.write("cannot use --stdin with positional arguments\n");
-            os.exit(1);
+            process.exit(1);
         }
 
         var stdin_file = try io.getStdIn();
@@ -188,7 +204,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
 
         const tree = std.zig.parse(allocator, source_code) catch |err| {
             try stderr.print("error parsing stdin: {}\n", err);
-            os.exit(1);
+            process.exit(1);
         };
         defer tree.deinit();
 
@@ -197,12 +213,12 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
             try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
         }
         if (tree.errors.len != 0) {
-            os.exit(1);
+            process.exit(1);
         }
         if (flags.present("check")) {
             const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
             const code = if (anything_changed) u8(1) else u8(0);
-            os.exit(code);
+            process.exit(code);
         }
 
         _ = try std.zig.render(allocator, stdout, tree);
@@ -211,7 +227,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
 
     if (flags.positionals.len == 0) {
         try stderr.write("expected at least one source file argument\n");
-        os.exit(1);
+        process.exit(1);
     }
 
     var fmt = Fmt{
@@ -227,7 +243,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
         try fmtPath(&fmt, file_path, check_mode);
     }
     if (fmt.any_error) {
-        os.exit(1);
+        process.exit(1);
     }
 }
 
@@ -250,7 +266,7 @@ const FmtError = error{
     ReadOnlyFileSystem,
     LinkQuotaExceeded,
     FileBusy,
-} || os.File.OpenError;
+} || fs.File.OpenError;
 
 fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
     const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref);
@@ -261,12 +277,12 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void
     const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
         error.IsDir, error.AccessDenied => {
             // TODO make event based (and dir.next())
-            var dir = try std.os.Dir.open(fmt.allocator, file_path);
+            var dir = try fs.Dir.open(fmt.allocator, file_path);
             defer dir.close();
 
             while (try dir.next()) |entry| {
-                if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
-                    const full_path = try os.path.join(fmt.allocator, [][]const u8{ file_path, entry.name });
+                if (entry.kind == fs.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
+                    const full_path = try fs.path.join(fmt.allocator, [][]const u8{ file_path, entry.name });
                     try fmtPath(fmt, full_path, check_mode);
                 }
             }
@@ -329,7 +345,7 @@ fn printErrMsgToFile(
     parse_error: *const ast.Error,
     tree: *ast.Tree,
     path: []const u8,
-    file: os.File,
+    file: fs.File,
     color: errmsg.Color,
 ) !void {
     const color_on = switch (color) {
@@ -377,20 +393,3 @@ fn printErrMsgToFile(
     try stream.writeByteNTimes('~', last_token.end - first_token.start);
     try stream.write("\n");
 }
-
-const os = std.os;
-const io = std.io;
-const mem = std.mem;
-const Allocator = mem.Allocator;
-const ArrayList = std.ArrayList;
-const Buffer = std.Buffer;
-
-const arg = @import("arg.zig");
-const self_hosted_main = @import("main.zig");
-const Args = arg.Args;
-const Flag = arg.Flag;
-const errmsg = @import("errmsg.zig");
-
-var stderr_file: os.File = undefined;
-var stderr: *io.OutStream(os.File.WriteError) = undefined;
-var stdout: *io.OutStream(os.File.WriteError) = undefined;
src-self-hosted/test.zig
@@ -55,12 +55,12 @@ pub const TestContext = struct {
         self.zig_lib_dir = try introspect.resolveZigLibDir(allocator);
         errdefer allocator.free(self.zig_lib_dir);
 
-        try std.os.makePath(allocator, tmp_dir_name);
-        errdefer std.os.deleteTree(allocator, tmp_dir_name) catch {};
+        try std.fs.makePath(allocator, tmp_dir_name);
+        errdefer std.fs.deleteTree(allocator, tmp_dir_name) catch {};
     }
 
     fn deinit(self: *TestContext) void {
-        std.os.deleteTree(allocator, tmp_dir_name) catch {};
+        std.fs.deleteTree(allocator, tmp_dir_name) catch {};
         allocator.free(self.zig_lib_dir);
         self.zig_compiler.deinit();
         self.loop.deinit();
@@ -87,10 +87,10 @@ pub const TestContext = struct {
     ) !void {
         var file_index_buf: [20]u8 = undefined;
         const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr());
-        const file1_path = try std.os.path.join(allocator, [][]const u8{ tmp_dir_name, file_index, file1 });
+        const file1_path = try std.fs.path.join(allocator, [][]const u8{ tmp_dir_name, file_index, file1 });
 
-        if (std.os.path.dirname(file1_path)) |dirname| {
-            try std.os.makePath(allocator, dirname);
+        if (std.fs.path.dirname(file1_path)) |dirname| {
+            try std.fs.makePath(allocator, dirname);
         }
 
         // TODO async I/O
@@ -120,11 +120,11 @@ pub const TestContext = struct {
     ) !void {
         var file_index_buf: [20]u8 = undefined;
         const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr());
-        const file1_path = try std.os.path.join(allocator, [][]const u8{ tmp_dir_name, file_index, file1 });
+        const file1_path = try std.fs.path.join(allocator, [][]const u8{ tmp_dir_name, file_index, file1 });
 
         const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, Target(Target.Native).exeFileExt());
-        if (std.os.path.dirname(file1_path)) |dirname| {
-            try std.os.makePath(allocator, dirname);
+        if (std.fs.path.dirname(file1_path)) |dirname| {
+            try std.fs.makePath(allocator, dirname);
         }
 
         // TODO async I/O
@@ -164,9 +164,9 @@ pub const TestContext = struct {
             Compilation.Event.Ok => {
                 const argv = []const []const u8{exe_file_2};
                 // TODO use event loop
-                const child = try std.os.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
+                const child = try std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
                 switch (child.term) {
-                    std.os.ChildProcess.Term.Exited => |code| {
+                    .Exited => |code| {
                         if (code != 0) {
                             return error.BadReturnCode;
                         }
std/event/fs.zig
@@ -879,7 +879,7 @@ pub fn Watch(comptime V: type) type {
         }
 
         async fn addFileKEvent(self: *Self, file_path: []const u8, value: V) !?V {
-            const resolved_path = try os.path.resolve(self.channel.loop.allocator, [][]const u8{file_path});
+            const resolved_path = try std.fs.path.resolve(self.channel.loop.allocator, [][]const u8{file_path});
             var resolved_path_consumed = false;
             defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path);
 
@@ -967,12 +967,12 @@ pub fn Watch(comptime V: type) type {
         async fn addFileLinux(self: *Self, file_path: []const u8, value: V) !?V {
             const value_copy = value;
 
-            const dirname = os.path.dirname(file_path) orelse ".";
+            const dirname = std.fs.path.dirname(file_path) orelse ".";
             const dirname_with_null = try std.cstr.addNullByte(self.channel.loop.allocator, dirname);
             var dirname_with_null_consumed = false;
             defer if (!dirname_with_null_consumed) self.channel.loop.allocator.free(dirname_with_null);
 
-            const basename = os.path.basename(file_path);
+            const basename = std.fs.path.basename(file_path);
             const basename_with_null = try std.cstr.addNullByte(self.channel.loop.allocator, basename);
             var basename_with_null_consumed = false;
             defer if (!basename_with_null_consumed) self.channel.loop.allocator.free(basename_with_null);
@@ -1013,7 +1013,7 @@ pub fn Watch(comptime V: type) type {
             const value_copy = value;
             // TODO we might need to convert dirname and basename to canonical file paths ("short"?)
 
-            const dirname = try std.mem.dupe(self.channel.loop.allocator, u8, os.path.dirname(file_path) orelse ".");
+            const dirname = try std.mem.dupe(self.channel.loop.allocator, u8, std.fs.path.dirname(file_path) orelse ".");
             var dirname_consumed = false;
             defer if (!dirname_consumed) self.channel.loop.allocator.free(dirname);
 
@@ -1021,7 +1021,7 @@ pub fn Watch(comptime V: type) type {
             defer self.channel.loop.allocator.free(dirname_utf16le);
 
             // TODO https://github.com/ziglang/zig/issues/265
-            const basename = os.path.basename(file_path);
+            const basename = std.fs.path.basename(file_path);
             const basename_utf16le_null = try std.unicode.utf8ToUtf16LeWithNull(self.channel.loop.allocator, basename);
             var basename_utf16le_null_consumed = false;
             defer if (!basename_utf16le_null_consumed) self.channel.loop.allocator.free(basename_utf16le_null);
@@ -1334,7 +1334,7 @@ async fn testFsWatchCantFail(loop: *Loop, result: *(anyerror!void)) void {
 }
 
 async fn testFsWatch(loop: *Loop) !void {
-    const file_path = try os.path.join(loop.allocator, [][]const u8{ test_tmp_dir, "file.txt" });
+    const file_path = try std.fs.path.join(loop.allocator, [][]const u8{ test_tmp_dir, "file.txt" });
     defer loop.allocator.free(file_path);
 
     const contents =
std/fs/file.zig
@@ -307,28 +307,4 @@ pub const File = struct {
             return self.file.getPos();
         }
     };
-
-    pub fn stdout() !File {
-        if (windows.is_the_target) {
-            const handle = try windows.GetStdHandle(windows.STD_OUTPUT_HANDLE);
-            return openHandle(handle);
-        }
-        return openHandle(os.STDOUT_FILENO);
-    }
-
-    pub fn stderr() !File {
-        if (windows.is_the_target) {
-            const handle = try windows.GetStdHandle(windows.STD_ERROR_HANDLE);
-            return openHandle(handle);
-        }
-        return openHandle(os.STDERR_FILENO);
-    }
-
-    pub fn stdin() !File {
-        if (windows.is_the_target) {
-            const handle = try windows.GetStdHandle(windows.STD_INPUT_HANDLE);
-            return openHandle(handle);
-        }
-        return openHandle(os.STDIN_FILENO);
-    }
 };
std/fs/get_app_data_dir.zig
@@ -2,6 +2,7 @@ const std = @import("../std.zig");
 const builtin = @import("builtin");
 const unicode = std.unicode;
 const mem = std.mem;
+const fs = std.fs;
 const os = std.os;
 
 pub const GetAppDataDirError = error{
@@ -15,7 +16,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
     switch (builtin.os) {
         .windows => {
             var dir_path_ptr: [*]u16 = undefined;
-            switch (os.windows.SHGetKnownFolderPath(
+            switch (os.windows.shell32.SHGetKnownFolderPath(
                 &os.windows.FOLDERID_LocalAppData,
                 os.windows.KF_FLAG_CREATE,
                 null,
@@ -30,25 +31,25 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
                         error.OutOfMemory => return error.OutOfMemory,
                     };
                     defer allocator.free(global_dir);
-                    return os.path.join(allocator, [][]const u8{ global_dir, appname });
+                    return fs.path.join(allocator, [][]const u8{ global_dir, appname });
                 },
                 os.windows.E_OUTOFMEMORY => return error.OutOfMemory,
                 else => return error.AppDataDirUnavailable,
             }
         },
         .macosx => {
-            const home_dir = os.getEnvPosix("HOME") orelse {
+            const home_dir = os.getenv("HOME") orelse {
                 // TODO look in /etc/passwd
                 return error.AppDataDirUnavailable;
             };
-            return os.path.join(allocator, [][]const u8{ home_dir, "Library", "Application Support", appname });
+            return fs.path.join(allocator, [][]const u8{ home_dir, "Library", "Application Support", appname });
         },
         .linux, .freebsd, .netbsd => {
-            const home_dir = os.getEnvPosix("HOME") orelse {
+            const home_dir = os.getenv("HOME") orelse {
                 // TODO look in /etc/passwd
                 return error.AppDataDirUnavailable;
             };
-            return os.path.join(allocator, [][]const u8{ home_dir, ".local", "share", appname });
+            return fs.path.join(allocator, [][]const u8{ home_dir, ".local", "share", appname });
         },
         else => @compileError("Unsupported OS"),
     }
std/fs/path.zig
@@ -1,16 +1,14 @@
-const std = @import("../std.zig");
 const builtin = @import("builtin");
-const Os = builtin.Os;
+const std = @import("../std.zig");
 const debug = std.debug;
 const assert = debug.assert;
 const testing = std.testing;
 const mem = std.mem;
 const fmt = std.fmt;
 const Allocator = mem.Allocator;
-const os = std.os;
 const math = std.math;
-const windows = os.windows;
-const cstr = std.cstr;
+const windows = std.os.windows;
+const fs = std.fs;
 
 pub const sep_windows = '\\';
 pub const sep_posix = '/';
@@ -392,7 +390,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
 pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
     if (paths.len == 0) {
         assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
-        return os.getCwdAlloc(allocator);
+        return fs.getCwdAlloc(allocator);
     }
 
     // determine which disk designator we will result with, if any
@@ -487,7 +485,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
             },
             WindowsPath.Kind.None => {
                 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
-                const cwd = try os.getCwdAlloc(allocator);
+                const cwd = try fs.getCwdAlloc(allocator);
                 defer allocator.free(cwd);
                 const parsed_cwd = windowsParsePath(cwd);
                 result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1);
@@ -503,7 +501,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
     } else {
         assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
         // TODO call get cwd for the result_disk_designator instead of the global one
-        const cwd = try os.getCwdAlloc(allocator);
+        const cwd = try fs.getCwdAlloc(allocator);
         defer allocator.free(cwd);
 
         result = try allocator.alloc(u8, max_size + cwd.len + 1);
@@ -573,7 +571,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
 pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
     if (paths.len == 0) {
         assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
-        return os.getCwdAlloc(allocator);
+        return fs.getCwdAlloc(allocator);
     }
 
     var first_index: usize = 0;
@@ -595,7 +593,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
         result = try allocator.alloc(u8, max_size);
     } else {
         assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
-        const cwd = try os.getCwdAlloc(allocator);
+        const cwd = try fs.getCwdAlloc(allocator);
         defer allocator.free(cwd);
         result = try allocator.alloc(u8, max_size + cwd.len + 1);
         mem.copy(u8, result, cwd);
@@ -634,7 +632,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
 }
 
 test "resolve" {
-    const cwd = try os.getCwdAlloc(debug.global_allocator);
+    const cwd = try fs.getCwdAlloc(debug.global_allocator);
     if (windows.is_the_target) {
         if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
             cwd[0] = asciiUpper(cwd[0]);
@@ -648,7 +646,7 @@ test "resolve" {
 
 test "resolveWindows" {
     if (windows.is_the_target) {
-        const cwd = try os.getCwdAlloc(debug.global_allocator);
+        const cwd = try fs.getCwdAlloc(debug.global_allocator);
         const parsed_cwd = windowsParsePath(cwd);
         {
             const result = testResolveWindows([][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });
std/os/bits/linux.zig
@@ -692,12 +692,12 @@ pub const winsize = extern struct {
     ws_ypixel: u16,
 };
 
-const NSIG = 65;
-const sigset_t = [128 / @sizeOf(usize)]usize;
-const all_mask = []u32{ 0xffffffff, 0xffffffff };
-const app_mask = []u32{ 0xfffffffc, 0x7fffffff };
+pub const NSIG = 65;
+pub const sigset_t = [128 / @sizeOf(usize)]usize;
+pub const all_mask = []u32{ 0xffffffff, 0xffffffff };
+pub const app_mask = []u32{ 0xfffffffc, 0x7fffffff };
 
-const k_sigaction = extern struct {
+pub const k_sigaction = extern struct {
     handler: extern fn (i32) void,
     flags: usize,
     restorer: extern fn () void,
std/os/bits/wasi.zig
@@ -13,10 +13,7 @@ pub const ADVICE_WILLNEED: advice_t = 3;
 pub const ADVICE_DONTNEED: advice_t = 4;
 pub const ADVICE_NOREUSE: advice_t = 5;
 
-pub const ciovec_t = extern struct {
-    buf: [*]const u8,
-    buf_len: usize,
-};
+pub const ciovec_t = iovec_const;
 
 pub const clockid_t = u32;
 pub const CLOCK_REALTIME: clockid_t = 0;
@@ -186,10 +183,7 @@ pub const FILESTAT_SET_MTIM_NOW: fstflags_t = 0x0008;
 
 pub const inode_t = u64;
 
-pub const iovec_t = extern struct {
-    buf: [*]u8,
-    buf_len: usize,
-};
+pub const iovec_t = iovec;
 
 pub const linkcount_t = u32;
 
std/os/linux/vdso.zig
@@ -1,7 +1,6 @@
 const std = @import("../../std.zig");
 const elf = std.elf;
 const linux = std.os.linux;
-const cstr = std.cstr;
 const mem = std.mem;
 const maxInt = std.math.maxInt;
 
@@ -66,7 +65,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
         if (0 == (u32(1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue;
         if (0 == (u32(1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue;
         if (0 == syms[i].st_shndx) continue;
-        if (!mem.eql(u8, name, cstr.toSliceConst(strings + syms[i].st_name))) continue;
+        if (!mem.eql(u8, name, mem.toSliceConst(u8, strings + syms[i].st_name))) continue;
         if (maybe_versym) |versym| {
             if (!checkver(maybe_verdef.?, versym[i], vername, strings))
                 continue;
@@ -88,5 +87,5 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
         def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next);
     }
     const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
-    return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name));
+    return mem.eql(u8, vername, mem.toSliceConst(u8, strings + aux.vda_name));
 }
std/os/linux.zig
@@ -20,6 +20,7 @@ pub use switch (builtin.arch) {
     else => struct {},
 };
 pub use @import("bits.zig");
+pub const tls = @import("linux/tls.zig");
 
 /// Set by startup code, used by `getauxval`.
 pub var elf_aux_maybe: ?[*]std.elf.Auxv = null;
@@ -539,15 +540,15 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
     return 0;
 }
 
-fn blockAllSignals(set: *sigset_t) void {
+pub fn blockAllSignals(set: *sigset_t) void {
     _ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG / 8);
 }
 
-fn blockAppSignals(set: *sigset_t) void {
+pub fn blockAppSignals(set: *sigset_t) void {
     _ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG / 8);
 }
 
-fn restoreSignals(set: *sigset_t) void {
+pub fn restoreSignals(set: *sigset_t) void {
     _ = syscall4(SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG / 8);
 }
 
std/os/test.zig
@@ -3,6 +3,7 @@ const os = std.os;
 const testing = std.testing;
 const expect = std.testing.expect;
 const io = std.io;
+const fs = std.fs;
 const mem = std.mem;
 const File = std.fs.File;
 const Thread = std.Thread;
@@ -14,9 +15,9 @@ const AtomicRmwOp = builtin.AtomicRmwOp;
 const AtomicOrder = builtin.AtomicOrder;
 
 test "makePath, put some files in it, deleteTree" {
-    try os.makePath(a, "os_test_tmp" ++ os.path.sep_str ++ "b" ++ os.path.sep_str ++ "c");
-    try io.writeFile("os_test_tmp" ++ os.path.sep_str ++ "b" ++ os.path.sep_str ++ "c" ++ os.path.sep_str ++ "file.txt", "nonsense");
-    try io.writeFile("os_test_tmp" ++ os.path.sep_str ++ "b" ++ os.path.sep_str ++ "file2.txt", "blah");
+    try os.makePath(a, "os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");
+    try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense");
+    try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah");
     try os.deleteTree(a, "os_test_tmp");
     if (os.Dir.open(a, "os_test_tmp")) |dir| {
         @panic("expected error");
@@ -27,14 +28,14 @@ test "makePath, put some files in it, deleteTree" {
 
 test "access file" {
     try os.makePath(a, "os_test_tmp");
-    if (File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt")) |ok| {
+    if (File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt")) |ok| {
         @panic("expected error");
     } else |err| {
         expect(err == error.FileNotFound);
     }
 
-    try io.writeFile("os_test_tmp" ++ os.path.sep_str ++ "file.txt", "");
-    try File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt");
+    try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", "");
+    try File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt");
     try os.deleteTree(a, "os_test_tmp");
 }
 
std/os/windows.zig
@@ -4,6 +4,7 @@
 // * When null-terminated or UTF16LE byte buffers are required, provide APIs which accept
 //   slices as well as APIs which accept null-terminated UTF16LE byte buffers.
 
+const builtin = @import("builtin");
 const std = @import("../std.zig");
 const assert = std.debug.assert;
 const maxInt = std.math.maxInt;
@@ -1103,6 +1104,42 @@ pub fn VirtualFree(lpAddress: ?LPVOID, dwSize: usize, dwFreeType: DWORD) void {
     assert(kernel32.VirtualFree(lpAddress, dwSize, dwFreeType) != 0);
 }
 
+pub const SetConsoleTextAttributeError = error{Unexpected};
+
+pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetConsoleTextAttributeError!void {
+    if (kernel32.SetConsoleTextAttribute(hConsoleOutput, wAttributes) == 0) {
+        switch (kernel32.GetLastError()) {
+            else => |err| return unexpectedError(err),
+        }
+    }
+}
+
+pub const GetEnvironmentStringsError = error{OutOfMemory};
+
+pub fn GetEnvironmentStringsW() GetEnvironmentStringsError![*]u16 {
+    return kernel32.GetEnvironmentStringsW() orelse return error.OutOfMemory;
+}
+
+pub fn FreeEnvironmentStringsW(penv: [*]u16) void {
+    assert(kernel32.FreeEnvironmentStringsW(penv) != 0);
+}
+
+pub const GetEnvironmentVariableError = error{
+    EnvironmentVariableNotFound,
+    Unexpected,
+};
+
+pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) GetEnvironmentVariableError!DWORD {
+    const rc = kernel32.GetEnvironmentVariableW(lpName, lpBuffer, nSize);
+    if (rc == 0) {
+        switch (kernel32.GetLastError()) {
+            ERROR.ENVVAR_NOT_FOUND => return error.EnvironmentVariableNotFound,
+            else => |err| return unexpectedError(err),
+        }
+    }
+    return rc;
+}
+
 pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {
     return sliceToPrefixedFileW(mem.toSliceConst(u8, s));
 }
@@ -1127,7 +1164,7 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
             else => {},
         }
     }
-    const start_index = if (mem.startsWith(u8, s, "\\\\") or !os.path.isAbsolute(s)) 0 else blk: {
+    const start_index = if (mem.startsWith(u8, s, "\\\\") or !std.fs.path.isAbsolute(s)) 0 else blk: {
         const prefix = []u16{ '\\', '\\', '?', '\\' };
         mem.copy(u16, result[0..], prefix);
         break :blk prefix.len;
std/special/bootstrap.zig
@@ -78,7 +78,7 @@ fn posixCallMainAndExit() noreturn {
     while (envp_optional[envp_count]) |_| : (envp_count += 1) {}
     const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];
 
-    if (builtin.os == builtin.Os.linux) {
+    if (builtin.os == .linux) {
         // Find the beginning of the auxiliary vector
         const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1);
         std.os.linux.elf_aux_maybe = auxv;
@@ -98,7 +98,7 @@ fn posixCallMainAndExit() noreturn {
 // This is marked inline because for some reason LLVM in release mode fails to inline it,
 // and we want fewer call frames in stack traces.
 inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {
-    std.os.ArgIteratorPosix.raw = argv[0..argc];
+    std.os.argv = argv[0..argc];
     std.os.environ = envp;
     return callMain();
 }
std/special/build_runner.zig
@@ -3,15 +3,15 @@ const std = @import("std");
 const builtin = @import("builtin");
 const io = std.io;
 const fmt = std.fmt;
-const os = std.os;
 const Builder = std.build.Builder;
 const mem = std.mem;
+const process = std.process;
 const ArrayList = std.ArrayList;
 const warn = std.debug.warn;
 const File = std.fs.File;
 
 pub fn main() !void {
-    var arg_it = os.args();
+    var arg_it = process.args();
 
     // Here we use an ArenaAllocator backed by a DirectAllocator because a build is a short-lived,
     // one shot program. We don't need to waste time freeing memory and finding places to squish
@@ -139,7 +139,7 @@ pub fn main() !void {
             error.InvalidStepName => {
                 return usageAndErr(&builder, true, try stderr_stream);
             },
-            error.UncleanExit => os.exit(1),
+            error.UncleanExit => process.exit(1),
             else => return err,
         }
     };
@@ -215,7 +215,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
 
 fn usageAndErr(builder: *Builder, already_ran_build: bool, out_stream: var) void {
     usage(builder, already_ran_build, out_stream) catch {};
-    os.exit(1);
+    process.exit(1);
 }
 
 const UnwrapArgError = error{OutOfMemory};
std/buffer.zig
@@ -139,15 +139,13 @@ pub const Buffer = struct {
 };
 
 test "simple Buffer" {
-    const cstr = @import("cstr.zig");
-
     var buf = try Buffer.init(debug.global_allocator, "");
     testing.expect(buf.len() == 0);
     try buf.append("hello");
     try buf.append(" ");
     try buf.append("world");
     testing.expect(buf.eql("hello world"));
-    testing.expect(mem.eql(u8, cstr.toSliceConst(buf.toSliceConst().ptr), buf.toSliceConst()));
+    testing.expect(mem.eql(u8, mem.toSliceConst(u8, buf.toSliceConst().ptr), buf.toSliceConst()));
 
     var buf2 = try Buffer.initFromBuffer(buf);
     testing.expect(buf.eql(buf2.toSliceConst()));
std/build.zig
@@ -1,6 +1,7 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
 const io = std.io;
+const fs = std.fs;
 const mem = std.mem;
 const debug = std.debug;
 const assert = debug.assert;
@@ -8,9 +9,7 @@ const warn = std.debug.warn;
 const ArrayList = std.ArrayList;
 const HashMap = std.HashMap;
 const Allocator = mem.Allocator;
-const os = std.os;
-const StdIo = os.ChildProcess.StdIo;
-const Term = os.ChildProcess.Term;
+const process = std.process;
 const BufSet = std.BufSet;
 const BufMap = std.BufMap;
 const fmt_lib = std.fmt;
@@ -96,11 +95,11 @@ pub const Builder = struct {
 
     pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
         const env_map = allocator.create(BufMap) catch unreachable;
-        env_map.* = os.getEnvMap(allocator) catch unreachable;
+        env_map.* = process.getEnvMap(allocator) catch unreachable;
         var self = Builder{
             .zig_exe = zig_exe,
             .build_root = build_root,
-            .cache_root = os.path.relative(allocator, build_root, cache_root) catch unreachable,
+            .cache_root = fs.path.relative(allocator, build_root, cache_root) catch unreachable,
             .verbose = false,
             .verbose_tokenize = false,
             .verbose_ast = false,
@@ -154,8 +153,8 @@ pub const Builder = struct {
 
     pub fn setInstallPrefix(self: *Builder, maybe_prefix: ?[]const u8) void {
         self.prefix = maybe_prefix orelse "/usr/local"; // TODO better default
-        self.lib_dir = os.path.join(self.allocator, [][]const u8{ self.prefix, "lib" }) catch unreachable;
-        self.exe_dir = os.path.join(self.allocator, [][]const u8{ self.prefix, "bin" }) catch unreachable;
+        self.lib_dir = fs.path.join(self.allocator, [][]const u8{ self.prefix, "lib" }) catch unreachable;
+        self.exe_dir = fs.path.join(self.allocator, [][]const u8{ self.prefix, "bin" }) catch unreachable;
     }
 
     pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
@@ -287,7 +286,7 @@ pub const Builder = struct {
             if (self.verbose) {
                 warn("rm {}\n", installed_file);
             }
-            os.deleteFile(installed_file) catch {};
+            fs.deleteFile(installed_file) catch {};
         }
 
         // TODO remove empty directories
@@ -326,7 +325,7 @@ pub const Builder = struct {
 
     fn detectNativeSystemPaths(self: *Builder) void {
         var is_nixos = false;
-        if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
+        if (process.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
             is_nixos = true;
             var it = mem.tokenize(nix_cflags_compile, " ");
             while (true) {
@@ -345,7 +344,7 @@ pub const Builder = struct {
         } else |err| {
             assert(err == error.EnvironmentVariableNotFound);
         }
-        if (os.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
+        if (process.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
             is_nixos = true;
             var it = mem.tokenize(nix_ldflags, " ");
             while (true) {
@@ -369,7 +368,7 @@ pub const Builder = struct {
         }
         if (is_nixos) return;
         switch (builtin.os) {
-            builtin.Os.windows => {},
+            .windows => {},
             else => {
                 const triple = (CrossTarget{
                     .arch = builtin.arch,
@@ -602,7 +601,7 @@ pub const Builder = struct {
             printCmd(cwd, argv);
         }
 
-        const child = os.ChildProcess.init(argv, self.allocator) catch unreachable;
+        const child = std.ChildProcess.init(argv, self.allocator) catch unreachable;
         defer child.deinit();
 
         child.cwd = cwd;
@@ -614,7 +613,7 @@ pub const Builder = struct {
         };
 
         switch (term) {
-            Term.Exited => |code| {
+            .Exited => |code| {
                 if (code != 0) {
                     warn("The following command exited with error code {}:\n", code);
                     printCmd(cwd, argv);
@@ -631,7 +630,7 @@ pub const Builder = struct {
     }
 
     pub fn makePath(self: *Builder, path: []const u8) !void {
-        os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
+        fs.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
             warn("Unable to create path {}: {}\n", path, @errorName(err));
             return err;
         };
@@ -652,7 +651,7 @@ pub const Builder = struct {
 
     ///::dest_rel_path is relative to prefix path or it can be an absolute path
     pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
-        const full_dest_path = os.path.resolve(
+        const full_dest_path = fs.path.resolve(
             self.allocator,
             [][]const u8{ self.prefix, dest_rel_path },
         ) catch unreachable;
@@ -677,20 +676,20 @@ pub const Builder = struct {
             warn("cp {} {}\n", source_path, dest_path);
         }
 
-        const dirname = os.path.dirname(dest_path) orelse ".";
+        const dirname = fs.path.dirname(dest_path) orelse ".";
         const abs_source_path = self.pathFromRoot(source_path);
-        os.makePath(self.allocator, dirname) catch |err| {
+        fs.makePath(self.allocator, dirname) catch |err| {
             warn("Unable to create path {}: {}\n", dirname, @errorName(err));
             return err;
         };
-        os.copyFileMode(abs_source_path, dest_path, mode) catch |err| {
+        fs.copyFileMode(abs_source_path, dest_path, mode) catch |err| {
             warn("Unable to copy {} to {}: {}\n", abs_source_path, dest_path, @errorName(err));
             return err;
         };
     }
 
     fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
-        return os.path.resolve(self.allocator, [][]const u8{ self.build_root, rel_path }) catch unreachable;
+        return fs.path.resolve(self.allocator, [][]const u8{ self.build_root, rel_path }) catch unreachable;
     }
 
     pub fn fmt(self: *Builder, comptime format: []const u8, args: ...) []u8 {
@@ -702,11 +701,11 @@ pub const Builder = struct {
         const exe_extension = (Target{ .Native = {} }).exeFileExt();
         for (self.search_prefixes.toSliceConst()) |search_prefix| {
             for (names) |name| {
-                if (os.path.isAbsolute(name)) {
+                if (fs.path.isAbsolute(name)) {
                     return name;
                 }
-                const full_path = try os.path.join(self.allocator, [][]const u8{ search_prefix, "bin", self.fmt("{}{}", name, exe_extension) });
-                if (os.path.real(self.allocator, full_path)) |real_path| {
+                const full_path = try fs.path.join(self.allocator, [][]const u8{ search_prefix, "bin", self.fmt("{}{}", name, exe_extension) });
+                if (fs.path.real(self.allocator, full_path)) |real_path| {
                     return real_path;
                 } else |_| {
                     continue;
@@ -715,13 +714,13 @@ pub const Builder = struct {
         }
         if (self.env_map.get("PATH")) |PATH| {
             for (names) |name| {
-                if (os.path.isAbsolute(name)) {
+                if (fs.path.isAbsolute(name)) {
                     return name;
                 }
-                var it = mem.tokenize(PATH, []u8{os.path.delimiter});
+                var it = mem.tokenize(PATH, []u8{fs.path.delimiter});
                 while (it.next()) |path| {
-                    const full_path = try os.path.join(self.allocator, [][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
-                    if (os.path.real(self.allocator, full_path)) |real_path| {
+                    const full_path = try fs.path.join(self.allocator, [][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
+                    if (fs.path.real(self.allocator, full_path)) |real_path| {
                         return real_path;
                     } else |_| {
                         continue;
@@ -730,12 +729,12 @@ pub const Builder = struct {
             }
         }
         for (names) |name| {
-            if (os.path.isAbsolute(name)) {
+            if (fs.path.isAbsolute(name)) {
                 return name;
             }
             for (paths) |path| {
-                const full_path = try os.path.join(self.allocator, [][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
-                if (os.path.real(self.allocator, full_path)) |real_path| {
+                const full_path = try fs.path.join(self.allocator, [][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
+                if (fs.path.real(self.allocator, full_path)) |real_path| {
                     return real_path;
                 } else |_| {
                     continue;
@@ -749,12 +748,12 @@ pub const Builder = struct {
         assert(argv.len != 0);
 
         const max_output_size = 100 * 1024;
-        const child = try os.ChildProcess.init(argv, self.allocator);
+        const child = try std.ChildProcess.init(argv, self.allocator);
         defer child.deinit();
 
-        child.stdin_behavior = os.ChildProcess.StdIo.Ignore;
-        child.stdout_behavior = os.ChildProcess.StdIo.Pipe;
-        child.stderr_behavior = os.ChildProcess.StdIo.Inherit;
+        child.stdin_behavior = .Ignore;
+        child.stdout_behavior = .Pipe;
+        child.stderr_behavior = .Inherit;
 
         try child.spawn();
 
@@ -766,7 +765,7 @@ pub const Builder = struct {
 
         const term = child.wait() catch |err| std.debug.panic("unable to spawn {}: {}", argv[0], err);
         switch (term) {
-            os.ChildProcess.Term.Exited => |code| {
+            .Exited => |code| {
                 if (code != 0) {
                     warn("The following command exited with error code {}:\n", code);
                     printCmd(null, argv);
@@ -846,7 +845,7 @@ pub const Target = union(enum) {
         }
     }
 
-    pub fn oFileExt(self: *const Target) []const u8 {
+    pub fn oFileExt(self: Target) []const u8 {
         const abi = switch (self.*) {
             Target.Native => builtin.abi,
             Target.Cross => |t| t.abi,
@@ -857,49 +856,49 @@ pub const Target = union(enum) {
         };
     }
 
-    pub fn exeFileExt(self: *const Target) []const u8 {
+    pub fn exeFileExt(self: Target) []const u8 {
         return switch (self.getOs()) {
-            builtin.Os.windows => ".exe",
+            .windows => ".exe",
             else => "",
         };
     }
 
-    pub fn libFileExt(self: *const Target) []const u8 {
+    pub fn libFileExt(self: Target) []const u8 {
         return switch (self.getOs()) {
-            builtin.Os.windows => ".lib",
+            .windows => ".lib",
             else => ".a",
         };
     }
 
-    pub fn getOs(self: *const Target) builtin.Os {
-        return switch (self.*) {
+    pub fn getOs(self: Target) builtin.Os {
+        return switch (self) {
             Target.Native => builtin.os,
             Target.Cross => |t| t.os,
         };
     }
 
-    pub fn isDarwin(self: *const Target) bool {
+    pub fn isDarwin(self: Target) bool {
         return switch (self.getOs()) {
-            builtin.Os.ios, builtin.Os.macosx => true,
+            .ios, .macosx, .watchos, .tvos => true,
             else => false,
         };
     }
 
-    pub fn isWindows(self: *const Target) bool {
+    pub fn isWindows(self: Target) bool {
         return switch (self.getOs()) {
-            builtin.Os.windows => true,
+            .windows => true,
             else => false,
         };
     }
 
-    pub fn isFreeBSD(self: *const Target) bool {
+    pub fn isFreeBSD(self: Target) bool {
         return switch (self.getOs()) {
-            builtin.Os.freebsd => true,
+            .freebsd => true,
             else => false,
         };
     }
 
-    pub fn wantSharedLibSymLinks(self: *const Target) bool {
+    pub fn wantSharedLibSymLinks(self: Target) bool {
         return !self.isWindows();
     }
 };
@@ -1065,19 +1064,19 @@ pub const LibExeObjStep = struct {
 
     fn computeOutFileNames(self: *LibExeObjStep) void {
         switch (self.kind) {
-            Kind.Obj => {
+            .Obj => {
                 self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt());
             },
-            Kind.Exe => {
+            .Exe => {
                 self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt());
             },
-            Kind.Test => {
+            .Test => {
                 self.out_filename = self.builder.fmt("test{}", self.target.exeFileExt());
             },
-            Kind.Lib => {
+            .Lib => {
                 if (!self.is_dynamic) {
                     switch (self.target.getOs()) {
-                        builtin.Os.windows => {
+                        .windows => {
                             self.out_filename = self.builder.fmt("{}.lib", self.name);
                         },
                         else => {
@@ -1087,13 +1086,13 @@ pub const LibExeObjStep = struct {
                     self.out_lib_filename = self.out_filename;
                 } else {
                     switch (self.target.getOs()) {
-                        builtin.Os.ios, builtin.Os.macosx => {
+                        .ios, .macosx => {
                             self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
                             self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
                             self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
                             self.out_lib_filename = self.out_filename;
                         },
-                        builtin.Os.windows => {
+                        .windows => {
                             self.out_filename = self.builder.fmt("{}.dll", self.name);
                             self.out_lib_filename = self.builder.fmt("{}.lib", self.name);
                         },
@@ -1228,7 +1227,7 @@ pub const LibExeObjStep = struct {
     /// the make step, from a step that has declared a dependency on this one.
     /// To run an executable built with zig build, use `run`, or create an install step and invoke it.
     pub fn getOutputPath(self: *LibExeObjStep) []const u8 {
-        return os.path.join(
+        return fs.path.join(
             self.builder.allocator,
             [][]const u8{ self.output_dir.?, self.out_filename },
         ) catch unreachable;
@@ -1238,7 +1237,7 @@ pub const LibExeObjStep = struct {
     /// the make step, from a step that has declared a dependency on this one.
     pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 {
         assert(self.kind == Kind.Lib);
-        return os.path.join(
+        return fs.path.join(
             self.builder.allocator,
             [][]const u8{ self.output_dir.?, self.out_lib_filename },
         ) catch unreachable;
@@ -1249,7 +1248,7 @@ pub const LibExeObjStep = struct {
     pub fn getOutputHPath(self: *LibExeObjStep) []const u8 {
         assert(self.kind != Kind.Exe);
         assert(!self.disable_gen_h);
-        return os.path.join(
+        return fs.path.join(
             self.builder.allocator,
             [][]const u8{ self.output_dir.?, self.out_h_filename },
         ) catch unreachable;
@@ -1365,7 +1364,7 @@ pub const LibExeObjStep = struct {
                             try zig_args.append("--library");
                             try zig_args.append(full_path_lib);
 
-                            if (os.path.dirname(full_path_lib)) |dirname| {
+                            if (fs.path.dirname(full_path_lib)) |dirname| {
                                 try zig_args.append("-rpath");
                                 try zig_args.append(dirname);
                             }
@@ -1391,7 +1390,7 @@ pub const LibExeObjStep = struct {
         }
 
         if (self.build_options_contents.len() > 0) {
-            const build_options_file = try os.path.join(
+            const build_options_file = try fs.path.join(
                 builder.allocator,
                 [][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", self.name) },
             );
@@ -1503,7 +1502,7 @@ pub const LibExeObjStep = struct {
                 IncludeDir.OtherStep => |other| {
                     const h_path = other.getOutputHPath();
                     try zig_args.append("-isystem");
-                    try zig_args.append(os.path.dirname(h_path).?);
+                    try zig_args.append(fs.path.dirname(h_path).?);
                 },
             }
         }
@@ -1576,7 +1575,7 @@ pub const LibExeObjStep = struct {
 
             const output_path_nl = try builder.exec(zig_args.toSliceConst());
             const output_path = mem.trimRight(u8, output_path_nl, "\r\n");
-            self.output_dir = os.path.dirname(output_path).?;
+            self.output_dir = fs.path.dirname(output_path).?;
         }
 
         if (self.kind == Kind.Lib and self.is_dynamic and self.target.wantSharedLibSymLinks()) {
@@ -1637,20 +1636,20 @@ pub const RunStep = struct {
     }
 
     pub fn addPathDir(self: *RunStep, search_path: []const u8) void {
-        const PATH = if (builtin.os == builtin.Os.windows) "Path" else "PATH";
+        const PATH = if (std.os.windows.is_the_target) "Path" else "PATH";
         const env_map = self.getEnvMap();
         const prev_path = env_map.get(PATH) orelse {
             env_map.set(PATH, search_path) catch unreachable;
             return;
         };
-        const new_path = self.builder.fmt("{}" ++ [1]u8{os.path.delimiter} ++ "{}", prev_path, search_path);
+        const new_path = self.builder.fmt("{}" ++ [1]u8{fs.path.delimiter} ++ "{}", prev_path, search_path);
         env_map.set(PATH, new_path) catch unreachable;
     }
 
     pub fn getEnvMap(self: *RunStep) *BufMap {
         return self.env_map orelse {
             const env_map = self.builder.allocator.create(BufMap) catch unreachable;
-            env_map.* = os.getEnvMap(self.builder.allocator) catch unreachable;
+            env_map.* = process.getEnvMap(self.builder.allocator) catch unreachable;
             self.env_map = env_map;
             return env_map;
         };
@@ -1688,7 +1687,7 @@ pub const RunStep = struct {
             switch (link_object) {
                 LibExeObjStep.LinkObject.OtherStep => |other| {
                     if (other.target.isWindows() and other.isDynamicLibrary()) {
-                        self.addPathDir(os.path.dirname(other.getOutputPath()).?);
+                        self.addPathDir(fs.path.dirname(other.getOutputPath()).?);
                         self.addPathForDynLibs(other);
                     }
                 },
@@ -1718,7 +1717,7 @@ const InstallArtifactStep = struct {
             .builder = builder,
             .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
             .artifact = artifact,
-            .dest_file = os.path.join(
+            .dest_file = fs.path.join(
                 builder.allocator,
                 [][]const u8{ dest_dir, artifact.out_filename },
             ) catch unreachable,
@@ -1726,11 +1725,11 @@ const InstallArtifactStep = struct {
         self.step.dependOn(&artifact.step);
         builder.pushInstalledFile(self.dest_file);
         if (self.artifact.kind == LibExeObjStep.Kind.Lib and self.artifact.is_dynamic) {
-            builder.pushInstalledFile(os.path.join(
+            builder.pushInstalledFile(fs.path.join(
                 builder.allocator,
                 [][]const u8{ builder.lib_dir, artifact.major_only_filename },
             ) catch unreachable);
-            builder.pushInstalledFile(os.path.join(
+            builder.pushInstalledFile(fs.path.join(
                 builder.allocator,
                 [][]const u8{ builder.lib_dir, artifact.name_only_filename },
             ) catch unreachable);
@@ -1743,12 +1742,12 @@ const InstallArtifactStep = struct {
         const builder = self.builder;
 
         const mode = switch (builtin.os) {
-            builtin.Os.windows => {},
+            .windows => {},
             else => switch (self.artifact.kind) {
-                LibExeObjStep.Kind.Obj => unreachable,
-                LibExeObjStep.Kind.Test => unreachable,
-                LibExeObjStep.Kind.Exe => u32(0o755),
-                LibExeObjStep.Kind.Lib => if (!self.artifact.is_dynamic) u32(0o666) else u32(0o755),
+                .Obj => unreachable,
+                .Test => unreachable,
+                .Exe => u32(0o755),
+                .Lib => if (!self.artifact.is_dynamic) u32(0o666) else u32(0o755),
             },
         };
         try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode);
@@ -1797,8 +1796,8 @@ pub const WriteFileStep = struct {
     fn make(step: *Step) !void {
         const self = @fieldParentPtr(WriteFileStep, "step", step);
         const full_path = self.builder.pathFromRoot(self.file_path);
-        const full_path_dir = os.path.dirname(full_path) orelse ".";
-        os.makePath(self.builder.allocator, full_path_dir) catch |err| {
+        const full_path_dir = fs.path.dirname(full_path) orelse ".";
+        fs.makePath(self.builder.allocator, full_path_dir) catch |err| {
             warn("unable to make path {}: {}\n", full_path_dir, @errorName(err));
             return err;
         };
@@ -1845,7 +1844,7 @@ pub const RemoveDirStep = struct {
         const self = @fieldParentPtr(RemoveDirStep, "step", step);
 
         const full_path = self.builder.pathFromRoot(self.dir_path);
-        os.deleteTree(self.builder.allocator, full_path) catch |err| {
+        fs.deleteTree(self.builder.allocator, full_path) catch |err| {
             warn("Unable to remove {}: {}\n", full_path, @errorName(err));
             return err;
         };
@@ -1887,23 +1886,23 @@ pub const Step = struct {
 };
 
 fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void {
-    const out_dir = os.path.dirname(output_path) orelse ".";
-    const out_basename = os.path.basename(output_path);
+    const out_dir = fs.path.dirname(output_path) orelse ".";
+    const out_basename = fs.path.basename(output_path);
     // sym link for libfoo.so.1 to libfoo.so.1.2.3
-    const major_only_path = os.path.join(
+    const major_only_path = fs.path.join(
         allocator,
         [][]const u8{ out_dir, filename_major_only },
     ) catch unreachable;
-    os.atomicSymLink(allocator, out_basename, major_only_path) catch |err| {
+    fs.atomicSymLink(allocator, out_basename, major_only_path) catch |err| {
         warn("Unable to symlink {} -> {}\n", major_only_path, out_basename);
         return err;
     };
     // sym link for libfoo.so to libfoo.so.1
-    const name_only_path = os.path.join(
+    const name_only_path = fs.path.join(
         allocator,
         [][]const u8{ out_dir, filename_name_only },
     ) catch unreachable;
-    os.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| {
+    fs.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| {
         warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only);
         return err;
     };
std/child_process.zig
@@ -2,7 +2,9 @@ const std = @import("std.zig");
 const cstr = std.cstr;
 const unicode = std.unicode;
 const io = std.io;
+const fs = std.fs;
 const os = std.os;
+const process = std.process;
 const File = std.fs.File;
 const windows = os.windows;
 const mem = std.mem;
@@ -14,12 +16,10 @@ const Os = builtin.Os;
 const LinkedList = std.LinkedList;
 const maxInt = std.math.maxInt;
 
-const is_windows = builtin.os == .windows;
-
 pub const ChildProcess = struct {
-    pub pid: if (is_windows) void else i32,
-    pub handle: if (is_windows) windows.HANDLE else void,
-    pub thread_handle: if (is_windows) windows.HANDLE else void,
+    pub pid: if (os.windows.is_the_target) void else i32,
+    pub handle: if (os.windows.is_the_target) windows.HANDLE else void,
+    pub thread_handle: if (os.windows.is_the_target) windows.HANDLE else void,
 
     pub allocator: *mem.Allocator,
 
@@ -39,16 +39,16 @@ pub const ChildProcess = struct {
     pub stderr_behavior: StdIo,
 
     /// Set to change the user id when spawning the child process.
-    pub uid: if (is_windows) void else ?u32,
+    pub uid: if (os.windows.is_the_target) void else ?u32,
 
     /// Set to change the group id when spawning the child process.
-    pub gid: if (is_windows) void else ?u32,
+    pub gid: if (os.windows.is_the_target) void else ?u32,
 
     /// Set to change the current working directory when spawning the child process.
     pub cwd: ?[]const u8,
 
-    err_pipe: if (is_windows) void else [2]i32,
-    llnode: if (is_windows) void else LinkedList(*ChildProcess).Node,
+    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,
@@ -98,10 +98,8 @@ pub const ChildProcess = struct {
             .term = null,
             .env_map = null,
             .cwd = null,
-            .uid = if (is_windows) {} else
-                null,
-            .gid = if (is_windows) {} else
-                null,
+            .uid = if (os.windows.is_the_target) {} else null,
+            .gid = if (os.windows.is_the_target) {} else null,
             .stdin = null,
             .stdout = null,
             .stderr = null,
@@ -121,7 +119,7 @@ pub const ChildProcess = struct {
 
     /// On success must call `kill` or `wait`.
     pub fn spawn(self: *ChildProcess) !void {
-        if (is_windows) {
+        if (os.windows.is_the_target) {
             return self.spawnWindows();
         } else {
             return self.spawnPosix();
@@ -135,7 +133,7 @@ pub const ChildProcess = struct {
 
     /// Forcibly terminates child process and then cleans up all resources.
     pub fn kill(self: *ChildProcess) !Term {
-        if (is_windows) {
+        if (os.windows.is_the_target) {
             return self.killWindows(1);
         } else {
             return self.killPosix();
@@ -165,7 +163,7 @@ pub const ChildProcess = struct {
 
     /// Blocks until child process terminates and then cleans up all resources.
     pub fn wait(self: *ChildProcess) !Term {
-        if (is_windows) {
+        if (os.windows.is_the_target) {
             return self.waitWindows();
         } else {
             return self.waitPosix();
@@ -339,7 +337,7 @@ pub const ChildProcess = struct {
             break :x env_map;
         } else x: {
             we_own_env_map = true;
-            env_map_owned = try os.getEnvMap(self.allocator);
+            env_map_owned = try process.getEnvMap(self.allocator);
             break :x &env_map_owned;
         };
         defer {
@@ -372,15 +370,15 @@ pub const ChildProcess = struct {
             }
 
             if (self.cwd) |cwd| {
-                os.changeCurDir(cwd) catch |err| forkChildErrReport(err_pipe[1], err);
+                os.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err);
             }
 
             if (self.gid) |gid| {
-                os.posix_setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
+                os.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
             }
 
             if (self.uid) |uid| {
-                os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
+                os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
             }
 
             os.execve(self.allocator, self.argv, env_map) catch |err| forkChildErrReport(err_pipe[1], err);
@@ -541,7 +539,7 @@ pub const ChildProcess = struct {
         // to match posix semantics
         const app_name = x: {
             if (self.cwd) |cwd| {
-                const resolved = try os.path.resolve(self.allocator, [][]const u8{ cwd, self.argv[0] });
+                const resolved = try fs.path.resolve(self.allocator, [][]const u8{ cwd, self.argv[0] });
                 defer self.allocator.free(resolved);
                 break :x try cstr.addNullByte(self.allocator, resolved);
             } else {
@@ -559,12 +557,12 @@ pub const ChildProcess = struct {
         windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {
             if (no_path_err != error.FileNotFound) return no_path_err;
 
-            const PATH = try os.getEnvVarOwned(self.allocator, "PATH");
+            const PATH = try process.getEnvVarOwned(self.allocator, "PATH");
             defer self.allocator.free(PATH);
 
             var it = mem.tokenize(PATH, ";");
             while (it.next()) |search_path| {
-                const joined_path = try os.path.join(self.allocator, [][]const u8{ search_path, app_name });
+                const joined_path = try fs.path.join(self.allocator, [][]const u8{ search_path, app_name });
                 defer self.allocator.free(joined_path);
 
                 const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
@@ -616,10 +614,10 @@ pub const ChildProcess = struct {
 
     fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
         switch (stdio) {
-            StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),
+            StdIo.Pipe => try os.dup2(pipe_fd, std_fileno),
             StdIo.Close => os.close(std_fileno),
             StdIo.Inherit => {},
-            StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno),
+            StdIo.Ignore => try os.dup2(dev_null_fd, std_fileno),
         }
     }
 };
std/cstr.zig
@@ -9,11 +9,6 @@ pub const line_sep = switch (builtin.os) {
     else => "\n",
 };
 
-/// Deprecated, use mem.len
-pub fn len(ptr: [*]const u8) usize {
-    return mem.len(u8, ptr);
-}
-
 pub fn cmp(a: [*]const u8, b: [*]const u8) i8 {
     var index: usize = 0;
     while (a[index] == b[index] and a[index] != 0) : (index += 1) {}
@@ -26,16 +21,6 @@ pub fn cmp(a: [*]const u8, b: [*]const u8) i8 {
     }
 }
 
-/// Deprecated, use mem.toSliceConst
-pub fn toSliceConst(str: [*]const u8) []const u8 {
-    return mem.toSliceConst(u8, str);
-}
-
-/// Deprecated, use mem.toSlice
-pub fn toSlice(str: [*]u8) []u8 {
-    return mem.toSlice(u8, str);
-}
-
 test "cstr fns" {
     comptime testCStrFnsImpl();
     testCStrFnsImpl();
std/debug.zig
@@ -3,16 +3,18 @@ const math = std.math;
 const mem = std.mem;
 const io = std.io;
 const os = std.os;
+const fs = std.fs;
+const process = std.process;
 const elf = std.elf;
 const DW = std.dwarf;
 const macho = std.macho;
 const coff = std.coff;
 const pdb = std.pdb;
-const windows = os.windows;
 const ArrayList = std.ArrayList;
 const builtin = @import("builtin");
 const maxInt = std.math.maxInt;
 const File = std.fs.File;
+const windows = std.os.windows;
 
 const leb = @import("debug/leb128.zig");
 
@@ -20,8 +22,8 @@ pub const FailingAllocator = @import("debug/failing_allocator.zig").FailingAlloc
 pub const failing_allocator = &FailingAllocator.init(global_allocator, 0).allocator;
 
 pub const runtime_safety = switch (builtin.mode) {
-    builtin.Mode.Debug, builtin.Mode.ReleaseSafe => true,
-    builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => false,
+    .Debug, .ReleaseSafe => true,
+    .ReleaseFast, .ReleaseSmall => false,
 };
 
 const Module = struct {
@@ -76,7 +78,7 @@ pub fn getSelfDebugInfo() !*DebugInfo {
 fn wantTtyColor() bool {
     var bytes: [128]u8 = undefined;
     const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
-    return if (std.os.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty();
+    return if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty();
 }
 
 /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
@@ -100,47 +102,44 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
 /// chopping off the irrelevant frames and shifting so that the returned addresses pointer
 /// equals the passed in addresses pointer.
 pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace) void {
-    switch (builtin.os) {
-        builtin.Os.windows => {
-            const addrs = stack_trace.instruction_addresses;
-            const u32_addrs_len = @intCast(u32, addrs.len);
-            const first_addr = first_address orelse {
-                stack_trace.index = windows.RtlCaptureStackBackTrace(
-                    0,
-                    u32_addrs_len,
-                    @ptrCast(**c_void, addrs.ptr),
-                    null,
-                );
-                return;
-            };
-            var addr_buf_stack: [32]usize = undefined;
-            const addr_buf = if (addr_buf_stack.len > addrs.len) addr_buf_stack[0..] else addrs;
-            const n = windows.RtlCaptureStackBackTrace(0, u32_addrs_len, @ptrCast(**c_void, addr_buf.ptr), null);
-            const first_index = for (addr_buf[0..n]) |addr, i| {
-                if (addr == first_addr) {
-                    break i;
-                }
-            } else {
-                stack_trace.index = 0;
+    if (windows.is_the_target) {
+        const addrs = stack_trace.instruction_addresses;
+        const u32_addrs_len = @intCast(u32, addrs.len);
+        const first_addr = first_address orelse {
+            stack_trace.index = windows.ntdll.RtlCaptureStackBackTrace(
+                0,
+                u32_addrs_len,
+                @ptrCast(**c_void, addrs.ptr),
+                null,
+            );
+            return;
+        };
+        var addr_buf_stack: [32]usize = undefined;
+        const addr_buf = if (addr_buf_stack.len > addrs.len) addr_buf_stack[0..] else addrs;
+        const n = windows.ntdll.RtlCaptureStackBackTrace(0, u32_addrs_len, @ptrCast(**c_void, addr_buf.ptr), null);
+        const first_index = for (addr_buf[0..n]) |addr, i| {
+            if (addr == first_addr) {
+                break i;
+            }
+        } else {
+            stack_trace.index = 0;
+            return;
+        };
+        const slice = addr_buf[first_index..n];
+        // We use a for loop here because slice and addrs may alias.
+        for (slice) |addr, i| {
+            addrs[i] = addr;
+        }
+        stack_trace.index = slice.len;
+    } else {
+        var it = StackIterator.init(first_address);
+        for (stack_trace.instruction_addresses) |*addr, i| {
+            addr.* = it.next() orelse {
+                stack_trace.index = i;
                 return;
             };
-            const slice = addr_buf[first_index..n];
-            // We use a for loop here because slice and addrs may alias.
-            for (slice) |addr, i| {
-                addrs[i] = addr;
-            }
-            stack_trace.index = slice.len;
-        },
-        else => {
-            var it = StackIterator.init(first_address);
-            for (stack_trace.instruction_addresses) |*addr, i| {
-                addr.* = it.next() orelse {
-                    stack_trace.index = i;
-                    return;
-                };
-            }
-            stack_trace.index = stack_trace.instruction_addresses.len;
-        },
+        }
+        stack_trace.index = stack_trace.instruction_addresses.len;
     }
 }
 
@@ -260,9 +259,8 @@ pub const StackIterator = struct {
 };
 
 pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
-    switch (builtin.os) {
-        builtin.Os.windows => return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr),
-        else => {},
+    if (windows.is_the_target) {
+        return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr);
     }
     var it = StackIterator.init(start_addr);
     while (it.next()) |return_address| {
@@ -277,7 +275,7 @@ pub fn writeCurrentStackTraceWindows(
     start_addr: ?usize,
 ) !void {
     var addr_buf: [1024]usize = undefined;
-    const n = windows.RtlCaptureStackBackTrace(0, addr_buf.len, @ptrCast(**c_void, &addr_buf), null);
+    const n = windows.ntdll.RtlCaptureStackBackTrace(0, addr_buf.len, @ptrCast(**c_void, &addr_buf), null);
     const addrs = addr_buf[0..n];
     var start_i: usize = if (start_addr) |saddr| blk: {
         for (addrs) |addr, i| {
@@ -291,17 +289,18 @@ pub fn writeCurrentStackTraceWindows(
 }
 
 pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
-    switch (builtin.os) {
-        builtin.Os.macosx => return printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color),
-        builtin.Os.linux, builtin.Os.freebsd, builtin.Os.netbsd => return printSourceAtAddressLinux(debug_info, out_stream, address, tty_color),
-        builtin.Os.windows => return printSourceAtAddressWindows(debug_info, out_stream, address, tty_color),
-        else => return error.UnsupportedOperatingSystem,
+    if (windows.is_the_target) {
+        return printSourceAtAddressWindows(debug_info, out_stream, address, tty_color);
     }
+    if (os.darwin.is_the_target) {
+        return printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color);
+    }
+    return printSourceAtAddressPosix(debug_info, out_stream, address, tty_color);
 }
 
 fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_address: usize, tty_color: bool) !void {
     const allocator = getDebugInfoAllocator();
-    const base_address = os.getBaseAddress();
+    const base_address = process.getBaseAddress();
     const relative_address = relocated_address - base_address;
 
     var coff_section: *coff.Section = undefined;
@@ -331,7 +330,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
 
     const mod = &di.modules[mod_index];
     try populateModule(di, mod);
-    const obj_basename = os.path.basename(mod.obj_file_name);
+    const obj_basename = fs.path.basename(mod.obj_file_name);
 
     var symbol_i: usize = 0;
     const symbol_name = while (symbol_i != mod.symbols.len) {
@@ -634,7 +633,7 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach
 }
 
 fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
-    const base_addr = std.os.getBaseAddress();
+    const base_addr = process.getBaseAddress();
     const adjusted_addr = 0x100000000 + (address - base_addr);
 
     const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse {
@@ -649,7 +648,7 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt
     const symbol_name = mem.toSliceConst(u8, di.strings.ptr + symbol.nlist.n_strx);
     const compile_unit_name = if (symbol.ofile) |ofile| blk: {
         const ofile_path = mem.toSliceConst(u8, di.strings.ptr + ofile.n_strx);
-        break :blk os.path.basename(ofile_path);
+        break :blk fs.path.basename(ofile_path);
     } else "???";
     if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| {
         defer line_info.deinit();
@@ -716,7 +715,7 @@ pub fn printSourceAtAddressDwarf(
     }
 }
 
-pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
+pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
     return printSourceAtAddressDwarf(debug_info, out_stream, address, tty_color, printLineFromFileAnyOs);
 }
 
@@ -776,16 +775,17 @@ pub const OpenSelfDebugInfoError = error{
 };
 
 pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
-    switch (builtin.os) {
-        builtin.Os.linux, builtin.Os.freebsd, builtin.Os.netbsd => return openSelfDebugInfoLinux(allocator),
-        builtin.Os.macosx, builtin.Os.ios => return openSelfDebugInfoMacOs(allocator),
-        builtin.Os.windows => return openSelfDebugInfoWindows(allocator),
-        else => return error.UnsupportedOperatingSystem,
+    if (windows.is_the_target) {
+        return openSelfDebugInfoWindows(allocator);
+    }
+    if (os.darwin.is_the_target) {
+        return openSelfDebugInfoMacOs(allocator);
     }
+    return openSelfDebugInfoPosix(allocator);
 }
 
 fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
-    const self_file = try os.openSelfExe();
+    const self_file = try fs.openSelfExe();
     defer self_file.close();
 
     const coff_obj = try allocator.create(coff.Coff);
@@ -812,7 +812,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
     const len = try di.coff.getPdbPath(path_buf[0..]);
     const raw_path = path_buf[0..len];
 
-    const path = try os.path.resolve(allocator, [][]const u8{raw_path});
+    const path = try fs.path.resolve(allocator, [][]const u8{raw_path});
 
     try di.pdb.openFile(di.coff, path);
 
@@ -1002,13 +1002,13 @@ pub fn openElfDebugInfo(
     return di;
 }
 
-fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DwarfInfo {
+fn openSelfDebugInfoPosix(allocator: *mem.Allocator) !DwarfInfo {
     const S = struct {
         var self_exe_file: File = undefined;
         var self_exe_mmap_seekable: io.SliceSeekableInStream = undefined;
     };
 
-    S.self_exe_file = try os.openSelfExe();
+    S.self_exe_file = try fs.openSelfExe();
     errdefer S.self_exe_file.close();
 
     const self_exe_mmap_len = try S.self_exe_file.getEndPos();
@@ -1195,7 +1195,7 @@ pub const DwarfInfo = struct {
 };
 
 pub const DebugInfo = switch (builtin.os) {
-    builtin.Os.macosx, builtin.Os.ios => struct {
+    .macosx, .ios, .watchos, .tvos => struct {
         symbols: []const MachoSymbol,
         strings: []const u8,
         ofiles: OFileTable,
@@ -1211,13 +1211,13 @@ pub const DebugInfo = switch (builtin.os) {
             return self.ofiles.allocator;
         }
     },
-    builtin.Os.uefi, builtin.Os.windows => struct {
+    .uefi, .windows => struct {
         pdb: pdb.Pdb,
         coff: *coff.Coff,
         sect_contribs: []pdb.SectionContribEntry,
         modules: []Module,
     },
-    builtin.Os.linux, builtin.Os.freebsd, builtin.Os.netbsd => DwarfInfo,
+    .linux, .freebsd, .netbsd => DwarfInfo,
     else => @compileError("Unsupported OS"),
 };
 
@@ -1411,7 +1411,7 @@ const LineNumberProgram = struct {
                 return error.InvalidDebugInfo;
             } else
                 self.include_dirs[file_entry.dir_index];
-            const file_name = try os.path.join(self.file_entries.allocator, [][]const u8{ dir_name, file_entry.file_name });
+            const file_name = try fs.path.join(self.file_entries.allocator, [][]const u8{ dir_name, file_entry.file_name });
             errdefer self.file_entries.allocator.free(file_name);
             return LineInfo{
                 .line = if (self.prev_line >= 0) @intCast(u64, self.prev_line) else 0,
std/dynamic_library.zig
@@ -2,7 +2,6 @@ const builtin = @import("builtin");
 
 const std = @import("std.zig");
 const mem = std.mem;
-const cstr = std.cstr;
 const os = std.os;
 const assert = std.debug.assert;
 const testing = std.testing;
@@ -223,7 +222,7 @@ pub const ElfLib = struct {
             if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;
             if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;
             if (0 == self.syms[i].st_shndx) continue;
-            if (!mem.eql(u8, name, cstr.toSliceConst(self.strings + self.syms[i].st_name))) continue;
+            if (!mem.eql(u8, name, mem.toSliceConst(u8, self.strings + self.syms[i].st_name))) continue;
             if (maybe_versym) |versym| {
                 if (!checkver(self.verdef.?, versym[i], vername, self.strings))
                     continue;
@@ -246,7 +245,7 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
         def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next);
     }
     const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
-    return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name));
+    return mem.eql(u8, vername, mem.toSliceConst(u8, strings + aux.vda_name));
 }
 
 pub const WindowsDynLib = struct {
std/fmt.zig
@@ -226,7 +226,7 @@ pub fn formatType(
             builtin.TypeInfo.Pointer.Size.Many => {
                 if (ptr_info.child == u8) {
                     if (fmt.len > 0 and fmt[0] == 's') {
-                        const len = std.cstr.len(value);
+                        const len = mem.len(u8, value);
                         return formatText(value[0..len], fmt, context, Errors, output);
                     }
                 }
std/fs.zig
@@ -1,6 +1,8 @@
+const builtin = @import("builtin");
 const std = @import("std.zig");
 const os = std.os;
 const mem = std.mem;
+const Allocator = std.mem.Allocator;
 
 pub const path = @import("fs/path.zig");
 pub const File = @import("fs/file.zig").File;
@@ -12,8 +14,6 @@ pub const deleteFileC = os.unlinkC;
 pub const rename = os.rename;
 pub const renameC = os.renameC;
 pub const renameW = os.renameW;
-pub const changeCurDir = os.chdir;
-pub const changeCurDirC = os.chdirC;
 pub const realpath = os.realpath;
 pub const realpathC = os.realpathC;
 pub const realpathW = os.realpathW;
@@ -65,13 +65,13 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path:
         else => return err, // TODO zig should know this set does not include PathAlreadyExists
     }
 
-    const dirname = os.path.dirname(new_path) orelse ".";
+    const dirname = path.dirname(new_path) orelse ".";
 
     var rand_buf: [12]u8 = undefined;
     const tmp_path = try allocator.alloc(u8, dirname.len + 1 + base64.Base64Encoder.calcSize(rand_buf.len));
     defer allocator.free(tmp_path);
     mem.copy(u8, tmp_path[0..], dirname);
-    tmp_path[dirname.len] = os.path.sep;
+    tmp_path[dirname.len] = path.sep;
     while (true) {
         try getRandomBytes(rand_buf[0..]);
         b64_fs_encoder.encode(tmp_path[dirname.len + 1 ..], rand_buf);
@@ -143,7 +143,7 @@ pub const AtomicFile = struct {
     /// TODO once we have null terminated pointers, use the
     /// openWriteNoClobberN function
     pub fn init(dest_path: []const u8, mode: File.Mode) InitError!AtomicFile {
-        const dirname = os.path.dirname(dest_path);
+        const dirname = path.dirname(dest_path);
         var rand_buf: [12]u8 = undefined;
         const dirname_component_len = if (dirname) |d| d.len + 1 else 0;
         const encoded_rand_len = comptime base64.Base64Encoder.calcSize(rand_buf.len);
@@ -153,7 +153,7 @@ pub const AtomicFile = struct {
 
         if (dirname) |dir| {
             mem.copy(u8, tmp_path_buf[0..], dir);
-            tmp_path_buf[dir.len] = os.path.sep;
+            tmp_path_buf[dir.len] = path.sep;
         }
 
         tmp_path_buf[tmp_path_len] = 0;
@@ -240,7 +240,7 @@ pub fn makePath(allocator: *Allocator, full_path: []const u8) !void {
                 // march end_index backward until next path component
                 while (true) {
                     end_index -= 1;
-                    if (os.path.isSep(resolved_path[end_index])) break;
+                    if (path.isSep(resolved_path[end_index])) break;
                 }
                 continue;
             },
@@ -250,7 +250,7 @@ pub fn makePath(allocator: *Allocator, full_path: []const u8) !void {
         // march end_index forward until next path component
         while (true) {
             end_index += 1;
-            if (end_index == resolved_path.len or os.path.isSep(resolved_path[end_index])) break;
+            if (end_index == resolved_path.len or path.isSep(resolved_path[end_index])) break;
         }
     }
 }
@@ -614,7 +614,7 @@ pub const Dir = struct {
             const next_index = self.handle.index + linux_entry.d_reclen;
             self.handle.index = next_index;
 
-            const name = cstr.toSlice(@ptrCast([*]u8, &linux_entry.d_name));
+            const name = mem.toSlice(u8, @ptrCast([*]u8, &linux_entry.d_name));
 
             // skip . and .. entries
             if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {
@@ -709,7 +709,7 @@ pub fn readLinkC(pathname: [*]const u8, buffer: *[os.PATH_MAX]u8) ![]u8 {
     return os.readlinkC(pathname, buffer);
 }
 
-pub const OpenSelfExeError = error{};
+pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError;
 
 pub fn openSelfExe() OpenSelfExeError!File {
     if (os.linux.is_the_target) {
std/heap.zig
@@ -103,7 +103,7 @@ pub const DirectAllocator = struct {
             return @ptrCast([*]u8, final_addr)[0..n];
         }
 
-        const alloc_size = if (alignment <= os.page_size) n else n + alignment;
+        const alloc_size = if (alignment <= mem.page_size) n else n + alignment;
         const addr = os.mmap(
             null,
             alloc_size,
@@ -123,7 +123,7 @@ pub const DirectAllocator = struct {
         if (unused_start_len != 0) {
             os.munmap(addr, unused_start_len);
         }
-        const aligned_end_addr = std.mem.alignForward(aligned_addr + n, os.page_size);
+        const aligned_end_addr = std.mem.alignForward(aligned_addr + n, mem.page_size);
         const unused_end_len = addr + alloc_size - aligned_end_addr;
         if (unused_end_len != 0) {
             os.munmap(aligned_end_addr, unused_end_len);
@@ -147,7 +147,7 @@ pub const DirectAllocator = struct {
                 const base_addr = @ptrToInt(old_mem.ptr);
                 const old_addr_end = base_addr + old_mem.len;
                 const new_addr_end = base_addr + new_size;
-                const new_addr_end_rounded = mem.alignForward(new_addr_end, os.page_size);
+                const new_addr_end_rounded = mem.alignForward(new_addr_end, mem.page_size);
                 if (old_addr_end > new_addr_end_rounded) {
                     // For shrinking that is not releasing, we will only
                     // decommit the pages not needed anymore.
@@ -163,7 +163,7 @@ pub const DirectAllocator = struct {
         const base_addr = @ptrToInt(old_mem.ptr);
         const old_addr_end = base_addr + old_mem.len;
         const new_addr_end = base_addr + new_size;
-        const new_addr_end_rounded = mem.alignForward(new_addr_end, os.page_size);
+        const new_addr_end_rounded = mem.alignForward(new_addr_end, mem.page_size);
         if (old_addr_end > new_addr_end_rounded) {
             os.munmap(new_addr_end_rounded, old_addr_end - new_addr_end_rounded);
         }
@@ -196,9 +196,9 @@ pub const DirectAllocator = struct {
             }
 
             const old_addr_end = base_addr + old_mem.len;
-            const old_addr_end_rounded = mem.alignForward(old_addr_end, os.page_size);
+            const old_addr_end_rounded = mem.alignForward(old_addr_end, mem.page_size);
             const new_addr_end = base_addr + new_size;
-            const new_addr_end_rounded = mem.alignForward(new_addr_end, os.page_size);
+            const new_addr_end_rounded = mem.alignForward(new_addr_end, mem.page_size);
             if (new_addr_end_rounded == old_addr_end_rounded) {
                 // The reallocation fits in the already allocated pages.
                 return @ptrCast([*]u8, old_mem.ptr)[0..new_size];
@@ -374,7 +374,7 @@ pub const ArenaAllocator = struct {
         var len = prev_len;
         while (true) {
             len += len / 2;
-            len += os.page_size - @rem(len, os.page_size);
+            len += mem.page_size - @rem(len, mem.page_size);
             if (len >= actual_min_size) break;
         }
         const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
@@ -520,11 +520,11 @@ const WasmAllocator = struct {
         const adjusted_index = self.end_index + (adjusted_addr - addr);
         const new_end_index = adjusted_index + size;
 
-        if (new_end_index > self.num_pages * os.page_size) {
-            const required_memory = new_end_index - (self.num_pages * os.page_size);
+        if (new_end_index > self.num_pages * mem.page_size) {
+            const required_memory = new_end_index - (self.num_pages * mem.page_size);
 
-            var num_pages: usize = required_memory / os.page_size;
-            if (required_memory % os.page_size != 0) {
+            var num_pages: usize = required_memory / mem.page_size;
+            if (required_memory % mem.page_size != 0) {
                 num_pages += 1;
             }
 
@@ -553,14 +553,14 @@ const WasmAllocator = struct {
 
         // Initialize start_ptr at the first realloc
         if (self.num_pages == 0) {
-            self.start_ptr = @intToPtr([*]u8, @intCast(usize, @"llvm.wasm.memory.size.i32"(0)) * os.page_size);
+            self.start_ptr = @intToPtr([*]u8, @intCast(usize, @"llvm.wasm.memory.size.i32"(0)) * mem.page_size);
         }
 
         if (is_last_item(allocator, old_mem, new_align)) {
             const start_index = self.end_index - old_mem.len;
             const new_end_index = start_index + new_size;
 
-            if (new_end_index > self.num_pages * os.page_size) {
+            if (new_end_index > self.num_pages * mem.page_size) {
                 _ = try alloc(allocator, new_end_index - self.end_index, new_align);
             }
             const result = self.start_ptr[start_index..new_end_index];
@@ -876,10 +876,10 @@ fn testAllocatorAligned(allocator: *mem.Allocator, comptime alignment: u29) !voi
 fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!void {
     //Maybe a platform's page_size is actually the same as or
     //  very near usize?
-    if (os.page_size << 2 > maxInt(usize)) return;
+    if (mem.page_size << 2 > maxInt(usize)) return;
 
     const USizeShift = @IntType(false, std.math.log2(usize.bit_count));
-    const large_align = u29(os.page_size << 2);
+    const large_align = u29(mem.page_size << 2);
 
     var align_mask: usize = undefined;
     _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask);
@@ -906,7 +906,7 @@ fn testAllocatorAlignedShrink(allocator: *mem.Allocator) mem.Allocator.Error!voi
     var debug_buffer: [1000]u8 = undefined;
     const debug_allocator = &FixedBufferAllocator.init(&debug_buffer).allocator;
 
-    const alloc_size = os.page_size * 2 + 50;
+    const alloc_size = mem.page_size * 2 + 50;
     var slice = try allocator.alignedAlloc(u8, 16, alloc_size);
     defer allocator.free(slice);
 
@@ -915,7 +915,7 @@ fn testAllocatorAlignedShrink(allocator: *mem.Allocator) mem.Allocator.Error!voi
     // which is 16 pages, hence the 32. This test may require to increase
     // the size of the allocations feeding the `allocator` parameter if they
     // fail, because of this high over-alignment we want to have.
-    while (@ptrToInt(slice.ptr) == mem.alignForward(@ptrToInt(slice.ptr), os.page_size * 32)) {
+    while (@ptrToInt(slice.ptr) == mem.alignForward(@ptrToInt(slice.ptr), mem.page_size * 32)) {
         try stuff_to_free.append(slice);
         slice = try allocator.alignedAlloc(u8, 16, alloc_size);
     }
@@ -926,7 +926,7 @@ fn testAllocatorAlignedShrink(allocator: *mem.Allocator) mem.Allocator.Error!voi
     slice[60] = 0x34;
 
     // realloc to a smaller size but with a larger alignment
-    slice = try allocator.alignedRealloc(slice, os.page_size * 32, alloc_size / 2);
+    slice = try allocator.alignedRealloc(slice, mem.page_size * 32, alloc_size / 2);
     testing.expect(slice[0] == 0x12);
     testing.expect(slice[60] == 0x34);
 }
std/io.zig
@@ -15,8 +15,31 @@ const fmt = std.fmt;
 const File = std.fs.File;
 const testing = std.testing;
 
-const is_posix = builtin.os != builtin.Os.windows;
-const is_windows = builtin.os == builtin.Os.windows;
+pub const GetStdIoError = os.windows.GetStdHandleError;
+
+pub fn getStdOut() GetStdIoError!File {
+    if (os.windows.is_the_target) {
+        const handle = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);
+        return File.openHandle(handle);
+    }
+    return File.openHandle(os.STDOUT_FILENO);
+}
+
+pub fn getStdErr() GetStdIoError!File {
+    if (os.windows.is_the_target) {
+        const handle = try os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE);
+        return File.openHandle(handle);
+    }
+    return File.openHandle(os.STDERR_FILENO);
+}
+
+pub fn getStdIn() GetStdIoError!File {
+    if (os.windows.is_the_target) {
+        const handle = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);
+        return File.openHandle(handle);
+    }
+    return File.openHandle(os.STDIN_FILENO);
+}
 
 pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;
 pub const SliceSeekableInStream = @import("io/seekable_stream.zig").SliceSeekableInStream;
std/mem.zig
@@ -1462,21 +1462,3 @@ test "std.mem.alignForward" {
     testing.expect(alignForward(16, 8) == 16);
     testing.expect(alignForward(17, 8) == 24);
 }
-
-pub fn getBaseAddress() usize {
-    switch (builtin.os) {
-        .linux => {
-            const base = std.os.system.getauxval(std.elf.AT_BASE);
-            if (base != 0) {
-                return base;
-            }
-            const phdr = std.os.system.getauxval(std.elf.AT_PHDR);
-            return phdr - @sizeOf(std.elf.Ehdr);
-        },
-        .macosx, .freebsd, .netbsd => {
-            return @ptrToInt(&std.c._mh_execute_header);
-        },
-        .windows => return @ptrToInt(windows.kernel32.GetModuleHandleW(null)),
-        else => @compileError("Unsupported OS"),
-    }
-}
std/os.zig
@@ -8,7 +8,7 @@
 //   cross platform abstracting.
 // * When there exists a corresponding libc function and linking libc, the libc
 //   implementation is used. Exceptions are made for known buggy areas of libc.
-//   On Linux libc can be side-stepped by using `std.os.linux.sys`.
+//   On Linux libc can be side-stepped by using `std.os.linux` directly.
 // * For Windows, this file represents the API that libc would provide for
 //   Windows. For thin wrappers around Windows-specific APIs, see `std.os.windows`.
 // Note: The Zig standard library does not support POSIX thread cancellation, and
@@ -16,7 +16,9 @@
 
 const std = @import("std.zig");
 const builtin = @import("builtin");
+const assert = std.debug.assert;
 const math = std.math;
+const mem = std.mem;
 const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
 
 comptime {
@@ -46,9 +48,14 @@ pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
 
 pub use @import("os/bits.zig");
 
-/// See also `getenv`.
+/// See also `getenv`. Populated by startup code before main().
 pub var environ: [][*]u8 = undefined;
 
+/// Populated by startup code before main().
+/// Not available on Windows. See `std.process.args`
+/// for obtaining the process arguments.
+pub var argv: [][*]u8 = undefined;
+
 /// To obtain errno, call this function with the return value of the
 /// system function call. For some systems this will obtain the value directly
 /// from the return code; for others it will use a thread-local errno variable.
@@ -103,7 +110,7 @@ pub fn getrandom(buf: []u8) GetRandomError!void {
         }
     }
     if (wasi.is_the_target) {
-        switch (os.wasi.random_get(buf.ptr, buf.len)) {
+        switch (wasi.random_get(buf.ptr, buf.len)) {
             0 => return,
             else => |err| return unexpectedErrno(err),
         }
@@ -138,15 +145,15 @@ pub fn abort() noreturn {
         while (true) {}
     }
 
-    raise(SIGABRT);
+    raise(SIGABRT) catch {};
 
     // TODO the rest of the implementation of abort() from musl libc here
 
-    raise(SIGKILL);
+    raise(SIGKILL) catch {};
     exit(127);
 }
 
-pub const RaiseError = error{};
+pub const RaiseError = error{Unexpected};
 
 pub fn raise(sig: u8) RaiseError!void {
     if (builtin.link_libc) {
@@ -163,19 +170,19 @@ pub fn raise(sig: u8) RaiseError!void {
         }
     }
 
-    if (windows.is_the_target) {
-        @compileError("TODO implement std.os.raise for Windows");
+    if (linux.is_the_target) {
+        var set: linux.sigset_t = undefined;
+        linux.blockAppSignals(&set);
+        const tid = linux.syscall0(linux.SYS_gettid);
+        const rc = linux.syscall2(linux.SYS_tkill, tid, sig);
+        linux.restoreSignals(&set);
+        switch (errno(rc)) {
+            0 => return,
+            else => |err| return unexpectedErrno(err),
+        }
     }
 
-    var set: system.sigset_t = undefined;
-    system.blockAppSignals(&set);
-    const tid = system.syscall0(system.SYS_gettid);
-    const rc = system.syscall2(system.SYS_tkill, tid, sig);
-    system.restoreSignals(&set);
-    switch (errno(rc)) {
-        0 => return,
-        else => |err| return unexpectedErrno(err),
-    }
+    @compileError("std.os.raise unimplemented for this target");
 }
 
 pub const KillError = error{
@@ -229,13 +236,13 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
     }
 
     if (wasi.is_the_target and !builtin.link_libc) {
-        const iovs = [1]was.iovec_t{wasi.iovec_t{
-            .buf = buf.ptr,
-            .buf_len = buf.len,
+        const iovs = [1]iovec{iovec{
+            .iov_base = buf.ptr,
+            .iov_len = buf.len,
         }};
 
         var nread: usize = undefined;
-        switch (fd_read(fd, &iovs, iovs.len, &nread)) {
+        switch (wasi.fd_read(fd, &iovs, iovs.len, &nread)) {
             0 => return nread,
             else => |err| return unexpectedErrno(err),
         }
@@ -277,7 +284,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
 /// This function is for blocking file descriptors only. For non-blocking, see
 /// `preadvAsync`.
 pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadError!usize {
-    if (os.darwin.is_the_target) {
+    if (darwin.is_the_target) {
         // Darwin does not have preadv but it does have pread.
         var off: usize = 0;
         var iov_i: usize = 0;
@@ -353,12 +360,12 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
     }
 
     if (wasi.is_the_target and !builtin.link_libc) {
-        const ciovs = [1]wasi.ciovec_t{wasi.ciovec_t{
-            .buf = bytes.ptr,
-            .buf_len = bytes.len,
+        const ciovs = [1]iovec_const{iovec_const{
+            .iov_base = bytes.ptr,
+            .iov_len = bytes.len,
         }};
         var nwritten: usize = undefined;
-        switch (fd_write(fd, &ciovs, ciovs.len, &nwritten)) {
+        switch (wasi.fd_write(fd, &ciovs, ciovs.len, &nwritten)) {
             0 => return,
             else => |err| return unexpectedErrno(err),
         }
@@ -538,29 +545,29 @@ pub fn dup2(old_fd: fd_t, new_fd: fd_t) !void {
 /// `argv[0]` is the executable path.
 /// This function also uses the PATH environment variable to get the full path to the executable.
 /// TODO provide execveC which does not take an allocator
-pub fn execve(allocator: *Allocator, argv: []const []const u8, env_map: *const BufMap) !void {
-    const argv_buf = try allocator.alloc(?[*]u8, argv.len + 1);
+pub fn execve(allocator: *mem.Allocator, argv_slice: []const []const u8, env_map: *const std.BufMap) !void {
+    const argv_buf = try allocator.alloc(?[*]u8, argv_slice.len + 1);
     mem.set(?[*]u8, argv_buf, null);
     defer {
         for (argv_buf) |arg| {
-            const arg_buf = if (arg) |ptr| cstr.toSlice(ptr) else break;
+            const arg_buf = if (arg) |ptr| mem.toSlice(u8, ptr) else break;
             allocator.free(arg_buf);
         }
         allocator.free(argv_buf);
     }
-    for (argv) |arg, i| {
+    for (argv_slice) |arg, i| {
         const arg_buf = try allocator.alloc(u8, arg.len + 1);
         @memcpy(arg_buf.ptr, arg.ptr, arg.len);
         arg_buf[arg.len] = 0;
 
         argv_buf[i] = arg_buf.ptr;
     }
-    argv_buf[argv.len] = null;
+    argv_buf[argv_slice.len] = null;
 
     const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);
     defer freeNullDelimitedEnvMap(allocator, envp_buf);
 
-    const exe_path = argv[0];
+    const exe_path = argv_slice[0];
     if (mem.indexOfScalar(u8, exe_path, '/') != null) {
         return execveErrnoToErr(errno(system.execve(argv_buf[0].?, argv_buf.ptr, envp_buf.ptr)));
     }
@@ -593,7 +600,7 @@ pub fn execve(allocator: *Allocator, argv: []const []const u8, env_map: *const B
     return execveErrnoToErr(err);
 }
 
-pub fn createNullDelimitedEnvMap(allocator: *Allocator, env_map: *const BufMap) ![]?[*]u8 {
+pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.BufMap) ![]?[*]u8 {
     const envp_count = env_map.count();
     const envp_buf = try allocator.alloc(?[*]u8, envp_count + 1);
     mem.set(?[*]u8, envp_buf, null);
@@ -616,9 +623,9 @@ pub fn createNullDelimitedEnvMap(allocator: *Allocator, env_map: *const BufMap)
     return envp_buf;
 }
 
-pub fn freeNullDelimitedEnvMap(allocator: *Allocator, envp_buf: []?[*]u8) void {
+pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*]u8) void {
     for (envp_buf) |env| {
-        const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;
+        const env_buf = if (env) |ptr| ptr[0 .. mem.len(u8, ptr) + 1] else break;
         allocator.free(env_buf);
     }
     allocator.free(envp_buf);
@@ -633,6 +640,8 @@ pub const ExecveError = error{
     FileNotFound,
     NotDir,
     FileBusy,
+    ProcessFdQuotaExceeded,
+    NameTooLong,
 
     Unexpected,
 };
@@ -703,17 +712,17 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
     }
 
     const err = if (builtin.link_libc) blk: {
-        break :blk if (system.getcwd(out_buffer.ptr, out_buffer.len)) |_| 0 else system._errno().*;
+        break :blk if (std.c.getcwd(out_buffer.ptr, out_buffer.len)) |_| 0 else std.c._errno().*;
     } else blk: {
-        break :blk errno(system.getcwd(out_buffer, out_buffer.len));
+        break :blk errno(system.getcwd(out_buffer.ptr, out_buffer.len));
     };
     switch (err) {
-        0 => return mem.toSlice(u8, out_buffer),
+        0 => return mem.toSlice(u8, out_buffer.ptr),
         EFAULT => unreachable,
         EINVAL => unreachable,
         ENOENT => return error.CurrentWorkingDirectoryUnlinked,
         ERANGE => return error.NameTooLong,
-        else => |err| return unexpectedErrno(err),
+        else => return unexpectedErrno(err),
     }
 }
 
@@ -1711,8 +1720,8 @@ pub const FStatError = error{
 
 pub fn fstat(fd: fd_t) FStatError!Stat {
     var stat: Stat = undefined;
-    if (os.darwin.is_the_target) {
-        switch (errno(system.@"fstat$INODE64"(fd, buf))) {
+    if (darwin.is_the_target) {
+        switch (errno(system.@"fstat$INODE64"(fd, &stat))) {
             0 => return stat,
             EBADF => unreachable, // Always a race condition.
             ENOMEM => return error.SystemResources,
@@ -1877,7 +1886,7 @@ pub const ForkError = error{
 pub fn fork() ForkError!pid_t {
     const rc = system.fork();
     switch (errno(rc)) {
-        0 => return rc,
+        0 => return @intCast(pid_t, rc),
         EAGAIN => return error.SystemResources,
         ENOMEM => return error.SystemResources,
         else => |err| return unexpectedErrno(err),
@@ -1891,6 +1900,7 @@ pub const MMapError = error{
     SystemFdQuotaExceeded,
     MemoryMappingNotSupported,
     OutOfMemory,
+    Unexpected,
 };
 
 /// Map files or devices into memory.
@@ -1992,6 +2002,7 @@ pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {
 pub const PipeError = error{
     SystemFdQuotaExceeded,
     ProcessFdQuotaExceeded,
+    Unexpected,
 };
 
 /// Creates a unidirectional data channel that can be used for interprocess communication.
@@ -2065,18 +2076,6 @@ pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) void {
     }
 }
 
-pub fn nanosleep(req: timespec) void {
-    var rem = req;
-    while (true) {
-        switch (errno(system.nanosleep(&rem, &rem))) {
-            0 => return,
-            EINVAL => unreachable, // Invalid parameters.
-            EFAULT => unreachable,
-            EINTR => continue,
-        }
-    }
-}
-
 pub const SeekError = error{
     Unseekable,
     Unexpected,
std/process.zig
@@ -1,13 +1,17 @@
+const builtin = @import("builtin");
 const std = @import("std.zig");
 const os = std.os;
 const BufMap = std.BufMap;
 const mem = std.mem;
+const math = std.math;
 const Allocator = mem.Allocator;
 const assert = std.debug.assert;
 const testing = std.testing;
 
 pub const abort = os.abort;
 pub const exit = os.exit;
+pub const changeCurDir = os.chdir;
+pub const changeCurDirC = os.chdirC;
 
 /// Caller must free result when done.
 /// TODO make this go through libc when we have it
@@ -15,9 +19,9 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
     var result = BufMap.init(allocator);
     errdefer result.deinit();
 
-    if (is_windows) {
-        const ptr = windows.GetEnvironmentStringsW() orelse return error.OutOfMemory;
-        defer assert(windows.FreeEnvironmentStringsW(ptr) != 0);
+    if (os.windows.is_the_target) {
+        const ptr = try os.windows.GetEnvironmentStringsW();
+        defer os.windows.FreeEnvironmentStringsW(ptr);
 
         var i: usize = 0;
         while (true) {
@@ -105,7 +109,7 @@ pub const GetEnvVarOwnedError = error{
 /// Caller must free returned memory.
 /// TODO make this go through libc when we have it
 pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
-    if (is_windows) {
+    if (os.windows.is_the_target) {
         const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
         defer allocator.free(key_with_null);
 
@@ -113,19 +117,15 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
         defer allocator.free(buf);
 
         while (true) {
-            const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory;
-            const result = windows.GetEnvironmentVariableW(key_with_null.ptr, buf.ptr, windows_buf_len);
-
-            if (result == 0) {
-                const err = windows.GetLastError();
-                return switch (err) {
-                    windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound,
-                    else => {
-                        windows.unexpectedError(err) catch {};
-                        return error.EnvironmentVariableNotFound;
-                    },
-                };
-            }
+            const windows_buf_len = math.cast(os.windows.DWORD, buf.len) catch return error.OutOfMemory;
+            const result = os.windows.GetEnvironmentVariableW(
+                key_with_null.ptr,
+                buf.ptr,
+                windows_buf_len,
+            ) catch |err| switch (err) {
+                error.Unexpected => return error.EnvironmentVariableNotFound,
+                else => return err,
+            };
 
             if (result > buf.len) {
                 buf = try allocator.realloc(buf, result);
@@ -136,11 +136,11 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
                 error.DanglingSurrogateHalf => return error.InvalidUtf8,
                 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,
                 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,
-                error.OutOfMemory => return error.OutOfMemory,
+                else => return err,
             };
         }
     } else {
-        const result = getEnvPosix(key) orelse return error.EnvironmentVariableNotFound;
+        const result = os.getenv(key) orelse return error.EnvironmentVariableNotFound;
         return mem.dupe(allocator, u8, result);
     }
 }
@@ -157,16 +157,16 @@ pub const ArgIteratorPosix = struct {
     pub fn init() ArgIteratorPosix {
         return ArgIteratorPosix{
             .index = 0,
-            .count = raw.len,
+            .count = os.argv.len,
         };
     }
 
     pub fn next(self: *ArgIteratorPosix) ?[]const u8 {
         if (self.index == self.count) return null;
 
-        const s = raw[self.index];
+        const s = os.argv[self.index];
         self.index += 1;
-        return cstr.toSlice(s);
+        return mem.toSlice(u8, s);
     }
 
     pub fn skip(self: *ArgIteratorPosix) bool {
@@ -175,10 +175,6 @@ pub const ArgIteratorPosix = struct {
         self.index += 1;
         return true;
     }
-
-    /// This is marked as public but actually it's only meant to be used
-    /// internally by zig's startup code.
-    pub var raw: [][*]u8 = undefined;
 };
 
 pub const ArgIteratorWindows = struct {
@@ -191,7 +187,7 @@ pub const ArgIteratorWindows = struct {
     pub const NextError = error{OutOfMemory};
 
     pub fn init() ArgIteratorWindows {
-        return initWithCmdLine(windows.GetCommandLineA());
+        return initWithCmdLine(os.windows.kernel32.GetCommandLineA());
     }
 
     pub fn initWithCmdLine(cmd_line: [*]const u8) ArgIteratorWindows {
@@ -581,3 +577,21 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
         if (amt_read < buf.len) return error.UserNotFound;
     }
 }
+
+pub fn getBaseAddress() usize {
+    switch (builtin.os) {
+        .linux => {
+            const base = os.system.getauxval(std.elf.AT_BASE);
+            if (base != 0) {
+                return base;
+            }
+            const phdr = os.system.getauxval(std.elf.AT_PHDR);
+            return phdr - @sizeOf(std.elf.Ehdr);
+        },
+        .macosx, .freebsd, .netbsd => {
+            return @ptrToInt(&std.c._mh_execute_header);
+        },
+        .windows => return @ptrToInt(os.windows.kernel32.GetModuleHandleW(null)),
+        else => @compileError("Unsupported OS"),
+    }
+}
std/thread.zig
@@ -227,7 +227,7 @@ pub const Thread = struct {
         var tls_start_offset: usize = undefined;
         const mmap_len = blk: {
             // First in memory will be the stack, which grows downwards.
-            var l: usize = mem.alignForward(default_stack_size, os.page_size);
+            var l: usize = mem.alignForward(default_stack_size, mem.page_size);
             stack_end_offset = l;
             // Above the stack, so that it can be in the same mmap call, put the Thread object.
             l = mem.alignForward(l, @alignOf(Thread));
test/cli.zig
@@ -1,7 +1,9 @@
 const std = @import("std");
 const builtin = @import("builtin");
-const os = std.os;
 const testing = std.testing;
+const process = std.process;
+const fs = std.fs;
+const ChildProcess = std.ChildProcess;
 
 var a: *std.mem.Allocator = undefined;
 
@@ -12,7 +14,7 @@ pub fn main() !void {
     var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
     defer arena.deinit();
 
-    var arg_it = os.args();
+    var arg_it = process.args();
 
     // skip my own exe name
     _ = arg_it.skip();
@@ -27,9 +29,9 @@ pub fn main() !void {
         std.debug.warn("Expected second argument to be cache root directory path\n");
         return error.InvalidArgs;
     });
-    const zig_exe = try os.path.resolve(a, [][]const u8{zig_exe_rel});
+    const zig_exe = try fs.path.resolve(a, [][]const u8{zig_exe_rel});
 
-    const dir_path = try os.path.join(a, [][]const u8{ cache_root, "clitest" });
+    const dir_path = try fs.path.join(a, [][]const u8{ cache_root, "clitest" });
     const TestFn = fn ([]const u8, []const u8) anyerror!void;
     const test_fns = []TestFn{
         testZigInitLib,
@@ -37,8 +39,8 @@ pub fn main() !void {
         testGodboltApi,
     };
     for (test_fns) |testFn| {
-        try os.deleteTree(a, dir_path);
-        try os.makeDir(dir_path);
+        try fs.deleteTree(a, dir_path);
+        try fs.makeDir(dir_path);
         try testFn(zig_exe, dir_path);
     }
 }
@@ -58,15 +60,15 @@ fn printCmd(cwd: []const u8, argv: []const []const u8) void {
     std.debug.warn("\n");
 }
 
-fn exec(cwd: []const u8, argv: []const []const u8) !os.ChildProcess.ExecResult {
+fn exec(cwd: []const u8, argv: []const []const u8) !ChildProcess.ExecResult {
     const max_output_size = 100 * 1024;
-    const result = os.ChildProcess.exec(a, argv, cwd, null, max_output_size) catch |err| {
+    const result = ChildProcess.exec(a, argv, cwd, null, max_output_size) catch |err| {
         std.debug.warn("The following command failed:\n");
         printCmd(cwd, argv);
         return err;
     };
     switch (result.term) {
-        os.ChildProcess.Term.Exited => |code| {
+        .Exited => |code| {
             if (code != 0) {
                 std.debug.warn("The following command exited with error code {}:\n", code);
                 printCmd(cwd, argv);
@@ -97,10 +99,10 @@ fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void {
 }
 
 fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
-    if (builtin.os != builtin.Os.linux or builtin.arch != builtin.Arch.x86_64) return;
+    if (builtin.os != .linux or builtin.arch != .x86_64) return;
 
-    const example_zig_path = try os.path.join(a, [][]const u8{ dir_path, "example.zig" });
-    const example_s_path = try os.path.join(a, [][]const u8{ dir_path, "example.s" });
+    const example_zig_path = try fs.path.join(a, [][]const u8{ dir_path, "example.zig" });
+    const example_s_path = try fs.path.join(a, [][]const u8{ dir_path, "example.s" });
 
     try std.io.writeFile(example_zig_path,
         \\// Type your code here, or load an example.
@@ -114,13 +116,13 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
     );
 
     const args = [][]const u8{
-        zig_exe, "build-obj",
-        "--cache-dir", dir_path,
-        "--name", "example",
-        "--output-dir", dir_path,
-        "--emit", "asm",
-        "-mllvm", "--x86-asm-syntax=intel",
-        "--strip", "--release-fast",
+        zig_exe,          "build-obj",
+        "--cache-dir",    dir_path,
+        "--name",         "example",
+        "--output-dir",   dir_path,
+        "--emit",         "asm",
+        "-mllvm",         "--x86-asm-syntax=intel",
+        "--strip",        "--release-fast",
         example_zig_path, "--disable-gen-h",
     };
     _ = try exec(dir_path, args);
test/tests.zig
@@ -2,11 +2,9 @@ const std = @import("std");
 const debug = std.debug;
 const warn = debug.warn;
 const build = std.build;
-const os = std.os;
-const StdIo = os.ChildProcess.StdIo;
-const Term = os.ChildProcess.Term;
 const Buffer = std.Buffer;
 const io = std.io;
+const fs = std.fs;
 const mem = std.mem;
 const fmt = std.fmt;
 const ArrayList = std.ArrayList;
@@ -30,19 +28,19 @@ const TestTarget = struct {
 
 const test_targets = []TestTarget{
     TestTarget{
-        .os = builtin.Os.linux,
-        .arch = builtin.Arch.x86_64,
-        .abi = builtin.Abi.gnu,
+        .os = .linux,
+        .arch = .x86_64,
+        .abi = .gnu,
     },
     TestTarget{
-        .os = builtin.Os.macosx,
-        .arch = builtin.Arch.x86_64,
-        .abi = builtin.Abi.gnu,
+        .os = .macosx,
+        .arch = .x86_64,
+        .abi = .gnu,
     },
     TestTarget{
-        .os = builtin.Os.windows,
-        .arch = builtin.Arch.x86_64,
-        .abi = builtin.Abi.msvc,
+        .os = .windows,
+        .arch = .x86_64,
+        .abi = .msvc,
     },
 };
 
@@ -114,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{
-        os.path.realAlloc(b.allocator, b.zig_exe) catch unreachable,
+        fs.path.realAlloc(b.allocator, b.zig_exe) catch unreachable,
         b.pathFromRoot(b.cache_root),
     });
 
@@ -301,12 +299,12 @@ pub const CompareOutputContext = struct {
 
             warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
 
-            const child = os.ChildProcess.init(args.toSliceConst(), b.allocator) catch unreachable;
+            const child = std.ChildProcess.init(args.toSliceConst(), b.allocator) catch unreachable;
             defer child.deinit();
 
-            child.stdin_behavior = StdIo.Ignore;
-            child.stdout_behavior = StdIo.Pipe;
-            child.stderr_behavior = StdIo.Pipe;
+            child.stdin_behavior = .Ignore;
+            child.stdout_behavior = .Pipe;
+            child.stderr_behavior = .Pipe;
             child.env_map = b.env_map;
 
             child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
@@ -324,7 +322,7 @@ pub const CompareOutputContext = struct {
                 debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
             };
             switch (term) {
-                Term.Exited => |code| {
+                .Exited => |code| {
                     if (code != 0) {
                         warn("Process {} exited with error code {}\n", full_exe_path, code);
                         printInvocation(args.toSliceConst());
@@ -383,13 +381,13 @@ pub const CompareOutputContext = struct {
 
             warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
 
-            const child = os.ChildProcess.init([][]const u8{full_exe_path}, b.allocator) catch unreachable;
+            const child = std.ChildProcess.init([][]const u8{full_exe_path}, b.allocator) catch unreachable;
             defer child.deinit();
 
             child.env_map = b.env_map;
-            child.stdin_behavior = StdIo.Ignore;
-            child.stdout_behavior = StdIo.Ignore;
-            child.stderr_behavior = StdIo.Ignore;
+            child.stdin_behavior = .Ignore;
+            child.stdout_behavior = .Ignore;
+            child.stderr_behavior = .Ignore;
 
             const term = child.spawnAndWait() catch |err| {
                 debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
@@ -397,13 +395,13 @@ pub const CompareOutputContext = struct {
 
             const expected_exit_code: i32 = 126;
             switch (term) {
-                Term.Exited => |code| {
+                .Exited => |code| {
                     if (code != expected_exit_code) {
                         warn("\nProgram expected to exit with code {} " ++ "but exited with code {}\n", expected_exit_code, code);
                         return error.TestFailed;
                     }
                 },
-                Term.Signal => |sig| {
+                .Signal => |sig| {
                     warn("\nProgram expected to exit with code {} " ++ "but instead signaled {}\n", expected_exit_code, sig);
                     return error.TestFailed;
                 },
@@ -459,7 +457,7 @@ pub const CompareOutputContext = struct {
     pub fn addCase(self: *CompareOutputContext, case: TestCase) void {
         const b = self.b;
 
-        const root_src = os.path.join(
+        const root_src = fs.path.join(
             b.allocator,
             [][]const u8{ b.cache_root, case.sources.items[0].filename },
         ) catch unreachable;
@@ -475,7 +473,7 @@ pub const CompareOutputContext = struct {
                 exe.addAssemblyFile(root_src);
 
                 for (case.sources.toSliceConst()) |src_file| {
-                    const expanded_src_path = os.path.join(
+                    const expanded_src_path = fs.path.join(
                         b.allocator,
                         [][]const u8{ b.cache_root, src_file.filename },
                     ) catch unreachable;
@@ -507,7 +505,7 @@ pub const CompareOutputContext = struct {
                     }
 
                     for (case.sources.toSliceConst()) |src_file| {
-                        const expanded_src_path = os.path.join(
+                        const expanded_src_path = fs.path.join(
                             b.allocator,
                             [][]const u8{ b.cache_root, src_file.filename },
                         ) catch unreachable;
@@ -538,7 +536,7 @@ pub const CompareOutputContext = struct {
                 }
 
                 for (case.sources.toSliceConst()) |src_file| {
-                    const expanded_src_path = os.path.join(
+                    const expanded_src_path = fs.path.join(
                         b.allocator,
                         [][]const u8{ b.cache_root, src_file.filename },
                     ) catch unreachable;
@@ -633,7 +631,7 @@ pub const CompileErrorContext = struct {
             const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
             const b = self.context.b;
 
-            const root_src = os.path.join(
+            const root_src = fs.path.join(
                 b.allocator,
                 [][]const u8{ b.cache_root, self.case.sources.items[0].filename },
             ) catch unreachable;
@@ -669,13 +667,13 @@ pub const CompileErrorContext = struct {
                 printInvocation(zig_args.toSliceConst());
             }
 
-            const child = os.ChildProcess.init(zig_args.toSliceConst(), b.allocator) catch unreachable;
+            const child = std.ChildProcess.init(zig_args.toSliceConst(), b.allocator) catch unreachable;
             defer child.deinit();
 
             child.env_map = b.env_map;
-            child.stdin_behavior = StdIo.Ignore;
-            child.stdout_behavior = StdIo.Pipe;
-            child.stderr_behavior = StdIo.Pipe;
+            child.stdin_behavior = .Ignore;
+            child.stdout_behavior = .Pipe;
+            child.stderr_behavior = .Pipe;
 
             child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err));
 
@@ -692,7 +690,7 @@ pub const CompileErrorContext = struct {
                 debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err));
             };
             switch (term) {
-                Term.Exited => |code| {
+                .Exited => |code| {
                     if (code == 0) {
                         printInvocation(zig_args.toSliceConst());
                         return error.CompilationIncorrectlySucceeded;
@@ -823,7 +821,7 @@ pub const CompileErrorContext = struct {
             self.step.dependOn(&compile_and_cmp_errors.step);
 
             for (case.sources.toSliceConst()) |src_file| {
-                const expanded_src_path = os.path.join(
+                const expanded_src_path = fs.path.join(
                     b.allocator,
                     [][]const u8{ b.cache_root, src_file.filename },
                 ) catch unreachable;
@@ -858,7 +856,7 @@ pub const BuildExamplesContext = struct {
         }
 
         var zig_args = ArrayList([]const u8).init(b.allocator);
-        const rel_zig_exe = os.path.relative(b.allocator, b.build_root, b.zig_exe) catch unreachable;
+        const rel_zig_exe = fs.path.relative(b.allocator, b.build_root, b.zig_exe) catch unreachable;
         zig_args.append(rel_zig_exe) catch unreachable;
         zig_args.append("build") catch unreachable;
 
@@ -958,7 +956,7 @@ pub const TranslateCContext = struct {
             const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
             const b = self.context.b;
 
-            const root_src = os.path.join(
+            const root_src = fs.path.join(
                 b.allocator,
                 [][]const u8{ b.cache_root, self.case.sources.items[0].filename },
             ) catch unreachable;
@@ -976,13 +974,13 @@ pub const TranslateCContext = struct {
                 printInvocation(zig_args.toSliceConst());
             }
 
-            const child = os.ChildProcess.init(zig_args.toSliceConst(), b.allocator) catch unreachable;
+            const child = std.ChildProcess.init(zig_args.toSliceConst(), b.allocator) catch unreachable;
             defer child.deinit();
 
             child.env_map = b.env_map;
-            child.stdin_behavior = StdIo.Ignore;
-            child.stdout_behavior = StdIo.Pipe;
-            child.stderr_behavior = StdIo.Pipe;
+            child.stdin_behavior = .Ignore;
+            child.stdout_behavior = .Pipe;
+            child.stderr_behavior = .Pipe;
 
             child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err));
 
@@ -999,14 +997,14 @@ pub const TranslateCContext = struct {
                 debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err));
             };
             switch (term) {
-                Term.Exited => |code| {
+                .Exited => |code| {
                     if (code != 0) {
                         warn("Compilation failed with exit code {}\n", code);
                         printInvocation(zig_args.toSliceConst());
                         return error.TestFailed;
                     }
                 },
-                Term.Signal => |code| {
+                .Signal => |code| {
                     warn("Compilation failed with signal {}\n", code);
                     printInvocation(zig_args.toSliceConst());
                     return error.TestFailed;
@@ -1131,7 +1129,7 @@ pub const TranslateCContext = struct {
         self.step.dependOn(&translate_c_and_cmp.step);
 
         for (case.sources.toSliceConst()) |src_file| {
-            const expanded_src_path = os.path.join(
+            const expanded_src_path = fs.path.join(
                 b.allocator,
                 [][]const u8{ b.cache_root, src_file.filename },
             ) catch unreachable;
@@ -1254,7 +1252,7 @@ pub const GenHContext = struct {
 
     pub fn addCase(self: *GenHContext, case: *const TestCase) void {
         const b = self.b;
-        const root_src = os.path.join(
+        const root_src = fs.path.join(
             b.allocator,
             [][]const u8{ b.cache_root, case.sources.items[0].filename },
         ) catch unreachable;
@@ -1269,7 +1267,7 @@ pub const GenHContext = struct {
         obj.setBuildMode(mode);
 
         for (case.sources.toSliceConst()) |src_file| {
-            const expanded_src_path = os.path.join(
+            const expanded_src_path = fs.path.join(
                 b.allocator,
                 [][]const u8{ b.cache_root, src_file.filename },
             ) catch unreachable;
build.zig
@@ -2,28 +2,28 @@ const builtin = @import("builtin");
 const std = @import("std");
 const Builder = std.build.Builder;
 const tests = @import("test/tests.zig");
-const os = std.os;
 const BufMap = std.BufMap;
 const warn = std.debug.warn;
 const mem = std.mem;
 const ArrayList = std.ArrayList;
 const Buffer = std.Buffer;
 const io = std.io;
+const fs = std.fs;
 
 pub fn build(b: *Builder) !void {
     const mode = b.standardReleaseOptions();
 
     var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
 
-    const rel_zig_exe = try os.path.relative(b.allocator, b.build_root, b.zig_exe);
-    const langref_out_path = os.path.join(
+    const rel_zig_exe = try fs.path.relative(b.allocator, b.build_root, b.zig_exe);
+    const langref_out_path = fs.path.join(
         b.allocator,
         [][]const u8{ b.cache_root, "langref.html" },
     ) catch unreachable;
     var docgen_cmd = docgen_exe.run();
     docgen_cmd.addArgs([][]const u8{
         rel_zig_exe,
-        "doc" ++ os.path.sep_str ++ "langref.html.in",
+        "doc" ++ fs.path.sep_str ++ "langref.html.in",
         langref_out_path,
     });
     docgen_cmd.step.dependOn(&docgen_exe.step);
@@ -137,7 +137,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
     for (dep.libdirs.toSliceConst()) |lib_dir| {
         lib_exe_obj.addLibPath(lib_dir);
     }
-    const lib_dir = os.path.join(
+    const lib_dir = fs.path.join(
         b.allocator,
         [][]const u8{ dep.prefix, "lib" },
     ) catch unreachable;
@@ -146,7 +146,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
             ([]const u8)("libncurses.a")
         else
             b.fmt("lib{}.a", lib);
-        const static_lib_name = os.path.join(
+        const static_lib_name = fs.path.join(
             b.allocator,
             [][]const u8{ lib_dir, static_bare_name },
         ) catch unreachable;
@@ -166,7 +166,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
 }
 
 fn fileExists(filename: []const u8) !bool {
-    os.File.access(filename) catch |err| switch (err) {
+    fs.File.access(filename) catch |err| switch (err) {
         error.PermissionDenied,
         error.FileNotFound,
         => return false,
@@ -177,7 +177,7 @@ fn fileExists(filename: []const u8) !bool {
 
 fn addCppLib(b: *Builder, lib_exe_obj: var, cmake_binary_dir: []const u8, lib_name: []const u8) void {
     const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
-    lib_exe_obj.addObjectFile(os.path.join(b.allocator, [][]const u8{
+    lib_exe_obj.addObjectFile(fs.path.join(b.allocator, [][]const u8{
         cmake_binary_dir,
         "zig_cpp",
         b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt()),
@@ -223,7 +223,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
             if (mem.startsWith(u8, lib_arg, "-l")) {
                 try result.system_libs.append(lib_arg[2..]);
             } else {
-                if (os.path.isAbsolute(lib_arg)) {
+                if (fs.path.isAbsolute(lib_arg)) {
                     try result.libs.append(lib_arg);
                 } else {
                     try result.system_libs.append(lib_arg);
@@ -257,8 +257,8 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
 pub fn installStdLib(b: *Builder, stdlib_files: []const u8) void {
     var it = mem.tokenize(stdlib_files, ";");
     while (it.next()) |stdlib_file| {
-        const src_path = os.path.join(b.allocator, [][]const u8{ "std", stdlib_file }) catch unreachable;
-        const dest_path = os.path.join(
+        const src_path = fs.path.join(b.allocator, [][]const u8{ "std", stdlib_file }) catch unreachable;
+        const dest_path = fs.path.join(
             b.allocator,
             [][]const u8{ "lib", "zig", "std", stdlib_file },
         ) catch unreachable;
@@ -269,8 +269,8 @@ pub fn installStdLib(b: *Builder, stdlib_files: []const u8) void {
 pub fn installCHeaders(b: *Builder, c_header_files: []const u8) void {
     var it = mem.tokenize(c_header_files, ";");
     while (it.next()) |c_header_file| {
-        const src_path = os.path.join(b.allocator, [][]const u8{ "c_headers", c_header_file }) catch unreachable;
-        const dest_path = os.path.join(
+        const src_path = fs.path.join(b.allocator, [][]const u8{ "c_headers", c_header_file }) catch unreachable;
+        const dest_path = fs.path.join(
             b.allocator,
             [][]const u8{ "lib", "zig", "include", c_header_file },
         ) catch unreachable;
@@ -315,7 +315,7 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void {
     }
     dependOnLib(b, exe, ctx.llvm);
 
-    if (exe.target.getOs() == builtin.Os.linux) {
+    if (exe.target.getOs() == .linux) {
         try addCxxKnownPath(b, ctx, exe, "libstdc++.a",
             \\Unable to determine path to libstdc++.a
             \\On Fedora, install libstdc++-static and try again.