| author | |
| committer | |
| log | 4a53e5b0b4131c6b8e18bb551e8215e425f8ac71 |
| tree | 4af8d360db353e40c74db394a9d03de1fdce9282 |
| parent | ebdbbd20ace6e93b581b90075f52946b3832da93 |
24 files changed, 148 insertions(+), 133 deletions(-)
lib/compiler/resinator/cli.zig+1-1| ... | @@ -2010,7 +2010,7 @@ test "maybeAppendRC" { | ... | @@ -2010,7 +2010,7 @@ test "maybeAppendRC" { |
| 2010 | 2010 | ||
| 2011 | // Now delete the file and try again. But this time change the input format | 2011 | // Now delete the file and try again. But this time change the input format |
| 2012 | // to non-rc. | 2012 | // to non-rc. |
| 2013 | try tmp.dir.deleteFile("foo"); | 2013 | try tmp.dir.deleteFile(io, "foo"); |
| 2014 | options.input_format = .res; | 2014 | options.input_format = .res; |
| 2015 | try options.maybeAppendRC(io, tmp.dir); | 2015 | try options.maybeAppendRC(io, tmp.dir); |
| 2016 | try std.testing.expectEqualStrings("foo", options.input_source.filename); | 2016 | try std.testing.expectEqualStrings("foo", options.input_source.filename); |
lib/compiler/resinator/main.zig+1-1| ... | @@ -440,7 +440,7 @@ const IoStream = struct { | ... | @@ -440,7 +440,7 @@ const IoStream = struct { |
| 440 | // Delete the output file on error | 440 | // Delete the output file on error |
| 441 | file.close(io); | 441 | file.close(io); |
| 442 | // Failing to delete is not really a big deal, so swallow any errors | 442 | // Failing to delete is not really a big deal, so swallow any errors |
| 443 | Io.Dir.cwd().deleteFile(self.name) catch {}; | 443 | Io.Dir.cwd().deleteFile(io, self.name) catch {}; |
| 444 | }, | 444 | }, |
| 445 | .stdio, .memory, .closed => return, | 445 | .stdio, .memory, .closed => return, |
| 446 | } | 446 | } |
lib/compiler/std-docs.zig+9-9| ... | @@ -72,8 +72,8 @@ pub fn main() !void { | ... | @@ -72,8 +72,8 @@ pub fn main() !void { |
| 72 | const url_with_newline = try std.fmt.allocPrint(arena, "http://127.0.0.1:{d}/\n", .{port}); | 72 | const url_with_newline = try std.fmt.allocPrint(arena, "http://127.0.0.1:{d}/\n", .{port}); |
| 73 | std.Io.File.stdout().writeAll(url_with_newline) catch {}; | 73 | std.Io.File.stdout().writeAll(url_with_newline) catch {}; |
| 74 | if (should_open_browser) { | 74 | if (should_open_browser) { |
| 75 | openBrowserTab(gpa, url_with_newline[0 .. url_with_newline.len - 1 :'\n']) catch |err| { | 75 | openBrowserTab(gpa, io, url_with_newline[0 .. url_with_newline.len - 1 :'\n']) catch |err| { |
| 76 | std.log.err("unable to open browser: {s}", .{@errorName(err)}); | 76 | std.log.err("unable to open browser: {t}", .{err}); |
| 77 | }; | 77 | }; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| ... | @@ -89,7 +89,7 @@ pub fn main() !void { | ... | @@ -89,7 +89,7 @@ pub fn main() !void { |
| 89 | while (true) { | 89 | while (true) { |
| 90 | const connection = try http_server.accept(); | 90 | const connection = try http_server.accept(); |
| 91 | _ = std.Thread.spawn(.{}, accept, .{ &context, connection }) catch |err| { | 91 | _ = std.Thread.spawn(.{}, accept, .{ &context, connection }) catch |err| { |
| 92 | std.log.err("unable to accept connection: {s}", .{@errorName(err)}); | 92 | std.log.err("unable to accept connection: {t}", .{err}); |
| 93 | connection.stream.close(io); | 93 | connection.stream.close(io); |
| 94 | continue; | 94 | continue; |
| 95 | }; | 95 | }; |
| ... | @@ -328,7 +328,7 @@ fn buildWasmBinary( | ... | @@ -328,7 +328,7 @@ fn buildWasmBinary( |
| 328 | child.stdin_behavior = .Pipe; | 328 | child.stdin_behavior = .Pipe; |
| 329 | child.stdout_behavior = .Pipe; | 329 | child.stdout_behavior = .Pipe; |
| 330 | child.stderr_behavior = .Pipe; | 330 | child.stderr_behavior = .Pipe; |
| 331 | try child.spawn(); | 331 | try child.spawn(io); |
| 332 | 332 | ||
| 333 | var poller = std.Io.poll(gpa, enum { stdout, stderr }, .{ | 333 | var poller = std.Io.poll(gpa, enum { stdout, stderr }, .{ |
| 334 | .stdout = child.stdout.?, | 334 | .stdout = child.stdout.?, |
| ... | @@ -434,13 +434,13 @@ fn sendMessage(io: Io, file: std.Io.File, tag: std.zig.Client.Message.Tag) !void | ... | @@ -434,13 +434,13 @@ fn sendMessage(io: Io, file: std.Io.File, tag: std.zig.Client.Message.Tag) !void |
| 434 | }; | 434 | }; |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | fn openBrowserTab(gpa: Allocator, url: []const u8) !void { | 437 | fn openBrowserTab(gpa: Allocator, io: Io, url: []const u8) !void { |
| 438 | // Until https://github.com/ziglang/zig/issues/19205 is implemented, we | 438 | // Until https://github.com/ziglang/zig/issues/19205 is implemented, we |
| 439 | // spawn a thread for this child process. | 439 | // spawn a thread for this child process. |
| 440 | _ = try std.Thread.spawn(.{}, openBrowserTabThread, .{ gpa, url }); | 440 | _ = try std.Thread.spawn(.{}, openBrowserTabThread, .{ gpa, io, url }); |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void { | 443 | fn openBrowserTabThread(gpa: Allocator, io: Io, url: []const u8) !void { |
| 444 | const main_exe = switch (builtin.os.tag) { | 444 | const main_exe = switch (builtin.os.tag) { |
| 445 | .windows => "explorer", | 445 | .windows => "explorer", |
| 446 | .macos => "open", | 446 | .macos => "open", |
| ... | @@ -450,6 +450,6 @@ fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void { | ... | @@ -450,6 +450,6 @@ fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void { |
| 450 | child.stdin_behavior = .Ignore; | 450 | child.stdin_behavior = .Ignore; |
| 451 | child.stdout_behavior = .Ignore; | 451 | child.stdout_behavior = .Ignore; |
| 452 | child.stderr_behavior = .Ignore; | 452 | child.stderr_behavior = .Ignore; |
| 453 | try child.spawn(); | 453 | try child.spawn(io); |
| 454 | _ = try child.wait(); | 454 | _ = try child.wait(io); |
| 455 | } | 455 | } |
lib/std/Build.zig+1-1| ... | @@ -1838,7 +1838,7 @@ pub fn runAllowFail( | ... | @@ -1838,7 +1838,7 @@ pub fn runAllowFail( |
| 1838 | child.env_map = &b.graph.env_map; | 1838 | child.env_map = &b.graph.env_map; |
| 1839 | 1839 | ||
| 1840 | try Step.handleVerbose2(b, null, child.env_map, argv); | 1840 | try Step.handleVerbose2(b, null, child.env_map, argv); |
| 1841 | try child.spawn(); | 1841 | try child.spawn(io); |
| 1842 | 1842 | ||
| 1843 | var stdout_reader = child.stdout.?.readerStreaming(io, &.{}); | 1843 | var stdout_reader = child.stdout.?.readerStreaming(io, &.{}); |
| 1844 | const stdout = stdout_reader.interface.allocRemaining(b.allocator, .limited(max_output_size)) catch { | 1844 | const stdout = stdout_reader.interface.allocRemaining(b.allocator, .limited(max_output_size)) catch { |
lib/std/Build/Cache.zig+1-1| ... | @@ -1300,7 +1300,7 @@ fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp { | ... | @@ -1300,7 +1300,7 @@ fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp { |
| 1300 | }); | 1300 | }); |
| 1301 | defer { | 1301 | defer { |
| 1302 | file.close(io); | 1302 | file.close(io); |
| 1303 | dir.deleteFile(test_out_file) catch {}; | 1303 | dir.deleteFile(io, test_out_file) catch {}; |
| 1304 | } | 1304 | } |
| 1305 | 1305 | ||
| 1306 | return (try file.stat(io)).mtime; | 1306 | return (try file.stat(io)).mtime; |
lib/std/Build/Step.zig+1-1| ... | @@ -455,7 +455,7 @@ pub fn evalZigProcess( | ... | @@ -455,7 +455,7 @@ pub fn evalZigProcess( |
| 455 | child.request_resource_usage_statistics = true; | 455 | child.request_resource_usage_statistics = true; |
| 456 | child.progress_node = prog_node; | 456 | child.progress_node = prog_node; |
| 457 | 457 | ||
| 458 | child.spawn() catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err }); | 458 | child.spawn(io) catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err }); |
| 459 | 459 | ||
| 460 | const zp = try gpa.create(ZigProcess); | 460 | const zp = try gpa.create(ZigProcess); |
| 461 | zp.* = .{ | 461 | zp.* = .{ |
lib/std/Build/Step/Run.zig+2-2| ... | @@ -1689,7 +1689,7 @@ fn evalZigTest( | ... | @@ -1689,7 +1689,7 @@ fn evalZigTest( |
| 1689 | }; | 1689 | }; |
| 1690 | 1690 | ||
| 1691 | while (true) { | 1691 | while (true) { |
| 1692 | try child.spawn(); | 1692 | try child.spawn(io); |
| 1693 | var poller = std.Io.poll(gpa, StdioPollEnum, .{ | 1693 | var poller = std.Io.poll(gpa, StdioPollEnum, .{ |
| 1694 | .stdout = child.stdout.?, | 1694 | .stdout = child.stdout.?, |
| 1695 | .stderr = child.stderr.?, | 1695 | .stderr = child.stderr.?, |
| ... | @@ -2168,7 +2168,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { | ... | @@ -2168,7 +2168,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { |
| 2168 | const io = b.graph.io; | 2168 | const io = b.graph.io; |
| 2169 | const arena = b.allocator; | 2169 | const arena = b.allocator; |
| 2170 | 2170 | ||
| 2171 | try child.spawn(); | 2171 | try child.spawn(io); |
| 2172 | errdefer _ = child.kill(io) catch {}; | 2172 | errdefer _ = child.kill(io) catch {}; |
| 2173 | 2173 | ||
| 2174 | try child.waitForSpawn(); | 2174 | try child.waitForSpawn(); |
lib/std/Build/WebServer.zig+1-1| ... | @@ -580,7 +580,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim | ... | @@ -580,7 +580,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim |
| 580 | child.stdin_behavior = .Pipe; | 580 | child.stdin_behavior = .Pipe; |
| 581 | child.stdout_behavior = .Pipe; | 581 | child.stdout_behavior = .Pipe; |
| 582 | child.stderr_behavior = .Pipe; | 582 | child.stderr_behavior = .Pipe; |
| 583 | try child.spawn(); | 583 | try child.spawn(io); |
| 584 | 584 | ||
| 585 | var poller = Io.poll(gpa, enum { stdout, stderr }, .{ | 585 | var poller = Io.poll(gpa, enum { stdout, stderr }, .{ |
| 586 | .stdout = child.stdout.?, | 586 | .stdout = child.stdout.?, |
lib/std/Io/Dir.zig+4-3| ... | @@ -1366,7 +1366,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { | ... | @@ -1366,7 +1366,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { |
| 1366 | => |e| return e, | 1366 | => |e| return e, |
| 1367 | }; | 1367 | }; |
| 1368 | } else { | 1368 | } else { |
| 1369 | if (parent_dir.deleteFile(name)) { | 1369 | if (parent_dir.deleteFile(io, name)) { |
| 1370 | continue :process_stack; | 1370 | continue :process_stack; |
| 1371 | } else |err| switch (err) { | 1371 | } else |err| switch (err) { |
| 1372 | error.FileNotFound => continue :process_stack, | 1372 | error.FileNotFound => continue :process_stack, |
| ... | @@ -1477,7 +1477,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, | ... | @@ -1477,7 +1477,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, |
| 1477 | dir_name = result; | 1477 | dir_name = result; |
| 1478 | continue :scan_dir; | 1478 | continue :scan_dir; |
| 1479 | } else { | 1479 | } else { |
| 1480 | if (dir.deleteFile(entry.name)) { | 1480 | if (dir.deleteFile(io, entry.name)) { |
| 1481 | continue :dir_it; | 1481 | continue :dir_it; |
| 1482 | } else |err| switch (err) { | 1482 | } else |err| switch (err) { |
| 1483 | error.FileNotFound => continue :dir_it, | 1483 | error.FileNotFound => continue :dir_it, |
| ... | @@ -1567,7 +1567,7 @@ fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hin | ... | @@ -1567,7 +1567,7 @@ fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hin |
| 1567 | => |e| return e, | 1567 | => |e| return e, |
| 1568 | }; | 1568 | }; |
| 1569 | } else { | 1569 | } else { |
| 1570 | if (dir.deleteFile(sub_path)) { | 1570 | if (dir.deleteFile(io, sub_path)) { |
| 1571 | return null; | 1571 | return null; |
| 1572 | } else |err| switch (err) { | 1572 | } else |err| switch (err) { |
| 1573 | error.FileNotFound => return null, | 1573 | error.FileNotFound => return null, |
| ... | @@ -1588,6 +1588,7 @@ fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hin | ... | @@ -1588,6 +1588,7 @@ fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hin |
| 1588 | error.FileBusy, | 1588 | error.FileBusy, |
| 1589 | error.BadPathName, | 1589 | error.BadPathName, |
| 1590 | error.NetworkNotFound, | 1590 | error.NetworkNotFound, |
| 1591 | error.Canceled, | ||
| 1591 | error.Unexpected, | 1592 | error.Unexpected, |
| 1592 | => |e| return e, | 1593 | => |e| return e, |
| 1593 | } | 1594 | } |
lib/std/Io/File.zig+4| ... | @@ -407,6 +407,10 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( | ... | @@ -407,6 +407,10 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( |
| 407 | return @intFromEnum(self); | 407 | return @intFromEnum(self); |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | pub fn fromMode(mode: std.posix.mode_t) @This() { | ||
| 411 | return @enumFromInt(mode); | ||
| 412 | } | ||
| 413 | |||
| 410 | /// Returns `true` if and only if no class has write permissions. | 414 | /// Returns `true` if and only if no class has write permissions. |
| 411 | pub fn readOnly(self: @This()) bool { | 415 | pub fn readOnly(self: @This()) bool { |
| 412 | const mode = toMode(self); | 416 | const mode = toMode(self); |
lib/std/Io/File/Atomic.zig+5-2| ... | @@ -20,7 +20,7 @@ pub const InitError = File.OpenError; | ... | @@ -20,7 +20,7 @@ pub const InitError = File.OpenError; |
| 20 | pub fn init( | 20 | pub fn init( |
| 21 | io: Io, | 21 | io: Io, |
| 22 | dest_basename: []const u8, | 22 | dest_basename: []const u8, |
| 23 | mode: File.Mode, | 23 | permissions: File.Permissions, |
| 24 | dir: Dir, | 24 | dir: Dir, |
| 25 | close_dir_on_deinit: bool, | 25 | close_dir_on_deinit: bool, |
| 26 | write_buffer: []u8, | 26 | write_buffer: []u8, |
| ... | @@ -28,7 +28,10 @@ pub fn init( | ... | @@ -28,7 +28,10 @@ pub fn init( |
| 28 | while (true) { | 28 | while (true) { |
| 29 | const random_integer = std.crypto.random.int(u64); | 29 | const random_integer = std.crypto.random.int(u64); |
| 30 | const tmp_sub_path = std.fmt.hex(random_integer); | 30 | const tmp_sub_path = std.fmt.hex(random_integer); |
| 31 | const file = dir.createFile(io, &tmp_sub_path, .{ .mode = mode, .exclusive = true }) catch |err| switch (err) { | 31 | const file = dir.createFile(io, &tmp_sub_path, .{ |
| 32 | .permissions = permissions, | ||
| 33 | .exclusive = true, | ||
| 34 | }) catch |err| switch (err) { | ||
| 32 | error.PathAlreadyExists => continue, | 35 | error.PathAlreadyExists => continue, |
| 33 | else => |e| return e, | 36 | else => |e| return e, |
| 34 | }; | 37 | }; |
lib/std/Io/net/test.zig+1-1| ... | @@ -278,7 +278,7 @@ test "listen on a unix socket, send bytes, receive bytes" { | ... | @@ -278,7 +278,7 @@ test "listen on a unix socket, send bytes, receive bytes" { |
| 278 | defer testing.allocator.free(socket_path); | 278 | defer testing.allocator.free(socket_path); |
| 279 | 279 | ||
| 280 | const socket_addr = try net.UnixAddress.init(socket_path); | 280 | const socket_addr = try net.UnixAddress.init(socket_path); |
| 281 | defer Io.Dir.cwd().deleteFile(socket_path) catch {}; | 281 | defer Io.Dir.cwd().deleteFile(io, socket_path) catch {}; |
| 282 | 282 | ||
| 283 | var server = try socket_addr.listen(io, .{}); | 283 | var server = try socket_addr.listen(io, .{}); |
| 284 | defer server.socket.close(io); | 284 | defer server.socket.close(io); |
lib/std/Io/test.zig+1-1| ... | @@ -60,7 +60,7 @@ test "write a file, read it, then delete it" { | ... | @@ -60,7 +60,7 @@ test "write a file, read it, then delete it" { |
| 60 | try expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data)); | 60 | try expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data)); |
| 61 | try expect(mem.eql(u8, contents[contents.len - "end".len ..], "end")); | 61 | try expect(mem.eql(u8, contents[contents.len - "end".len ..], "end")); |
| 62 | } | 62 | } |
| 63 | try tmp.dir.deleteFile(tmp_file_name); | 63 | try tmp.dir.deleteFile(io, tmp_file_name); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | test "File seek ops" { | 66 | test "File seek ops" { |
lib/std/fs/test.zig+13-13| ... | @@ -873,7 +873,7 @@ test "file operations on directories" { | ... | @@ -873,7 +873,7 @@ test "file operations on directories" { |
| 873 | try ctx.dir.makeDir(io, test_dir_name, .default_dir); | 873 | try ctx.dir.makeDir(io, test_dir_name, .default_dir); |
| 874 | 874 | ||
| 875 | try testing.expectError(error.IsDir, ctx.dir.createFile(io, test_dir_name, .{})); | 875 | try testing.expectError(error.IsDir, ctx.dir.createFile(io, test_dir_name, .{})); |
| 876 | try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name)); | 876 | try testing.expectError(error.IsDir, ctx.dir.deleteFile(io, test_dir_name)); |
| 877 | switch (native_os) { | 877 | switch (native_os) { |
| 878 | .dragonfly, .netbsd => { | 878 | .dragonfly, .netbsd => { |
| 879 | // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732 | 879 | // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732 |
| ... | @@ -942,7 +942,7 @@ test "deleteDir" { | ... | @@ -942,7 +942,7 @@ test "deleteDir" { |
| 942 | try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(test_dir_path)); | 942 | try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(test_dir_path)); |
| 943 | 943 | ||
| 944 | // deleting an empty directory | 944 | // deleting an empty directory |
| 945 | try ctx.dir.deleteFile(test_file_path); | 945 | try ctx.dir.deleteFile(io, test_file_path); |
| 946 | try ctx.dir.deleteDir(test_dir_path); | 946 | try ctx.dir.deleteDir(test_dir_path); |
| 947 | } | 947 | } |
| 948 | }.impl); | 948 | }.impl); |
| ... | @@ -1671,13 +1671,13 @@ test "copyFile" { | ... | @@ -1671,13 +1671,13 @@ test "copyFile" { |
| 1671 | const dest_file2 = try ctx.transformPath("tmp_test_copy_file3.txt"); | 1671 | const dest_file2 = try ctx.transformPath("tmp_test_copy_file3.txt"); |
| 1672 | 1672 | ||
| 1673 | try ctx.dir.writeFile(io, .{ .sub_path = src_file, .data = data }); | 1673 | try ctx.dir.writeFile(io, .{ .sub_path = src_file, .data = data }); |
| 1674 | defer ctx.dir.deleteFile(src_file) catch {}; | 1674 | defer ctx.dir.deleteFile(io, src_file) catch {}; |
| 1675 | 1675 | ||
| 1676 | try ctx.dir.copyFile(src_file, ctx.dir, dest_file, .{}); | 1676 | try ctx.dir.copyFile(src_file, ctx.dir, dest_file, .{}); |
| 1677 | defer ctx.dir.deleteFile(dest_file) catch {}; | 1677 | defer ctx.dir.deleteFile(io, dest_file) catch {}; |
| 1678 | 1678 | ||
| 1679 | try ctx.dir.copyFile(src_file, ctx.dir, dest_file2, .{ .override_mode = File.default_mode }); | 1679 | try ctx.dir.copyFile(src_file, ctx.dir, dest_file2, .{ .override_mode = File.default_mode }); |
| 1680 | defer ctx.dir.deleteFile(dest_file2) catch {}; | 1680 | defer ctx.dir.deleteFile(io, dest_file2) catch {}; |
| 1681 | 1681 | ||
| 1682 | try expectFileContents(io, ctx.dir, dest_file, data); | 1682 | try expectFileContents(io, ctx.dir, dest_file, data); |
| 1683 | try expectFileContents(io, ctx.dir, dest_file2, data); | 1683 | try expectFileContents(io, ctx.dir, dest_file2, data); |
| ... | @@ -1713,7 +1713,7 @@ test "AtomicFile" { | ... | @@ -1713,7 +1713,7 @@ test "AtomicFile" { |
| 1713 | const content = try ctx.dir.readFileAlloc(io, test_out_file, allocator, .limited(9999)); | 1713 | const content = try ctx.dir.readFileAlloc(io, test_out_file, allocator, .limited(9999)); |
| 1714 | try testing.expectEqualStrings(test_content, content); | 1714 | try testing.expectEqualStrings(test_content, content); |
| 1715 | 1715 | ||
| 1716 | try ctx.dir.deleteFile(test_out_file); | 1716 | try ctx.dir.deleteFile(io, test_out_file); |
| 1717 | } | 1717 | } |
| 1718 | }.impl); | 1718 | }.impl); |
| 1719 | } | 1719 | } |
| ... | @@ -2055,7 +2055,7 @@ test "'.' and '..' in Io.Dir functions" { | ... | @@ -2055,7 +2055,7 @@ test "'.' and '..' in Io.Dir functions" { |
| 2055 | try ctx.dir.rename(copy_path, ctx.dir, rename_path, io); | 2055 | try ctx.dir.rename(copy_path, ctx.dir, rename_path, io); |
| 2056 | const renamed_file = try ctx.dir.openFile(io, rename_path, .{}); | 2056 | const renamed_file = try ctx.dir.openFile(io, rename_path, .{}); |
| 2057 | renamed_file.close(io); | 2057 | renamed_file.close(io); |
| 2058 | try ctx.dir.deleteFile(rename_path); | 2058 | try ctx.dir.deleteFile(io, rename_path); |
| 2059 | 2059 | ||
| 2060 | try ctx.dir.writeFile(io, .{ .sub_path = update_path, .data = "something" }); | 2060 | try ctx.dir.writeFile(io, .{ .sub_path = update_path, .data = "something" }); |
| 2061 | var dir = ctx.dir; | 2061 | var dir = ctx.dir; |
| ... | @@ -2113,19 +2113,19 @@ test "chmod" { | ... | @@ -2113,19 +2113,19 @@ test "chmod" { |
| 2113 | var tmp = tmpDir(.{}); | 2113 | var tmp = tmpDir(.{}); |
| 2114 | defer tmp.cleanup(); | 2114 | defer tmp.cleanup(); |
| 2115 | 2115 | ||
| 2116 | const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 }); | 2116 | const file = try tmp.dir.createFile(io, "test_file", .{ .permissions = .fromMode(0o600) }); |
| 2117 | defer file.close(io); | 2117 | defer file.close(io); |
| 2118 | try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat(io)).mode & 0o7777); | 2118 | try testing.expectEqual(@as(posix.mode_t, 0o600), (try file.stat(io)).permissions.toMode() & 0o7777); |
| 2119 | 2119 | ||
| 2120 | try file.chmod(0o644); | 2120 | try file.setPermissions(io, .fromMode(0o644)); |
| 2121 | try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat(io)).mode & 0o7777); | 2121 | try testing.expectEqual(@as(posix.mode_t, 0o644), (try file.stat(io)).permissions.toMode() & 0o7777); |
| 2122 | 2122 | ||
| 2123 | try tmp.dir.makeDir(io, "test_dir", .default_dir); | 2123 | try tmp.dir.makeDir(io, "test_dir", .default_dir); |
| 2124 | var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); | 2124 | var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); |
| 2125 | defer dir.close(io); | 2125 | defer dir.close(io); |
| 2126 | 2126 | ||
| 2127 | try dir.chmod(0o700); | 2127 | try dir.setPermissions(io, .fromMode(0o700)); |
| 2128 | try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat(io)).mode & 0o7777); | 2128 | try testing.expectEqual(@as(posix.mode_t, 0o700), (try dir.stat(io)).permissions.toMode() & 0o7777); |
| 2129 | } | 2129 | } |
| 2130 | 2130 | ||
| 2131 | test "chown" { | 2131 | test "chown" { |
lib/std/posix/test.zig+1-1| ... | @@ -144,7 +144,7 @@ test "linkat with different directories" { | ... | @@ -144,7 +144,7 @@ test "linkat with different directories" { |
| 144 | 144 | ||
| 145 | const subdir = try tmp.dir.makeOpenPath("subdir", .{}); | 145 | const subdir = try tmp.dir.makeOpenPath("subdir", .{}); |
| 146 | 146 | ||
| 147 | defer tmp.dir.deleteFile(target_name) catch {}; | 147 | defer tmp.dir.deleteFile(io, target_name) catch {}; |
| 148 | try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "example" }); | 148 | try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "example" }); |
| 149 | 149 | ||
| 150 | // Test 1: link from file in subdir back up to target in parent directory | 150 | // Test 1: link from file in subdir back up to target in parent directory |
lib/std/process/Child.zig+47-47| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | const ChildProcess = @This(); | 1 | const Child = @This(); |
| 2 | 2 | ||
| 3 | const builtin = @import("builtin"); | 3 | const builtin = @import("builtin"); |
| 4 | const native_os = builtin.os.tag; | 4 | const native_os = builtin.os.tag; |
| ... | @@ -31,7 +31,7 @@ pub const Id = switch (native_os) { | ... | @@ -31,7 +31,7 @@ pub const Id = switch (native_os) { |
| 31 | id: Id, | 31 | id: Id, |
| 32 | thread_handle: if (native_os == .windows) windows.HANDLE else void, | 32 | thread_handle: if (native_os == .windows) windows.HANDLE else void, |
| 33 | 33 | ||
| 34 | allocator: mem.Allocator, | 34 | allocator: Allocator, |
| 35 | 35 | ||
| 36 | /// The writing end of the child process's standard input pipe. | 36 | /// The writing end of the child process's standard input pipe. |
| 37 | /// Usage requires `stdin_behavior == StdIo.Pipe`. | 37 | /// Usage requires `stdin_behavior == StdIo.Pipe`. |
| ... | @@ -229,7 +229,7 @@ pub const StdIo = enum { | ... | @@ -229,7 +229,7 @@ pub const StdIo = enum { |
| 229 | }; | 229 | }; |
| 230 | 230 | ||
| 231 | /// First argument in argv is the executable. | 231 | /// First argument in argv is the executable. |
| 232 | pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { | 232 | pub fn init(argv: []const []const u8, allocator: Allocator) Child { |
| 233 | return .{ | 233 | return .{ |
| 234 | .allocator = allocator, | 234 | .allocator = allocator, |
| 235 | .argv = argv, | 235 | .argv = argv, |
| ... | @@ -252,7 +252,7 @@ pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { | ... | @@ -252,7 +252,7 @@ pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { |
| 252 | }; | 252 | }; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | pub fn setUserName(self: *ChildProcess, name: []const u8) !void { | 255 | pub fn setUserName(self: *Child, name: []const u8) !void { |
| 256 | const user_info = try process.getUserInfo(name); | 256 | const user_info = try process.getUserInfo(name); |
| 257 | self.uid = user_info.uid; | 257 | self.uid = user_info.uid; |
| 258 | self.gid = user_info.gid; | 258 | self.gid = user_info.gid; |
| ... | @@ -260,7 +260,7 @@ pub fn setUserName(self: *ChildProcess, name: []const u8) !void { | ... | @@ -260,7 +260,7 @@ pub fn setUserName(self: *ChildProcess, name: []const u8) !void { |
| 260 | 260 | ||
| 261 | /// On success must call `kill` or `wait`. | 261 | /// On success must call `kill` or `wait`. |
| 262 | /// After spawning the `id` is available. | 262 | /// After spawning the `id` is available. |
| 263 | pub fn spawn(self: *ChildProcess) SpawnError!void { | 263 | pub fn spawn(self: *Child, io: Io) SpawnError!void { |
| 264 | if (!process.can_spawn) { | 264 | if (!process.can_spawn) { |
| 265 | @compileError("the target operating system cannot spawn processes"); | 265 | @compileError("the target operating system cannot spawn processes"); |
| 266 | } | 266 | } |
| ... | @@ -268,17 +268,17 @@ pub fn spawn(self: *ChildProcess) SpawnError!void { | ... | @@ -268,17 +268,17 @@ pub fn spawn(self: *ChildProcess) SpawnError!void { |
| 268 | if (native_os == .windows) { | 268 | if (native_os == .windows) { |
| 269 | return self.spawnWindows(); | 269 | return self.spawnWindows(); |
| 270 | } else { | 270 | } else { |
| 271 | return self.spawnPosix(); | 271 | return self.spawnPosix(io); |
| 272 | } | 272 | } |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | pub fn spawnAndWait(self: *ChildProcess) SpawnError!Term { | 275 | pub fn spawnAndWait(child: *Child, io: Io) SpawnError!Term { |
| 276 | try self.spawn(); | 276 | try child.spawn(io); |
| 277 | return self.wait(); | 277 | return child.wait(io); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | /// Forcibly terminates child process and then cleans up all resources. | 280 | /// Forcibly terminates child process and then cleans up all resources. |
| 281 | pub fn kill(self: *ChildProcess, io: Io) !Term { | 281 | pub fn kill(self: *Child, io: Io) !Term { |
| 282 | if (native_os == .windows) { | 282 | if (native_os == .windows) { |
| 283 | return self.killWindows(io, 1); | 283 | return self.killWindows(io, 1); |
| 284 | } else { | 284 | } else { |
| ... | @@ -286,7 +286,7 @@ pub fn kill(self: *ChildProcess, io: Io) !Term { | ... | @@ -286,7 +286,7 @@ pub fn kill(self: *ChildProcess, io: Io) !Term { |
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | pub fn killWindows(self: *ChildProcess, io: Io, exit_code: windows.UINT) !Term { | 289 | pub fn killWindows(self: *Child, io: Io, exit_code: windows.UINT) !Term { |
| 290 | if (self.term) |term| { | 290 | if (self.term) |term| { |
| 291 | self.cleanupStreams(io); | 291 | self.cleanupStreams(io); |
| 292 | return term; | 292 | return term; |
| ... | @@ -308,7 +308,7 @@ pub fn killWindows(self: *ChildProcess, io: Io, exit_code: windows.UINT) !Term { | ... | @@ -308,7 +308,7 @@ pub fn killWindows(self: *ChildProcess, io: Io, exit_code: windows.UINT) !Term { |
| 308 | return self.term.?; | 308 | return self.term.?; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | pub fn killPosix(self: *ChildProcess, io: Io) !Term { | 311 | pub fn killPosix(self: *Child, io: Io) !Term { |
| 312 | if (self.term) |term| { | 312 | if (self.term) |term| { |
| 313 | self.cleanupStreams(io); | 313 | self.cleanupStreams(io); |
| 314 | return term; | 314 | return term; |
| ... | @@ -325,7 +325,7 @@ pub const WaitError = SpawnError || std.os.windows.GetProcessMemoryInfoError; | ... | @@ -325,7 +325,7 @@ pub const WaitError = SpawnError || std.os.windows.GetProcessMemoryInfoError; |
| 325 | 325 | ||
| 326 | /// On some targets, `spawn` may not report all spawn errors, such as `error.InvalidExe`. | 326 | /// On some targets, `spawn` may not report all spawn errors, such as `error.InvalidExe`. |
| 327 | /// This function will block until any spawn errors can be reported, and return them. | 327 | /// This function will block until any spawn errors can be reported, and return them. |
| 328 | pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { | 328 | pub fn waitForSpawn(self: *Child) SpawnError!void { |
| 329 | if (native_os == .windows) return; // `spawn` reports everything | 329 | if (native_os == .windows) return; // `spawn` reports everything |
| 330 | if (self.term) |term| { | 330 | if (self.term) |term| { |
| 331 | _ = term catch |spawn_err| return spawn_err; | 331 | _ = term catch |spawn_err| return spawn_err; |
| ... | @@ -355,7 +355,7 @@ pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { | ... | @@ -355,7 +355,7 @@ pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | /// Blocks until child process terminates and then cleans up all resources. | 357 | /// Blocks until child process terminates and then cleans up all resources. |
| 358 | pub fn wait(self: *ChildProcess, io: Io) WaitError!Term { | 358 | pub fn wait(self: *Child, io: Io) WaitError!Term { |
| 359 | try self.waitForSpawn(); // report spawn errors | 359 | try self.waitForSpawn(); // report spawn errors |
| 360 | if (self.term) |term| { | 360 | if (self.term) |term| { |
| 361 | self.cleanupStreams(io); | 361 | self.cleanupStreams(io); |
| ... | @@ -381,7 +381,7 @@ pub const RunResult = struct { | ... | @@ -381,7 +381,7 @@ pub const RunResult = struct { |
| 381 | /// | 381 | /// |
| 382 | /// The process must be started with stdout_behavior and stderr_behavior == .Pipe | 382 | /// The process must be started with stdout_behavior and stderr_behavior == .Pipe |
| 383 | pub fn collectOutput( | 383 | pub fn collectOutput( |
| 384 | child: ChildProcess, | 384 | child: Child, |
| 385 | /// Used for `stdout` and `stderr`. | 385 | /// Used for `stdout` and `stderr`. |
| 386 | allocator: Allocator, | 386 | allocator: Allocator, |
| 387 | stdout: *ArrayList(u8), | 387 | stdout: *ArrayList(u8), |
| ... | @@ -446,7 +446,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { | ... | @@ -446,7 +446,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { |
| 446 | expand_arg0: Arg0Expand = .no_expand, | 446 | expand_arg0: Arg0Expand = .no_expand, |
| 447 | progress_node: std.Progress.Node = std.Progress.Node.none, | 447 | progress_node: std.Progress.Node = std.Progress.Node.none, |
| 448 | }) RunError!RunResult { | 448 | }) RunError!RunResult { |
| 449 | var child = ChildProcess.init(args.argv, allocator); | 449 | var child = Child.init(args.argv, allocator); |
| 450 | child.stdin_behavior = .Ignore; | 450 | child.stdin_behavior = .Ignore; |
| 451 | child.stdout_behavior = .Pipe; | 451 | child.stdout_behavior = .Pipe; |
| 452 | child.stderr_behavior = .Pipe; | 452 | child.stderr_behavior = .Pipe; |
| ... | @@ -461,7 +461,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { | ... | @@ -461,7 +461,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { |
| 461 | var stderr: ArrayList(u8) = .empty; | 461 | var stderr: ArrayList(u8) = .empty; |
| 462 | defer stderr.deinit(allocator); | 462 | defer stderr.deinit(allocator); |
| 463 | 463 | ||
| 464 | try child.spawn(); | 464 | try child.spawn(io); |
| 465 | errdefer { | 465 | errdefer { |
| 466 | _ = child.kill(io) catch {}; | 466 | _ = child.kill(io) catch {}; |
| 467 | } | 467 | } |
| ... | @@ -474,7 +474,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { | ... | @@ -474,7 +474,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { |
| 474 | }; | 474 | }; |
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | fn waitUnwrappedWindows(self: *ChildProcess, io: Io) WaitError!void { | 477 | fn waitUnwrappedWindows(self: *Child, io: Io) WaitError!void { |
| 478 | const result = windows.WaitForSingleObjectEx(self.id, windows.INFINITE, false); | 478 | const result = windows.WaitForSingleObjectEx(self.id, windows.INFINITE, false); |
| 479 | 479 | ||
| 480 | self.term = @as(SpawnError!Term, x: { | 480 | self.term = @as(SpawnError!Term, x: { |
| ... | @@ -496,7 +496,7 @@ fn waitUnwrappedWindows(self: *ChildProcess, io: Io) WaitError!void { | ... | @@ -496,7 +496,7 @@ fn waitUnwrappedWindows(self: *ChildProcess, io: Io) WaitError!void { |
| 496 | return result; | 496 | return result; |
| 497 | } | 497 | } |
| 498 | 498 | ||
| 499 | fn waitUnwrappedPosix(self: *ChildProcess, io: Io) void { | 499 | fn waitUnwrappedPosix(self: *Child, io: Io) void { |
| 500 | const res: posix.WaitPidResult = res: { | 500 | const res: posix.WaitPidResult = res: { |
| 501 | if (self.request_resource_usage_statistics) { | 501 | if (self.request_resource_usage_statistics) { |
| 502 | switch (native_os) { | 502 | switch (native_os) { |
| ... | @@ -531,11 +531,11 @@ fn waitUnwrappedPosix(self: *ChildProcess, io: Io) void { | ... | @@ -531,11 +531,11 @@ fn waitUnwrappedPosix(self: *ChildProcess, io: Io) void { |
| 531 | self.handleWaitResult(status); | 531 | self.handleWaitResult(status); |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | fn handleWaitResult(self: *ChildProcess, status: u32) void { | 534 | fn handleWaitResult(self: *Child, status: u32) void { |
| 535 | self.term = statusToTerm(status); | 535 | self.term = statusToTerm(status); |
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | fn cleanupStreams(self: *ChildProcess, io: Io) void { | 538 | fn cleanupStreams(self: *Child, io: Io) void { |
| 539 | if (self.stdin) |*stdin| { | 539 | if (self.stdin) |*stdin| { |
| 540 | stdin.close(io); | 540 | stdin.close(io); |
| 541 | self.stdin = null; | 541 | self.stdin = null; |
| ... | @@ -561,7 +561,7 @@ fn statusToTerm(status: u32) Term { | ... | @@ -561,7 +561,7 @@ fn statusToTerm(status: u32) Term { |
| 561 | Term{ .Unknown = status }; | 561 | Term{ .Unknown = status }; |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | fn spawnPosix(self: *ChildProcess) SpawnError!void { | 564 | fn spawnPosix(self: *Child, io: Io) SpawnError!void { |
| 565 | // The child process does need to access (one end of) these pipes. However, | 565 | // The child process does need to access (one end of) these pipes. However, |
| 566 | // we must initially set CLOEXEC to avoid a race condition. If another thread | 566 | // we must initially set CLOEXEC to avoid a race condition. If another thread |
| 567 | // is racing to spawn a different child process, we don't want it to inherit | 567 | // is racing to spawn a different child process, we don't want it to inherit |
| ... | @@ -659,7 +659,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { | ... | @@ -659,7 +659,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { |
| 659 | })).ptr; | 659 | })).ptr; |
| 660 | } else { | 660 | } else { |
| 661 | // TODO come up with a solution for this. | 661 | // TODO come up with a solution for this. |
| 662 | @panic("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process"); | 662 | @panic("missing std lib enhancement: std.process.Child implementation has no way to collect the environment variables to forward to the child process"); |
| 663 | } | 663 | } |
| 664 | }; | 664 | }; |
| 665 | 665 | ||
| ... | @@ -671,41 +671,41 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { | ... | @@ -671,41 +671,41 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { |
| 671 | const pid_result = try posix.fork(); | 671 | const pid_result = try posix.fork(); |
| 672 | if (pid_result == 0) { | 672 | if (pid_result == 0) { |
| 673 | // we are the child | 673 | // we are the child |
| 674 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); | 674 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 675 | setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); | 675 | setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 676 | setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); | 676 | setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 677 | 677 | ||
| 678 | if (self.cwd_dir) |cwd| { | 678 | if (self.cwd_dir) |cwd| { |
| 679 | posix.fchdir(cwd.handle) catch |err| forkChildErrReport(err_pipe[1], err); | 679 | posix.fchdir(cwd.handle) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 680 | } else if (self.cwd) |cwd| { | 680 | } else if (self.cwd) |cwd| { |
| 681 | posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err); | 681 | posix.chdir(cwd) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | // Must happen after fchdir above, the cwd file descriptor might be | 684 | // Must happen after fchdir above, the cwd file descriptor might be |
| 685 | // equal to prog_fileno and be clobbered by this dup2 call. | 685 | // equal to prog_fileno and be clobbered by this dup2 call. |
| 686 | if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(err_pipe[1], err); | 686 | if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 687 | 687 | ||
| 688 | if (self.gid) |gid| { | 688 | if (self.gid) |gid| { |
| 689 | posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err); | 689 | posix.setregid(gid, gid) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 690 | } | 690 | } |
| 691 | 691 | ||
| 692 | if (self.uid) |uid| { | 692 | if (self.uid) |uid| { |
| 693 | posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err); | 693 | posix.setreuid(uid, uid) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | if (self.pgid) |pid| { | 696 | if (self.pgid) |pid| { |
| 697 | posix.setpgid(0, pid) catch |err| forkChildErrReport(err_pipe[1], err); | 697 | posix.setpgid(0, pid) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 698 | } | 698 | } |
| 699 | 699 | ||
| 700 | if (self.start_suspended) { | 700 | if (self.start_suspended) { |
| 701 | posix.kill(posix.getpid(), .STOP) catch |err| forkChildErrReport(err_pipe[1], err); | 701 | posix.kill(posix.getpid(), .STOP) catch |err| forkChildErrReport(io, err_pipe[1], err); |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | const err = switch (self.expand_arg0) { | 704 | const err = switch (self.expand_arg0) { |
| 705 | .expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), | 705 | .expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), |
| 706 | .no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), | 706 | .no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), |
| 707 | }; | 707 | }; |
| 708 | forkChildErrReport(err_pipe[1], err); | 708 | forkChildErrReport(io, err_pipe[1], err); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | // we are the parent | 711 | // we are the parent |
| ... | @@ -750,7 +750,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { | ... | @@ -750,7 +750,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { |
| 750 | self.progress_node.setIpcFd(prog_pipe[0]); | 750 | self.progress_node.setIpcFd(prog_pipe[0]); |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | fn spawnWindows(self: *ChildProcess) SpawnError!void { | 753 | fn spawnWindows(self: *Child) SpawnError!void { |
| 754 | var saAttr = windows.SECURITY_ATTRIBUTES{ | 754 | var saAttr = windows.SECURITY_ATTRIBUTES{ |
| 755 | .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES), | 755 | .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES), |
| 756 | .bInheritHandle = windows.TRUE, | 756 | .bInheritHandle = windows.TRUE, |
| ... | @@ -880,7 +880,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void { | ... | @@ -880,7 +880,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void { |
| 880 | const app_name_wtf8 = self.argv[0]; | 880 | const app_name_wtf8 = self.argv[0]; |
| 881 | const app_name_is_absolute = fs.path.isAbsolute(app_name_wtf8); | 881 | const app_name_is_absolute = fs.path.isAbsolute(app_name_wtf8); |
| 882 | 882 | ||
| 883 | // the cwd set in ChildProcess is in effect when choosing the executable path | 883 | // the cwd set in Child is in effect when choosing the executable path |
| 884 | // to match posix semantics | 884 | // to match posix semantics |
| 885 | var cwd_path_w_needs_free = false; | 885 | var cwd_path_w_needs_free = false; |
| 886 | const cwd_path_w = x: { | 886 | const cwd_path_w = x: { |
| ... | @@ -965,7 +965,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void { | ... | @@ -965,7 +965,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void { |
| 965 | // If the app name had path separators, that disallows PATH searching, | 965 | // If the app name had path separators, that disallows PATH searching, |
| 966 | // and there's no need to search the PATH if the app name is absolute. | 966 | // and there's no need to search the PATH if the app name is absolute. |
| 967 | // We still search the path if the cwd is absolute because of the | 967 | // We still search the path if the cwd is absolute because of the |
| 968 | // "cwd set in ChildProcess is in effect when choosing the executable path | 968 | // "cwd set in Child is in effect when choosing the executable path |
| 969 | // to match posix semantics" behavior--we don't want to skip searching | 969 | // to match posix semantics" behavior--we don't want to skip searching |
| 970 | // the PATH just because we were trying to set the cwd of the child process. | 970 | // the PATH just because we were trying to set the cwd of the child process. |
| 971 | if (app_dirname_w != null or app_name_is_absolute) { | 971 | if (app_dirname_w != null or app_name_is_absolute) { |
| ... | @@ -1039,8 +1039,8 @@ fn destroyPipe(pipe: [2]posix.fd_t) void { | ... | @@ -1039,8 +1039,8 @@ fn destroyPipe(pipe: [2]posix.fd_t) void { |
| 1039 | 1039 | ||
| 1040 | // Child of fork calls this to report an error to the fork parent. | 1040 | // Child of fork calls this to report an error to the fork parent. |
| 1041 | // Then the child exits. | 1041 | // Then the child exits. |
| 1042 | fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { | 1042 | fn forkChildErrReport(io: Io, fd: i32, err: Child.SpawnError) noreturn { |
| 1043 | writeIntFd(fd, @as(ErrInt, @intFromError(err))) catch {}; | 1043 | writeIntFd(io, fd, @as(ErrInt, @intFromError(err))) catch {}; |
| 1044 | // If we're linking libc, some naughty applications may have registered atexit handlers | 1044 | // If we're linking libc, some naughty applications may have registered atexit handlers |
| 1045 | // which we really do not want to run in the fork child. I caught LLVM doing this and | 1045 | // which we really do not want to run in the fork child. I caught LLVM doing this and |
| 1046 | // it caused a deadlock instead of doing an exit syscall. In the words of Avril Lavigne, | 1046 | // it caused a deadlock instead of doing an exit syscall. In the words of Avril Lavigne, |
| ... | @@ -1052,9 +1052,9 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { | ... | @@ -1052,9 +1052,9 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { |
| 1052 | posix.system.exit(1); | 1052 | posix.system.exit(1); |
| 1053 | } | 1053 | } |
| 1054 | 1054 | ||
| 1055 | fn writeIntFd(fd: i32, value: ErrInt) !void { | 1055 | fn writeIntFd(io: Io, fd: i32, value: ErrInt) !void { |
| 1056 | var buffer: [8]u8 = undefined; | 1056 | var buffer: [8]u8 = undefined; |
| 1057 | var fw: File.Writer = .initStreaming(.{ .handle = fd }, &buffer); | 1057 | var fw: File.Writer = .initStreaming(.{ .handle = fd }, io, &buffer); |
| 1058 | fw.interface.writeInt(u64, value, .little) catch unreachable; | 1058 | fw.interface.writeInt(u64, value, .little) catch unreachable; |
| 1059 | fw.interface.flush() catch return error.SystemResources; | 1059 | fw.interface.flush() catch return error.SystemResources; |
| 1060 | } | 1060 | } |
| ... | @@ -1078,7 +1078,7 @@ const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); | ... | @@ -1078,7 +1078,7 @@ const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); |
| 1078 | /// Note: `app_buf` should not contain any leading path separators. | 1078 | /// Note: `app_buf` should not contain any leading path separators. |
| 1079 | /// Note: If the dir is the cwd, dir_buf should be empty (len = 0). | 1079 | /// Note: If the dir is the cwd, dir_buf should be empty (len = 0). |
| 1080 | fn windowsCreateProcessPathExt( | 1080 | fn windowsCreateProcessPathExt( |
| 1081 | allocator: mem.Allocator, | 1081 | allocator: Allocator, |
| 1082 | dir_buf: *ArrayList(u16), | 1082 | dir_buf: *ArrayList(u16), |
| 1083 | app_buf: *ArrayList(u16), | 1083 | app_buf: *ArrayList(u16), |
| 1084 | pathext: [:0]const u16, | 1084 | pathext: [:0]const u16, |
| ... | @@ -1525,9 +1525,9 @@ const WindowsCommandLineCache = struct { | ... | @@ -1525,9 +1525,9 @@ const WindowsCommandLineCache = struct { |
| 1525 | script_cmd_line: ?[:0]u16 = null, | 1525 | script_cmd_line: ?[:0]u16 = null, |
| 1526 | cmd_exe_path: ?[:0]u16 = null, | 1526 | cmd_exe_path: ?[:0]u16 = null, |
| 1527 | argv: []const []const u8, | 1527 | argv: []const []const u8, |
| 1528 | allocator: mem.Allocator, | 1528 | allocator: Allocator, |
| 1529 | 1529 | ||
| 1530 | fn init(allocator: mem.Allocator, argv: []const []const u8) WindowsCommandLineCache { | 1530 | fn init(allocator: Allocator, argv: []const []const u8) WindowsCommandLineCache { |
| 1531 | return .{ | 1531 | return .{ |
| 1532 | .allocator = allocator, | 1532 | .allocator = allocator, |
| 1533 | .argv = argv, | 1533 | .argv = argv, |
| ... | @@ -1571,7 +1571,7 @@ const WindowsCommandLineCache = struct { | ... | @@ -1571,7 +1571,7 @@ const WindowsCommandLineCache = struct { |
| 1571 | 1571 | ||
| 1572 | /// Returns the absolute path of `cmd.exe` within the Windows system directory. | 1572 | /// Returns the absolute path of `cmd.exe` within the Windows system directory. |
| 1573 | /// The caller owns the returned slice. | 1573 | /// The caller owns the returned slice. |
| 1574 | fn windowsCmdExePath(allocator: mem.Allocator) error{ OutOfMemory, Unexpected }![:0]u16 { | 1574 | fn windowsCmdExePath(allocator: Allocator) error{ OutOfMemory, Unexpected }![:0]u16 { |
| 1575 | var buf = try ArrayList(u16).initCapacity(allocator, 128); | 1575 | var buf = try ArrayList(u16).initCapacity(allocator, 128); |
| 1576 | errdefer buf.deinit(allocator); | 1576 | errdefer buf.deinit(allocator); |
| 1577 | while (true) { | 1577 | while (true) { |
| ... | @@ -1608,7 +1608,7 @@ const ArgvToCommandLineError = error{ OutOfMemory, InvalidWtf8, InvalidArg0 }; | ... | @@ -1608,7 +1608,7 @@ const ArgvToCommandLineError = error{ OutOfMemory, InvalidWtf8, InvalidArg0 }; |
| 1608 | /// | 1608 | /// |
| 1609 | /// When executing `.bat`/`.cmd` scripts, use `argvToScriptCommandLineWindows` instead. | 1609 | /// When executing `.bat`/`.cmd` scripts, use `argvToScriptCommandLineWindows` instead. |
| 1610 | fn argvToCommandLineWindows( | 1610 | fn argvToCommandLineWindows( |
| 1611 | allocator: mem.Allocator, | 1611 | allocator: Allocator, |
| 1612 | argv: []const []const u8, | 1612 | argv: []const []const u8, |
| 1613 | ) ArgvToCommandLineError![:0]u16 { | 1613 | ) ArgvToCommandLineError![:0]u16 { |
| 1614 | var buf = std.array_list.Managed(u8).init(allocator); | 1614 | var buf = std.array_list.Managed(u8).init(allocator); |
| ... | @@ -1784,7 +1784,7 @@ const ArgvToScriptCommandLineError = error{ | ... | @@ -1784,7 +1784,7 @@ const ArgvToScriptCommandLineError = error{ |
| 1784 | /// Should only be used when spawning `.bat`/`.cmd` scripts, see `argvToCommandLineWindows` otherwise. | 1784 | /// Should only be used when spawning `.bat`/`.cmd` scripts, see `argvToCommandLineWindows` otherwise. |
| 1785 | /// The `.bat`/`.cmd` file must be known to both have the `.bat`/`.cmd` extension and exist on the filesystem. | 1785 | /// The `.bat`/`.cmd` file must be known to both have the `.bat`/`.cmd` extension and exist on the filesystem. |
| 1786 | fn argvToScriptCommandLineWindows( | 1786 | fn argvToScriptCommandLineWindows( |
| 1787 | allocator: mem.Allocator, | 1787 | allocator: Allocator, |
| 1788 | /// Path to the `.bat`/`.cmd` script. If this path is relative, it is assumed to be relative to the CWD. | 1788 | /// Path to the `.bat`/`.cmd` script. If this path is relative, it is assumed to be relative to the CWD. |
| 1789 | /// The script must have been verified to exist at this path before calling this function. | 1789 | /// The script must have been verified to exist at this path before calling this function. |
| 1790 | script_path: []const u16, | 1790 | script_path: []const u16, |
lib/std/tar.zig+18-18| ... | @@ -610,7 +610,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp | ... | @@ -610,7 +610,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp |
| 610 | } | 610 | } |
| 611 | }, | 611 | }, |
| 612 | .file => { | 612 | .file => { |
| 613 | if (createDirAndFile(io, dir, file_name, fileMode(file.mode, options))) |fs_file| { | 613 | if (createDirAndFile(io, dir, file_name, filePermissions(file.mode, options))) |fs_file| { |
| 614 | defer fs_file.close(io); | 614 | defer fs_file.close(io); |
| 615 | var file_writer = fs_file.writer(io, &file_contents_buffer); | 615 | var file_writer = fs_file.writer(io, &file_contents_buffer); |
| 616 | try it.streamRemaining(file, &file_writer.interface); | 616 | try it.streamRemaining(file, &file_writer.interface); |
| ... | @@ -638,12 +638,12 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp | ... | @@ -638,12 +638,12 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp |
| 638 | } | 638 | } |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { | 641 | fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, permissions: Io.File.Permissions) !Io.File { |
| 642 | const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }) catch |err| { | 642 | const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .permissions = permissions }) catch |err| { |
| 643 | if (err == error.FileNotFound) { | 643 | if (err == error.FileNotFound) { |
| 644 | if (std.fs.path.dirname(file_name)) |dir_name| { | 644 | if (std.fs.path.dirname(file_name)) |dir_name| { |
| 645 | try dir.makePath(io, dir_name); | 645 | try dir.makePath(io, dir_name); |
| 646 | return try dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }); | 646 | return try dir.createFile(io, file_name, .{ .exclusive = true, .permissions = permissions }); |
| 647 | } | 647 | } |
| 648 | } | 648 | } |
| 649 | return err; | 649 | return err; |
| ... | @@ -880,9 +880,9 @@ test "create file and symlink" { | ... | @@ -880,9 +880,9 @@ test "create file and symlink" { |
| 880 | var root = testing.tmpDir(.{}); | 880 | var root = testing.tmpDir(.{}); |
| 881 | defer root.cleanup(); | 881 | defer root.cleanup(); |
| 882 | 882 | ||
| 883 | var file = try createDirAndFile(io, root.dir, "file1", default_mode); | 883 | var file = try createDirAndFile(io, root.dir, "file1", .default_file); |
| 884 | file.close(io); | 884 | file.close(io); |
| 885 | file = try createDirAndFile(io, root.dir, "a/b/c/file2", default_mode); | 885 | file = try createDirAndFile(io, root.dir, "a/b/c/file2", .default_file); |
| 886 | file.close(io); | 886 | file.close(io); |
| 887 | 887 | ||
| 888 | createDirAndSymlink(io, root.dir, "a/b/c/file2", "symlink1") catch |err| { | 888 | createDirAndSymlink(io, root.dir, "a/b/c/file2", "symlink1") catch |err| { |
| ... | @@ -894,7 +894,7 @@ test "create file and symlink" { | ... | @@ -894,7 +894,7 @@ test "create file and symlink" { |
| 894 | 894 | ||
| 895 | // Danglink symlnik, file created later | 895 | // Danglink symlnik, file created later |
| 896 | try createDirAndSymlink(io, root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); | 896 | try createDirAndSymlink(io, root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); |
| 897 | file = try createDirAndFile(io, root.dir, "g/h/i/file4", default_mode); | 897 | file = try createDirAndFile(io, root.dir, "g/h/i/file4", .default_file); |
| 898 | file.close(io); | 898 | file.close(io); |
| 899 | } | 899 | } |
| 900 | 900 | ||
| ... | @@ -1118,30 +1118,30 @@ fn normalizePath(bytes: []u8) []u8 { | ... | @@ -1118,30 +1118,30 @@ fn normalizePath(bytes: []u8) []u8 { |
| 1118 | return bytes; | 1118 | return bytes; |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | const default_mode = Io.File.default_mode; | ||
| 1122 | |||
| 1123 | // File system mode based on tar header mode and mode_mode options. | 1121 | // File system mode based on tar header mode and mode_mode options. |
| 1124 | fn fileMode(mode: u32, options: PipeOptions) Io.File.Mode { | 1122 | fn filePermissions(mode: u32, options: PipeOptions) Io.File.Permissions { |
| 1123 | const default_mode = 0o666; | ||
| 1124 | |||
| 1125 | if (!std.fs.has_executable_bit or options.mode_mode == .ignore) | 1125 | if (!std.fs.has_executable_bit or options.mode_mode == .ignore) |
| 1126 | return default_mode; | 1126 | return .fromMode(default_mode); |
| 1127 | 1127 | ||
| 1128 | const S = std.posix.S; | 1128 | const S = std.posix.S; |
| 1129 | 1129 | ||
| 1130 | // The mode from the tar file is inspected for the owner executable bit. | 1130 | // The mode from the tar file is inspected for the owner executable bit. |
| 1131 | if (mode & S.IXUSR == 0) | 1131 | if (mode & S.IXUSR == 0) |
| 1132 | return default_mode; | 1132 | return .fromMode(default_mode); |
| 1133 | 1133 | ||
| 1134 | // This bit is copied to the group and other executable bits. | 1134 | // This bit is copied to the group and other executable bits. |
| 1135 | // Other bits of the mode are left as the default when creating files. | 1135 | // Other bits of the mode are left as the default when creating files. |
| 1136 | return default_mode | S.IXUSR | S.IXGRP | S.IXOTH; | 1136 | return .fromMode(default_mode | S.IXUSR | S.IXGRP | S.IXOTH); |
| 1137 | } | 1137 | } |
| 1138 | 1138 | ||
| 1139 | test fileMode { | 1139 | test filePermissions { |
| 1140 | if (!std.fs.has_executable_bit) return error.SkipZigTest; | 1140 | if (!std.fs.has_executable_bit) return error.SkipZigTest; |
| 1141 | try testing.expectEqual(default_mode, fileMode(0o744, PipeOptions{ .mode_mode = .ignore })); | 1141 | try testing.expectEqual(0o666, filePermissions(0o744, PipeOptions{ .mode_mode = .ignore })); |
| 1142 | try testing.expectEqual(0o777, fileMode(0o744, PipeOptions{})); | 1142 | try testing.expectEqual(0o777, filePermissions(0o744, PipeOptions{})); |
| 1143 | try testing.expectEqual(0o666, fileMode(0o644, PipeOptions{})); | 1143 | try testing.expectEqual(0o666, filePermissions(0o644, PipeOptions{})); |
| 1144 | try testing.expectEqual(0o666, fileMode(0o655, PipeOptions{})); | 1144 | try testing.expectEqual(0o666, filePermissions(0o655, PipeOptions{})); |
| 1145 | } | 1145 | } |
| 1146 | 1146 | ||
| 1147 | test "executable bit" { | 1147 | test "executable bit" { |
src/Compilation.zig+8-7| ... | @@ -5782,7 +5782,7 @@ pub fn translateC( | ... | @@ -5782,7 +5782,7 @@ pub fn translateC( |
| 5782 | } | 5782 | } |
| 5783 | 5783 | ||
| 5784 | // Just to save disk space, we delete the file because it is never needed again. | 5784 | // Just to save disk space, we delete the file because it is never needed again. |
| 5785 | cache_tmp_dir.deleteFile(dep_basename) catch |err| { | 5785 | cache_tmp_dir.deleteFile(io, dep_basename) catch |err| { |
| 5786 | log.warn("failed to delete '{s}': {t}", .{ dep_file_path, err }); | 5786 | log.warn("failed to delete '{s}': {t}", .{ dep_file_path, err }); |
| 5787 | }; | 5787 | }; |
| 5788 | } | 5788 | } |
| ... | @@ -6314,11 +6314,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -6314,11 +6314,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 6314 | } | 6314 | } |
| 6315 | 6315 | ||
| 6316 | // Just to save disk space, we delete the files that are never needed again. | 6316 | // Just to save disk space, we delete the files that are never needed again. |
| 6317 | defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(fs.path.basename(diag_file_path)) catch |err| switch (err) { | 6317 | defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(diag_file_path)) catch |err| switch (err) { |
| 6318 | error.FileNotFound => {}, // the file wasn't created due to an error we reported | 6318 | error.FileNotFound => {}, // the file wasn't created due to an error we reported |
| 6319 | else => log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) }), | 6319 | else => log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) }), |
| 6320 | }; | 6320 | }; |
| 6321 | defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(fs.path.basename(dep_file_path)) catch |err| switch (err) { | 6321 | defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(dep_file_path)) catch |err| switch (err) { |
| 6322 | error.FileNotFound => {}, // the file wasn't created due to an error we reported | 6322 | error.FileNotFound => {}, // the file wasn't created due to an error we reported |
| 6323 | else => log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }), | 6323 | else => log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }), |
| 6324 | }; | 6324 | }; |
| ... | @@ -6329,7 +6329,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -6329,7 +6329,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 6329 | child.stdout_behavior = .Inherit; | 6329 | child.stdout_behavior = .Inherit; |
| 6330 | child.stderr_behavior = .Inherit; | 6330 | child.stderr_behavior = .Inherit; |
| 6331 | 6331 | ||
| 6332 | const term = child.spawnAndWait() catch |err| { | 6332 | const term = child.spawnAndWait(io) catch |err| { |
| 6333 | return comp.failCObj(c_object, "failed to spawn zig clang (passthrough mode) {s}: {s}", .{ argv.items[0], @errorName(err) }); | 6333 | return comp.failCObj(c_object, "failed to spawn zig clang (passthrough mode) {s}: {s}", .{ argv.items[0], @errorName(err) }); |
| 6334 | }; | 6334 | }; |
| 6335 | switch (term) { | 6335 | switch (term) { |
| ... | @@ -6347,7 +6347,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -6347,7 +6347,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 6347 | child.stdout_behavior = .Ignore; | 6347 | child.stdout_behavior = .Ignore; |
| 6348 | child.stderr_behavior = .Pipe; | 6348 | child.stderr_behavior = .Pipe; |
| 6349 | 6349 | ||
| 6350 | try child.spawn(); | 6350 | try child.spawn(io); |
| 6351 | 6351 | ||
| 6352 | var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); | 6352 | var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); |
| 6353 | const stderr = try stderr_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32))); | 6353 | const stderr = try stderr_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32))); |
| ... | @@ -6723,6 +6723,7 @@ fn spawnZigRc( | ... | @@ -6723,6 +6723,7 @@ fn spawnZigRc( |
| 6723 | argv: []const []const u8, | 6723 | argv: []const []const u8, |
| 6724 | child_progress_node: std.Progress.Node, | 6724 | child_progress_node: std.Progress.Node, |
| 6725 | ) !void { | 6725 | ) !void { |
| 6726 | const io = comp.io; | ||
| 6726 | var node_name: std.ArrayList(u8) = .empty; | 6727 | var node_name: std.ArrayList(u8) = .empty; |
| 6727 | defer node_name.deinit(arena); | 6728 | defer node_name.deinit(arena); |
| 6728 | 6729 | ||
| ... | @@ -6732,8 +6733,8 @@ fn spawnZigRc( | ... | @@ -6732,8 +6733,8 @@ fn spawnZigRc( |
| 6732 | child.stderr_behavior = .Pipe; | 6733 | child.stderr_behavior = .Pipe; |
| 6733 | child.progress_node = child_progress_node; | 6734 | child.progress_node = child_progress_node; |
| 6734 | 6735 | ||
| 6735 | child.spawn() catch |err| { | 6736 | child.spawn(io) catch |err| { |
| 6736 | return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv[0], @errorName(err) }); | 6737 | return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {t}", .{ argv[0], err }); |
| 6737 | }; | 6738 | }; |
| 6738 | 6739 | ||
| 6739 | var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{ | 6740 | var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{ |
src/Package/Fetch.zig+6-6| ... | @@ -1347,7 +1347,7 @@ fn unzip( | ... | @@ -1347,7 +1347,7 @@ fn unzip( |
| 1347 | .diagnostics = &diagnostics, | 1347 | .diagnostics = &diagnostics, |
| 1348 | }) catch |err| return f.fail(f.location_tok, try eb.printString("zip extract failed: {t}", .{err})); | 1348 | }) catch |err| return f.fail(f.location_tok, try eb.printString("zip extract failed: {t}", .{err})); |
| 1349 | 1349 | ||
| 1350 | cache_root.handle.deleteFile(&zip_path) catch |err| | 1350 | cache_root.handle.deleteFile(io, &zip_path) catch |err| |
| 1351 | return f.fail(f.location_tok, try eb.printString("delete temporary zip failed: {t}", .{err})); | 1351 | return f.fail(f.location_tok, try eb.printString("delete temporary zip failed: {t}", .{err})); |
| 1352 | 1352 | ||
| 1353 | return .{ .root_dir = diagnostics.root_dir }; | 1353 | return .{ .root_dir = diagnostics.root_dir }; |
| ... | @@ -1547,7 +1547,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute | ... | @@ -1547,7 +1547,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute |
| 1547 | .fs_path = fs_path, | 1547 | .fs_path = fs_path, |
| 1548 | .failure = undefined, // to be populated by the worker | 1548 | .failure = undefined, // to be populated by the worker |
| 1549 | }; | 1549 | }; |
| 1550 | group.async(io, workerDeleteFile, .{ root_dir, deleted_file }); | 1550 | group.async(io, workerDeleteFile, .{ io, root_dir, deleted_file }); |
| 1551 | try deleted_files.append(deleted_file); | 1551 | try deleted_files.append(deleted_file); |
| 1552 | continue; | 1552 | continue; |
| 1553 | } | 1553 | } |
| ... | @@ -1669,8 +1669,8 @@ fn workerHashFile(dir: Io.Dir, hashed_file: *HashedFile) void { | ... | @@ -1669,8 +1669,8 @@ fn workerHashFile(dir: Io.Dir, hashed_file: *HashedFile) void { |
| 1669 | hashed_file.failure = hashFileFallible(dir, hashed_file); | 1669 | hashed_file.failure = hashFileFallible(dir, hashed_file); |
| 1670 | } | 1670 | } |
| 1671 | 1671 | ||
| 1672 | fn workerDeleteFile(dir: Io.Dir, deleted_file: *DeletedFile) void { | 1672 | fn workerDeleteFile(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) void { |
| 1673 | deleted_file.failure = deleteFileFallible(dir, deleted_file); | 1673 | deleted_file.failure = deleteFileFallible(io, dir, deleted_file); |
| 1674 | } | 1674 | } |
| 1675 | 1675 | ||
| 1676 | fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Error!void { | 1676 | fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Error!void { |
| ... | @@ -1712,8 +1712,8 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er | ... | @@ -1712,8 +1712,8 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er |
| 1712 | hashed_file.size = file_size; | 1712 | hashed_file.size = file_size; |
| 1713 | } | 1713 | } |
| 1714 | 1714 | ||
| 1715 | fn deleteFileFallible(dir: Io.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void { | 1715 | fn deleteFileFallible(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void { |
| 1716 | try dir.deleteFile(deleted_file.fs_path); | 1716 | try dir.deleteFile(io, deleted_file.fs_path); |
| 1717 | } | 1717 | } |
| 1718 | 1718 | ||
| 1719 | fn setExecutable(file: Io.File) !void { | 1719 | fn setExecutable(file: Io.File) !void { |
src/link.zig+9-5| ... | @@ -1235,22 +1235,26 @@ pub const File = struct { | ... | @@ -1235,22 +1235,26 @@ pub const File = struct { |
| 1235 | ty: InternPool.Index, | 1235 | ty: InternPool.Index, |
| 1236 | }; | 1236 | }; |
| 1237 | 1237 | ||
| 1238 | pub fn determineMode( | 1238 | pub fn determinePermissions( |
| 1239 | output_mode: std.builtin.OutputMode, | 1239 | output_mode: std.builtin.OutputMode, |
| 1240 | link_mode: std.builtin.LinkMode, | 1240 | link_mode: std.builtin.LinkMode, |
| 1241 | ) Io.File.Mode { | 1241 | ) Io.File.Permissions { |
| 1242 | // On common systems with a 0o022 umask, 0o777 will still result in a file created | 1242 | // On common systems with a 0o022 umask, 0o777 will still result in a file created |
| 1243 | // with 0o755 permissions, but it works appropriately if the system is configured | 1243 | // with 0o755 permissions, but it works appropriately if the system is configured |
| 1244 | // more leniently. As another data point, C's fopen seems to open files with the | 1244 | // more leniently. As another data point, C's fopen seems to open files with the |
| 1245 | // 666 mode. | 1245 | // 666 mode. |
| 1246 | const executable_mode = if (builtin.target.os.tag == .windows) 0 else 0o777; | 1246 | const executable_mode: Io.FilePermissions = if (builtin.target.os.tag == .windows) |
| 1247 | .default_file | ||
| 1248 | else | ||
| 1249 | .fromMode(0o777); | ||
| 1250 | |||
| 1247 | switch (output_mode) { | 1251 | switch (output_mode) { |
| 1248 | .Lib => return switch (link_mode) { | 1252 | .Lib => return switch (link_mode) { |
| 1249 | .dynamic => executable_mode, | 1253 | .dynamic => executable_mode, |
| 1250 | .static => Io.File.default_mode, | 1254 | .static => .default_file, |
| 1251 | }, | 1255 | }, |
| 1252 | .Exe => return executable_mode, | 1256 | .Exe => return executable_mode, |
| 1253 | .Obj => return Io.File.default_mode, | 1257 | .Obj => return .default_file, |
| 1254 | } | 1258 | } |
| 1255 | } | 1259 | } |
| 1256 | 1260 |
src/link/Lld.zig+4-4| ... | @@ -1608,13 +1608,13 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi | ... | @@ -1608,13 +1608,13 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1608 | child.stdout_behavior = .Inherit; | 1608 | child.stdout_behavior = .Inherit; |
| 1609 | child.stderr_behavior = .Inherit; | 1609 | child.stderr_behavior = .Inherit; |
| 1610 | 1610 | ||
| 1611 | break :term child.spawnAndWait(); | 1611 | break :term child.spawnAndWait(io); |
| 1612 | } else term: { | 1612 | } else term: { |
| 1613 | child.stdin_behavior = .Ignore; | 1613 | child.stdin_behavior = .Ignore; |
| 1614 | child.stdout_behavior = .Ignore; | 1614 | child.stdout_behavior = .Ignore; |
| 1615 | child.stderr_behavior = .Pipe; | 1615 | child.stderr_behavior = .Pipe; |
| 1616 | 1616 | ||
| 1617 | child.spawn() catch |err| break :term err; | 1617 | child.spawn(io) catch |err| break :term err; |
| 1618 | var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); | 1618 | var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); |
| 1619 | stderr = try stderr_reader.interface.allocRemaining(comp.gpa, .unlimited); | 1619 | stderr = try stderr_reader.interface.allocRemaining(comp.gpa, .unlimited); |
| 1620 | break :term child.wait(); | 1620 | break :term child.wait(); |
| ... | @@ -1658,13 +1658,13 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi | ... | @@ -1658,13 +1658,13 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1658 | rsp_child.stdout_behavior = .Inherit; | 1658 | rsp_child.stdout_behavior = .Inherit; |
| 1659 | rsp_child.stderr_behavior = .Inherit; | 1659 | rsp_child.stderr_behavior = .Inherit; |
| 1660 | 1660 | ||
| 1661 | break :term rsp_child.spawnAndWait() catch |err| break :err err; | 1661 | break :term rsp_child.spawnAndWait(io) catch |err| break :err err; |
| 1662 | } else { | 1662 | } else { |
| 1663 | rsp_child.stdin_behavior = .Ignore; | 1663 | rsp_child.stdin_behavior = .Ignore; |
| 1664 | rsp_child.stdout_behavior = .Ignore; | 1664 | rsp_child.stdout_behavior = .Ignore; |
| 1665 | rsp_child.stderr_behavior = .Pipe; | 1665 | rsp_child.stderr_behavior = .Pipe; |
| 1666 | 1666 | ||
| 1667 | rsp_child.spawn() catch |err| break :err err; | 1667 | rsp_child.spawn(io) catch |err| break :err err; |
| 1668 | var stderr_reader = rsp_child.stderr.?.readerStreaming(io, &.{}); | 1668 | var stderr_reader = rsp_child.stderr.?.readerStreaming(io, &.{}); |
| 1669 | stderr = try stderr_reader.interface.allocRemaining(comp.gpa, .unlimited); | 1669 | stderr = try stderr_reader.interface.allocRemaining(comp.gpa, .unlimited); |
| 1670 | break :term rsp_child.wait() catch |err| break :err err; | 1670 | break :term rsp_child.wait() catch |err| break :err err; |
src/main.zig+7-6| ... | @@ -4457,7 +4457,7 @@ fn runOrTest( | ... | @@ -4457,7 +4457,7 @@ fn runOrTest( |
| 4457 | const term_result = t: { | 4457 | const term_result = t: { |
| 4458 | std.debug.lockStdErr(); | 4458 | std.debug.lockStdErr(); |
| 4459 | defer std.debug.unlockStdErr(); | 4459 | defer std.debug.unlockStdErr(); |
| 4460 | break :t child.spawnAndWait(); | 4460 | break :t child.spawnAndWait(io); |
| 4461 | }; | 4461 | }; |
| 4462 | const term = term_result catch |err| { | 4462 | const term = term_result catch |err| { |
| 4463 | try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); | 4463 | try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); |
| ... | @@ -4512,6 +4512,7 @@ fn runOrTestHotSwap( | ... | @@ -4512,6 +4512,7 @@ fn runOrTestHotSwap( |
| 4512 | all_args: []const []const u8, | 4512 | all_args: []const []const u8, |
| 4513 | runtime_args_start: ?usize, | 4513 | runtime_args_start: ?usize, |
| 4514 | ) !std.process.Child.Id { | 4514 | ) !std.process.Child.Id { |
| 4515 | const io = comp.io; | ||
| 4515 | const lf = comp.bin_file.?; | 4516 | const lf = comp.bin_file.?; |
| 4516 | 4517 | ||
| 4517 | const exe_path = switch (builtin.target.os.tag) { | 4518 | const exe_path = switch (builtin.target.os.tag) { |
| ... | @@ -4593,7 +4594,7 @@ fn runOrTestHotSwap( | ... | @@ -4593,7 +4594,7 @@ fn runOrTestHotSwap( |
| 4593 | child.stdout_behavior = .Inherit; | 4594 | child.stdout_behavior = .Inherit; |
| 4594 | child.stderr_behavior = .Inherit; | 4595 | child.stderr_behavior = .Inherit; |
| 4595 | 4596 | ||
| 4596 | try child.spawn(); | 4597 | try child.spawn(io); |
| 4597 | 4598 | ||
| 4598 | return child.id; | 4599 | return child.id; |
| 4599 | }, | 4600 | }, |
| ... | @@ -5419,8 +5420,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) | ... | @@ -5419,8 +5420,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) |
| 5419 | const term = t: { | 5420 | const term = t: { |
| 5420 | std.debug.lockStdErr(); | 5421 | std.debug.lockStdErr(); |
| 5421 | defer std.debug.unlockStdErr(); | 5422 | defer std.debug.unlockStdErr(); |
| 5422 | break :t child.spawnAndWait() catch |err| { | 5423 | break :t child.spawnAndWait(io) catch |err| { |
| 5423 | fatal("failed to spawn build runner {s}: {s}", .{ child_argv.items[0], @errorName(err) }); | 5424 | fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); |
| 5424 | }; | 5425 | }; |
| 5425 | }; | 5426 | }; |
| 5426 | 5427 | ||
| ... | @@ -5444,7 +5445,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) | ... | @@ -5444,7 +5445,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) |
| 5444 | dirs.local_cache, tmp_sub_path, @errorName(err), | 5445 | dirs.local_cache, tmp_sub_path, @errorName(err), |
| 5445 | }); | 5446 | }); |
| 5446 | }; | 5447 | }; |
| 5447 | dirs.local_cache.handle.deleteFile(tmp_sub_path) catch {}; | 5448 | dirs.local_cache.handle.deleteFile(io, tmp_sub_path) catch {}; |
| 5448 | 5449 | ||
| 5449 | var it = mem.splitScalar(u8, stdout, '\n'); | 5450 | var it = mem.splitScalar(u8, stdout, '\n'); |
| 5450 | var any_errors = false; | 5451 | var any_errors = false; |
| ... | @@ -5685,7 +5686,7 @@ fn jitCmd( | ... | @@ -5685,7 +5686,7 @@ fn jitCmd( |
| 5685 | child.stdout_behavior = if (options.capture == null) .Inherit else .Pipe; | 5686 | child.stdout_behavior = if (options.capture == null) .Inherit else .Pipe; |
| 5686 | child.stderr_behavior = .Inherit; | 5687 | child.stderr_behavior = .Inherit; |
| 5687 | 5688 | ||
| 5688 | try child.spawn(); | 5689 | try child.spawn(io); |
| 5689 | 5690 | ||
| 5690 | if (options.capture) |ptr| { | 5691 | if (options.capture) |ptr| { |
| 5691 | var stdout_reader = child.stdout.?.readerStreaming(io, &.{}); | 5692 | var stdout_reader = child.stdout.?.readerStreaming(io, &.{}); |
test/src/Cases.zig+2-1| ... | @@ -461,6 +461,7 @@ pub fn lowerToBuildSteps( | ... | @@ -461,6 +461,7 @@ pub fn lowerToBuildSteps( |
| 461 | parent_step: *std.Build.Step, | 461 | parent_step: *std.Build.Step, |
| 462 | options: CaseTestOptions, | 462 | options: CaseTestOptions, |
| 463 | ) void { | 463 | ) void { |
| 464 | const io = self.io; | ||
| 464 | const host = b.resolveTargetQuery(.{}); | 465 | const host = b.resolveTargetQuery(.{}); |
| 465 | const cases_dir_path = b.build_root.join(b.allocator, &.{ "test", "cases" }) catch @panic("OOM"); | 466 | const cases_dir_path = b.build_root.join(b.allocator, &.{ "test", "cases" }) catch @panic("OOM"); |
| 466 | 467 | ||
| ... | @@ -595,7 +596,7 @@ pub fn lowerToBuildSteps( | ... | @@ -595,7 +596,7 @@ pub fn lowerToBuildSteps( |
| 595 | }, | 596 | }, |
| 596 | .Execution => |expected_stdout| no_exec: { | 597 | .Execution => |expected_stdout| no_exec: { |
| 597 | const run = if (case.target.result.ofmt == .c) run_step: { | 598 | const run = if (case.target.result.ofmt == .c) run_step: { |
| 598 | if (getExternalExecutor(&host.result, &case.target.result, .{ .link_libc = true }) != .native) { | 599 | if (getExternalExecutor(io, &host.result, &case.target.result, .{ .link_libc = true }) != .native) { |
| 599 | // We wouldn't be able to run the compiled C code. | 600 | // We wouldn't be able to run the compiled C code. |
| 600 | break :no_exec; | 601 | break :no_exec; |
| 601 | } | 602 | } |
test/standalone/child_process/main.zig+1-1| ... | @@ -29,7 +29,7 @@ pub fn main() !void { | ... | @@ -29,7 +29,7 @@ pub fn main() !void { |
| 29 | child.stdin_behavior = .Pipe; | 29 | child.stdin_behavior = .Pipe; |
| 30 | child.stdout_behavior = .Pipe; | 30 | child.stdout_behavior = .Pipe; |
| 31 | child.stderr_behavior = .Inherit; | 31 | child.stderr_behavior = .Inherit; |
| 32 | try child.spawn(); | 32 | try child.spawn(io); |
| 33 | const child_stdin = child.stdin.?; | 33 | const child_stdin = child.stdin.?; |
| 34 | try child_stdin.writeAll("hello from stdin"); // verified in child | 34 | try child_stdin.writeAll("hello from stdin"); // verified in child |
| 35 | child_stdin.close(io); | 35 | child_stdin.close(io); |