| author | |
| committer | |
| log | 05346e123bc5dbc20a7a60655b06b55030a84f47 |
| tree | cb3fc030e20efdda9e427d08568e7ecf26562d06 |
| parent | 83abd73801a6ab3125c1b0b8ba432be188c9e7ca |
The user must now explicitly choose between inheriting the current CWD, passing a path for the CWD, or passing a Dir for the CWD.13 files changed, 112 insertions(+), 95 deletions(-)
lib/compiler/std-docs.zig+5-5| ... | ... | @@ -398,7 +398,7 @@ fn buildWasmBinary( |
| 398 | 398 | if (code != 0) { |
| 399 | 399 | std.log.err( |
| 400 | 400 | "the following command exited with error code {d}:\n{s}", |
| 401 | .{ code, try std.Build.Step.allocPrintCmd(arena, null, null, argv.items) }, | |
| 401 | .{ code, try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items) }, | |
| 402 | 402 | ); |
| 403 | 403 | return error.WasmCompilationFailed; |
| 404 | 404 | } |
| ... | ... | @@ -406,14 +406,14 @@ fn buildWasmBinary( |
| 406 | 406 | .signal => |sig| { |
| 407 | 407 | std.log.err( |
| 408 | 408 | "the following command terminated with signal {t}:\n{s}", |
| 409 | .{ sig, try std.Build.Step.allocPrintCmd(arena, null, null, argv.items) }, | |
| 409 | .{ sig, try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items) }, | |
| 410 | 410 | ); |
| 411 | 411 | return error.WasmCompilationFailed; |
| 412 | 412 | }, |
| 413 | 413 | .stopped, .unknown => { |
| 414 | 414 | std.log.err( |
| 415 | 415 | "the following command terminated unexpectedly:\n{s}", |
| 416 | .{try std.Build.Step.allocPrintCmd(arena, null, null, argv.items)}, | |
| 416 | .{try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items)}, | |
| 417 | 417 | ); |
| 418 | 418 | return error.WasmCompilationFailed; |
| 419 | 419 | }, |
| ... | ... | @@ -423,14 +423,14 @@ fn buildWasmBinary( |
| 423 | 423 | try result_error_bundle.renderToStderr(io, .{}, .auto); |
| 424 | 424 | std.log.err("the following command failed with {d} compilation errors:\n{s}", .{ |
| 425 | 425 | result_error_bundle.errorMessageCount(), |
| 426 | try std.Build.Step.allocPrintCmd(arena, null, null, argv.items), | |
| 426 | try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items), | |
| 427 | 427 | }); |
| 428 | 428 | return error.WasmCompilationFailed; |
| 429 | 429 | } |
| 430 | 430 | |
| 431 | 431 | return result orelse { |
| 432 | 432 | std.log.err("child process failed to report result\n{s}", .{ |
| 433 | try std.Build.Step.allocPrintCmd(arena, null, null, argv.items), | |
| 433 | try std.Build.Step.allocPrintCmd(arena, .inherit, null, argv.items), | |
| 434 | 434 | }); |
| 435 | 435 | return error.WasmCompilationFailed; |
| 436 | 436 | }; |
lib/std/Build.zig+2-2| ... | ... | @@ -1868,7 +1868,7 @@ pub fn runAllowFail( |
| 1868 | 1868 | const io = graph.io; |
| 1869 | 1869 | |
| 1870 | 1870 | const max_output_size = 400 * 1024; |
| 1871 | try Step.handleVerbose2(b, null, &graph.environ_map, argv); | |
| 1871 | try Step.handleVerbose2(b, .inherit, &graph.environ_map, argv); | |
| 1872 | 1872 | |
| 1873 | 1873 | var child = try std.process.spawn(io, .{ |
| 1874 | 1874 | .argv = argv, |
| ... | ... | @@ -1911,7 +1911,7 @@ pub fn run(b: *Build, argv: []const []const u8) []u8 { |
| 1911 | 1911 | var code: u8 = undefined; |
| 1912 | 1912 | return b.runAllowFail(argv, &code, .inherit) catch |err| process.fatal( |
| 1913 | 1913 | "the following command failed with {t}:\n{s}", |
| 1914 | .{ err, Step.allocPrintCmd(b.allocator, null, null, argv) catch @panic("OOM") }, | |
| 1914 | .{ err, Step.allocPrintCmd(b.allocator, .inherit, null, argv) catch @panic("OOM") }, | |
| 1915 | 1915 | ); |
| 1916 | 1916 | } |
| 1917 | 1917 |
lib/std/Build/Step.zig+16-12| ... | ... | @@ -350,10 +350,10 @@ pub fn captureChildProcess( |
| 350 | 350 | |
| 351 | 351 | // If an error occurs, it's happened in this command: |
| 352 | 352 | assert(s.result_failed_command == null); |
| 353 | s.result_failed_command = try allocPrintCmd(gpa, null, null, argv); | |
| 353 | s.result_failed_command = try allocPrintCmd(gpa, .inherit, null, argv); | |
| 354 | 354 | |
| 355 | 355 | try handleChildProcUnsupported(s); |
| 356 | try handleVerbose(s.owner, null, argv); | |
| 356 | try handleVerbose(s.owner, .inherit, argv); | |
| 357 | 357 | |
| 358 | 358 | const result = std.process.run(arena, io, .{ |
| 359 | 359 | .argv = argv, |
| ... | ... | @@ -410,7 +410,7 @@ pub fn evalZigProcess( |
| 410 | 410 | |
| 411 | 411 | // If an error occurs, it's happened in this command: |
| 412 | 412 | assert(s.result_failed_command == null); |
| 413 | s.result_failed_command = try allocPrintCmd(gpa, null, null, argv); | |
| 413 | s.result_failed_command = try allocPrintCmd(gpa, .inherit, null, argv); | |
| 414 | 414 | |
| 415 | 415 | if (s.getZigProcess()) |zp| update: { |
| 416 | 416 | assert(watch); |
| ... | ... | @@ -449,7 +449,7 @@ pub fn evalZigProcess( |
| 449 | 449 | assert(argv.len != 0); |
| 450 | 450 | |
| 451 | 451 | try handleChildProcUnsupported(s); |
| 452 | try handleVerbose(s.owner, null, argv); | |
| 452 | try handleVerbose(s.owner, .inherit, argv); | |
| 453 | 453 | |
| 454 | 454 | const zp = try gpa.create(ZigProcess); |
| 455 | 455 | defer if (!watch) gpa.destroy(zp); |
| ... | ... | @@ -515,7 +515,7 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u |
| 515 | 515 | const b = s.owner; |
| 516 | 516 | const io = b.graph.io; |
| 517 | 517 | const src_path = src_lazy_path.getPath3(b, s); |
| 518 | try handleVerbose(b, null, &.{ "install", "-C", b.fmt("{f}", .{src_path}), dest_path }); | |
| 518 | try handleVerbose(b, .inherit, &.{ "install", "-C", b.fmt("{f}", .{src_path}), dest_path }); | |
| 519 | 519 | return Io.Dir.updateFile(src_path.root_dir.handle, io, src_path.sub_path, .cwd(), dest_path, .{}) catch |err| |
| 520 | 520 | return s.fail("unable to update file from '{f}' to '{s}': {t}", .{ src_path, dest_path, err }); |
| 521 | 521 | } |
| ... | ... | @@ -524,7 +524,7 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u |
| 524 | 524 | pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.CreatePathStatus { |
| 525 | 525 | const b = s.owner; |
| 526 | 526 | const io = b.graph.io; |
| 527 | try handleVerbose(b, null, &.{ "install", "-d", dest_path }); | |
| 527 | try handleVerbose(b, .inherit, &.{ "install", "-d", dest_path }); | |
| 528 | 528 | return Io.Dir.cwd().createDirPathStatus(io, dest_path, .default_dir) catch |err| |
| 529 | 529 | return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err }); |
| 530 | 530 | } |
| ... | ... | @@ -700,15 +700,15 @@ fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void { |
| 700 | 700 | |
| 701 | 701 | pub fn handleVerbose( |
| 702 | 702 | b: *Build, |
| 703 | opt_cwd: ?[]const u8, | |
| 703 | cwd: std.process.Child.Cwd, | |
| 704 | 704 | argv: []const []const u8, |
| 705 | 705 | ) error{OutOfMemory}!void { |
| 706 | return handleVerbose2(b, opt_cwd, null, argv); | |
| 706 | return handleVerbose2(b, cwd, null, argv); | |
| 707 | 707 | } |
| 708 | 708 | |
| 709 | 709 | pub fn handleVerbose2( |
| 710 | 710 | b: *Build, |
| 711 | opt_cwd: ?[]const u8, | |
| 711 | cwd: std.process.Child.Cwd, | |
| 712 | 712 | opt_env: ?*const std.process.Environ.Map, |
| 713 | 713 | argv: []const []const u8, |
| 714 | 714 | ) error{OutOfMemory}!void { |
| ... | ... | @@ -716,7 +716,7 @@ pub fn handleVerbose2( |
| 716 | 716 | const graph = b.graph; |
| 717 | 717 | // Intention of verbose is to print all sub-process command lines to |
| 718 | 718 | // stderr before spawning them. |
| 719 | const text = try allocPrintCmd(b.allocator, opt_cwd, if (opt_env) |env| .{ | |
| 719 | const text = try allocPrintCmd(b.allocator, cwd, if (opt_env) |env| .{ | |
| 720 | 720 | .child = env, |
| 721 | 721 | .parent = &graph.environ_map, |
| 722 | 722 | } else null, argv); |
| ... | ... | @@ -751,7 +751,7 @@ pub fn handleChildProcessTerm(s: *Step, term: std.process.Child.Term) error{ Mak |
| 751 | 751 | |
| 752 | 752 | pub fn allocPrintCmd( |
| 753 | 753 | gpa: Allocator, |
| 754 | opt_cwd: ?[]const u8, | |
| 754 | cwd: std.process.Child.Cwd, | |
| 755 | 755 | opt_env: ?struct { |
| 756 | 756 | child: *const std.process.Environ.Map, |
| 757 | 757 | parent: *const std.process.Environ.Map, |
| ... | ... | @@ -796,7 +796,11 @@ pub fn allocPrintCmd( |
| 796 | 796 | var aw: Io.Writer.Allocating = .init(gpa); |
| 797 | 797 | defer aw.deinit(); |
| 798 | 798 | const writer = &aw.writer; |
| 799 | if (opt_cwd) |cwd| writer.print("cd {s} && ", .{cwd}) catch return error.OutOfMemory; | |
| 799 | switch (cwd) { | |
| 800 | .inherit => {}, | |
| 801 | .path => |path| writer.print("cd {s} && ", .{path}) catch return error.OutOfMemory, | |
| 802 | .dir => @panic("TODO"), | |
| 803 | } | |
| 800 | 804 | if (opt_env) |env| { |
| 801 | 805 | var it = env.child.iterator(); |
| 802 | 806 | while (it.next()) |entry| { |
lib/std/Build/Step/InstallArtifact.zig+1-1| ... | ... | @@ -187,7 +187,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 187 | 187 | const full_dest_path = b.pathJoin(&.{ full_h_prefix, entry.path }); |
| 188 | 188 | switch (entry.kind) { |
| 189 | 189 | .directory => { |
| 190 | try Step.handleVerbose(b, null, &.{ "install", "-d", full_dest_path }); | |
| 190 | try Step.handleVerbose(b, .inherit, &.{ "install", "-d", full_dest_path }); | |
| 191 | 191 | const p = try step.installDir(full_dest_path); |
| 192 | 192 | all_cached = all_cached and p == .existed; |
| 193 | 193 | }, |
lib/std/Build/Step/Run.zig+2-2| ... | ... | @@ -1227,7 +1227,7 @@ fn runCommand( |
| 1227 | 1227 | const gpa = options.gpa; |
| 1228 | 1228 | const io = b.graph.io; |
| 1229 | 1229 | |
| 1230 | const cwd: ?[]const u8 = if (run.cwd) |lazy_cwd| lazy_cwd.getPath2(b, step) else null; | |
| 1230 | const cwd: process.Child.Cwd = if (run.cwd) |lazy_cwd| .{ .path = lazy_cwd.getPath2(b, step) } else .inherit; | |
| 1231 | 1231 | |
| 1232 | 1232 | try step.handleChildProcUnsupported(); |
| 1233 | 1233 | try Step.handleVerbose2(step.owner, cwd, run.environ_map, argv); |
| ... | ... | @@ -1549,7 +1549,7 @@ fn spawnChildAndCollect( |
| 1549 | 1549 | assert(run.stdio == .zig_test); |
| 1550 | 1550 | } |
| 1551 | 1551 | |
| 1552 | const child_cwd = if (run.cwd) |lazy_cwd| lazy_cwd.getPath2(b, &run.step) else null; | |
| 1552 | const child_cwd: process.Child.Cwd = if (run.cwd) |lazy_cwd| .{ .path = lazy_cwd.getPath2(b, &run.step) } else .inherit; | |
| 1553 | 1553 | |
| 1554 | 1554 | // If an error occurs, it's caused by this command: |
| 1555 | 1555 | assert(run.step.result_failed_command == null); |
lib/std/Build/WebServer.zig+5-5| ... | ... | @@ -652,7 +652,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim |
| 652 | 652 | if (code != 0) { |
| 653 | 653 | log.err( |
| 654 | 654 | "the following command exited with error code {d}:\n{s}", |
| 655 | .{ code, try Build.Step.allocPrintCmd(arena, null, null, argv.items) }, | |
| 655 | .{ code, try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items) }, | |
| 656 | 656 | ); |
| 657 | 657 | return error.WasmCompilationFailed; |
| 658 | 658 | } |
| ... | ... | @@ -660,14 +660,14 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim |
| 660 | 660 | .signal => |sig| { |
| 661 | 661 | log.err( |
| 662 | 662 | "the following command terminated with signal {t}:\n{s}", |
| 663 | .{ sig, try Build.Step.allocPrintCmd(arena, null, null, argv.items) }, | |
| 663 | .{ sig, try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items) }, | |
| 664 | 664 | ); |
| 665 | 665 | return error.WasmCompilationFailed; |
| 666 | 666 | }, |
| 667 | 667 | .stopped, .unknown => { |
| 668 | 668 | log.err( |
| 669 | 669 | "the following command terminated unexpectedly:\n{s}", |
| 670 | .{try Build.Step.allocPrintCmd(arena, null, null, argv.items)}, | |
| 670 | .{try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items)}, | |
| 671 | 671 | ); |
| 672 | 672 | return error.WasmCompilationFailed; |
| 673 | 673 | }, |
| ... | ... | @@ -677,14 +677,14 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim |
| 677 | 677 | try result_error_bundle.renderToStderr(io, .{}, .auto); |
| 678 | 678 | log.err("the following command failed with {d} compilation errors:\n{s}", .{ |
| 679 | 679 | result_error_bundle.errorMessageCount(), |
| 680 | try Build.Step.allocPrintCmd(arena, null, null, argv.items), | |
| 680 | try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items), | |
| 681 | 681 | }); |
| 682 | 682 | return error.WasmCompilationFailed; |
| 683 | 683 | } |
| 684 | 684 | |
| 685 | 685 | const base_path = result orelse { |
| 686 | 686 | log.err("child process failed to report result\n{s}", .{ |
| 687 | try Build.Step.allocPrintCmd(arena, null, null, argv.items), | |
| 687 | try Build.Step.allocPrintCmd(arena, .inherit, null, argv.items), | |
| 688 | 688 | }); |
| 689 | 689 | return error.WasmCompilationFailed; |
| 690 | 690 | }; |
lib/std/Io/Threaded.zig+27-21| ... | ... | @@ -14606,10 +14606,14 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp |
| 14606 | 14606 | setUpChildIo(options.stdout, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkBail(ep1, err); |
| 14607 | 14607 | setUpChildIo(options.stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkBail(ep1, err); |
| 14608 | 14608 | |
| 14609 | if (options.cwd_dir) |cwd| { | |
| 14610 | fchdir(cwd.handle) catch |err| forkBail(ep1, err); | |
| 14611 | } else if (options.cwd) |cwd| { | |
| 14612 | chdir(cwd) catch |err| forkBail(ep1, err); | |
| 14609 | switch (options.cwd) { | |
| 14610 | .inherit => {}, | |
| 14611 | .dir => |cwd| { | |
| 14612 | fchdir(cwd.handle) catch |err| forkBail(ep1, err); | |
| 14613 | }, | |
| 14614 | .path => |cwd| { | |
| 14615 | chdir(cwd) catch |err| forkBail(ep1, err); | |
| 14616 | }, | |
| 14613 | 14617 | } |
| 14614 | 14618 | |
| 14615 | 14619 | // Must happen after fchdir above, the cwd file descriptor might be |
| ... | ... | @@ -15194,23 +15198,25 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro |
| 15194 | 15198 | const arena = arena_allocator.allocator(); |
| 15195 | 15199 | |
| 15196 | 15200 | const cwd_w = cwd_w: { |
| 15197 | if (options.cwd_dir) |cwd_dir| { | |
| 15198 | var dir_path_buffer = try arena.alloc(u16, windows.PATH_MAX_WIDE + 1); | |
| 15199 | // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks | |
| 15200 | try Thread.checkCancel(); | |
| 15201 | const dir_path = try windows.GetFinalPathNameByHandle( | |
| 15202 | cwd_dir.handle, | |
| 15203 | .{}, | |
| 15204 | dir_path_buffer[0..windows.PATH_MAX_WIDE], | |
| 15205 | ); | |
| 15206 | dir_path_buffer[dir_path.len] = 0; | |
| 15207 | // Shrink the allocation down to just the path buffer + sentinel | |
| 15208 | dir_path_buffer = try arena.realloc(dir_path_buffer, dir_path.len + 1); | |
| 15209 | break :cwd_w dir_path_buffer[0..dir_path.len :0]; | |
| 15210 | } else if (options.cwd) |cwd| { | |
| 15211 | break :cwd_w try std.unicode.wtf8ToWtf16LeAllocZ(arena, cwd); | |
| 15212 | } else { | |
| 15213 | break :cwd_w null; | |
| 15201 | switch (options.cwd) { | |
| 15202 | .inherit => break :cwd_w null, | |
| 15203 | .dir => |cwd_dir| { | |
| 15204 | var dir_path_buffer = try arena.alloc(u16, windows.PATH_MAX_WIDE + 1); | |
| 15205 | // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks | |
| 15206 | try Thread.checkCancel(); | |
| 15207 | const dir_path = try windows.GetFinalPathNameByHandle( | |
| 15208 | cwd_dir.handle, | |
| 15209 | .{}, | |
| 15210 | dir_path_buffer[0..windows.PATH_MAX_WIDE], | |
| 15211 | ); | |
| 15212 | dir_path_buffer[dir_path.len] = 0; | |
| 15213 | // Shrink the allocation down to just the path buffer + sentinel | |
| 15214 | dir_path_buffer = try arena.realloc(dir_path_buffer, dir_path.len + 1); | |
| 15215 | break :cwd_w dir_path_buffer[0..dir_path.len :0]; | |
| 15216 | }, | |
| 15217 | .path => |cwd| { | |
| 15218 | break :cwd_w try std.unicode.wtf8ToWtf16LeAllocZ(arena, cwd); | |
| 15219 | }, | |
| 15214 | 15220 | } |
| 15215 | 15221 | }; |
| 15216 | 15222 | const cwd_w_ptr = if (cwd_w) |cwd| cwd.ptr else null; |
lib/std/process.zig+2-11| ... | ... | @@ -368,11 +368,7 @@ pub const SpawnOptions = struct { |
| 368 | 368 | argv: []const []const u8, |
| 369 | 369 | |
| 370 | 370 | /// Set to change the current working directory when spawning the child process. |
| 371 | cwd: ?[]const u8 = null, | |
| 372 | /// Set to change the current working directory when spawning the child process. | |
| 373 | /// This is not yet implemented for Windows. See https://github.com/ziglang/zig/issues/5190 | |
| 374 | /// Once that is done, `cwd` will be deprecated in favor of this field. | |
| 375 | cwd_dir: ?Io.Dir = null, | |
| 371 | cwd: Child.Cwd = .inherit, | |
| 376 | 372 | /// Replaces the child environment when provided. The PATH value from here |
| 377 | 373 | /// is not used to resolve `argv[0]`; that resolution always uses parent |
| 378 | 374 | /// environment. |
| ... | ... | @@ -468,11 +464,7 @@ pub const RunOptions = struct { |
| 468 | 464 | reserve_amount: usize = 64, |
| 469 | 465 | |
| 470 | 466 | /// Set to change the current working directory when spawning the child process. |
| 471 | cwd: ?[]const u8 = null, | |
| 472 | /// Set to change the current working directory when spawning the child process. | |
| 473 | /// This is not yet implemented for Windows. See https://github.com/ziglang/zig/issues/5190 | |
| 474 | /// Once that is done, `cwd` will be deprecated in favor of this field. | |
| 475 | cwd_dir: ?Io.Dir = null, | |
| 467 | cwd: Child.Cwd = .inherit, | |
| 476 | 468 | /// Replaces the child environment when provided. The PATH value from here |
| 477 | 469 | /// is not used to resolve `argv[0]`; that resolution always uses parent |
| 478 | 470 | /// environment. |
| ... | ... | @@ -506,7 +498,6 @@ pub fn run(gpa: Allocator, io: Io, options: RunOptions) RunError!RunResult { |
| 506 | 498 | var child = try spawn(io, .{ |
| 507 | 499 | .argv = options.argv, |
| 508 | 500 | .cwd = options.cwd, |
| 509 | .cwd_dir = options.cwd_dir, | |
| 510 | 501 | .environ_map = options.environ_map, |
| 511 | 502 | .expand_arg0 = options.expand_arg0, |
| 512 | 503 | .progress_node = options.progress_node, |
lib/std/process/Child.zig+11| ... | ... | @@ -98,6 +98,17 @@ pub const Term = union(enum) { |
| 98 | 98 | unknown: u32, |
| 99 | 99 | }; |
| 100 | 100 | |
| 101 | pub const Cwd = union(enum) { | |
| 102 | /// CWD of the child is the same as the current CWD. | |
| 103 | inherit, | |
| 104 | /// On POSIX systems, `fchdir` is called after `fork` using this handle. | |
| 105 | /// On Windows, the path is inferred from the provided handle and that path is used when calling `CreateProcessW`. | |
| 106 | dir: Io.Dir, | |
| 107 | /// On POSIX systems, `chdir` is called after `fork` using this path. | |
| 108 | /// On Windows, this path is used when calling `CreateProcessW`. | |
| 109 | path: []const u8, | |
| 110 | }; | |
| 111 | ||
| 101 | 112 | /// Requests for the operating system to forcibly terminate the child process, |
| 102 | 113 | /// then blocks until it terminates, then cleans up all resources. |
| 103 | 114 | /// |
test/standalone/windows_paths/test.zig+20-22| ... | ... | @@ -32,39 +32,39 @@ pub fn main(init: std.process.Init) !void { |
| 32 | 32 | |
| 33 | 33 | // With the special =X: environment variable set, drive-relative paths that |
| 34 | 34 | // don't match the CWD's drive letter are resolved against that env var. |
| 35 | try checkRelative(arena, io, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &alt_drive_env_map); | |
| 36 | try checkRelative(arena, io, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map); | |
| 35 | try checkRelative(arena, io, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, &alt_drive_env_map); | |
| 36 | try checkRelative(arena, io, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, &alt_drive_env_map); | |
| 37 | 37 | |
| 38 | 38 | // Without that environment variable set, drive-relative paths that don't match the |
| 39 | 39 | // CWD's drive letter are resolved against the root of the drive. |
| 40 | try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env); | |
| 41 | try checkRelative(arena, io, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env); | |
| 40 | try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, &empty_env); | |
| 41 | try checkRelative(arena, io, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, &empty_env); | |
| 42 | 42 | |
| 43 | 43 | // Bare drive-relative path with no components |
| 44 | try checkRelative(arena, io, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &empty_env); | |
| 45 | try checkRelative(arena, io, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &empty_env); | |
| 44 | try checkRelative(arena, io, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, &empty_env); | |
| 45 | try checkRelative(arena, io, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, &empty_env); | |
| 46 | 46 | |
| 47 | 47 | // Bare drive-relative path with no components, drive-CWD set |
| 48 | try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &alt_drive_env_map); | |
| 49 | try checkRelative(arena, io, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &alt_drive_env_map); | |
| 48 | try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, &alt_drive_env_map); | |
| 49 | try checkRelative(arena, io, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, &alt_drive_env_map); | |
| 50 | 50 | |
| 51 | 51 | // Bare drive-relative path relative to the CWD should be equivalent if drive-CWD is set |
| 52 | try checkRelative(arena, io, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, null, &alt_drive_env_map); | |
| 53 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, null, &alt_drive_env_map); | |
| 52 | try checkRelative(arena, io, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, &alt_drive_env_map); | |
| 53 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, &alt_drive_env_map); | |
| 54 | 54 | |
| 55 | 55 | // Bare drive-relative should always be equivalent to itself |
| 56 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map); | |
| 57 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map); | |
| 58 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env); | |
| 59 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env); | |
| 56 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, &alt_drive_env_map); | |
| 57 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, &alt_drive_env_map); | |
| 58 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, &empty_env); | |
| 59 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, &empty_env); | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | if (parsed_cwd_path.kind == .unc_absolute) { |
| 63 | 63 | const drive_abs_path = try std.fmt.allocPrint(arena, "{c}:\\foo\\bar", .{alt_drive_letter}); |
| 64 | 64 | |
| 65 | 65 | { |
| 66 | try checkRelative(arena, io, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, null, &empty_env); | |
| 67 | try checkRelative(arena, io, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, null, &empty_env); | |
| 66 | try checkRelative(arena, io, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, &empty_env); | |
| 67 | try checkRelative(arena, io, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, &empty_env); | |
| 68 | 68 | } |
| 69 | 69 | } else if (parsed_cwd_path.kind == .drive_absolute) { |
| 70 | 70 | const cur_drive_letter = parsed_cwd_path.root[0]; |
| ... | ... | @@ -72,14 +72,14 @@ pub fn main(init: std.process.Init) !void { |
| 72 | 72 | const unc_cwd = try std.fmt.allocPrint(arena, "\\\\127.0.0.1\\{c}$\\{s}", .{ cur_drive_letter, path_beyond_root }); |
| 73 | 73 | |
| 74 | 74 | { |
| 75 | try checkRelative(arena, io, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, null, &empty_env); | |
| 76 | try checkRelative(arena, io, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, null, &empty_env); | |
| 75 | try checkRelative(arena, io, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, &empty_env); | |
| 76 | try checkRelative(arena, io, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, &empty_env); | |
| 77 | 77 | } |
| 78 | 78 | { |
| 79 | 79 | const drive_abs = cwd_path; |
| 80 | 80 | const drive_rel = parsed_cwd_path.root[0..2]; |
| 81 | try checkRelative(arena, io, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env); | |
| 82 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env); | |
| 81 | try checkRelative(arena, io, "", &.{ exe_path, drive_abs, drive_rel }, &empty_env); | |
| 82 | try checkRelative(arena, io, "", &.{ exe_path, drive_rel, drive_abs }, &empty_env); | |
| 83 | 83 | } |
| 84 | 84 | } else { |
| 85 | 85 | return error.UnexpectedPathType; |
| ... | ... | @@ -91,12 +91,10 @@ fn checkRelative( |
| 91 | 91 | io: Io, |
| 92 | 92 | expected_stdout: []const u8, |
| 93 | 93 | argv: []const []const u8, |
| 94 | cwd: ?[]const u8, | |
| 95 | 94 | environ_map: ?*const std.process.Environ.Map, |
| 96 | 95 | ) !void { |
| 97 | 96 | const result = try std.process.run(allocator, io, .{ |
| 98 | 97 | .argv = argv, |
| 99 | .cwd = cwd, | |
| 100 | 98 | .environ_map = environ_map, |
| 101 | 99 | }); |
| 102 | 100 | defer allocator.free(result.stdout); |
test/standalone/windows_spawn/main.zig+12-2| ... | ... | @@ -207,10 +207,20 @@ fn testExecError(err: anyerror, gpa: Allocator, io: Io, command: []const u8) !vo |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | fn testExec(gpa: Allocator, io: Io, command: []const u8, expected_stdout: []const u8) !void { |
| 210 | return testExecWithCwd(gpa, io, command, null, expected_stdout); | |
| 210 | return testExecWithCwdInner(gpa, io, command, .inherit, expected_stdout); | |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | fn testExecWithCwd(gpa: Allocator, io: Io, command: []const u8, cwd: ?[]const u8, expected_stdout: []const u8) !void { | |
| 213 | fn testExecWithCwd(gpa: Allocator, io: Io, command: []const u8, cwd: []const u8, expected_stdout: []const u8) !void { | |
| 214 | // Test by passing CWD as both a path and a Dir | |
| 215 | try testExecWithCwdInner(gpa, io, command, .{ .path = cwd }, expected_stdout); | |
| 216 | ||
| 217 | var cwd_dir = try Io.Dir.cwd().openDir(io, cwd, .{}); | |
| 218 | defer cwd_dir.close(io); | |
| 219 | ||
| 220 | try testExecWithCwdInner(gpa, io, command, .{ .dir = cwd_dir }, expected_stdout); | |
| 221 | } | |
| 222 | ||
| 223 | fn testExecWithCwdInner(gpa: Allocator, io: Io, command: []const u8, cwd: std.process.Child.Cwd, expected_stdout: []const u8) !void { | |
| 214 | 224 | const result = try std.process.run(gpa, io, .{ |
| 215 | 225 | .argv = &[_][]const u8{command}, |
| 216 | 226 | .cwd = cwd, |
tools/doctest.zig+6-6| ... | ... | @@ -199,7 +199,7 @@ fn printOutput( |
| 199 | 199 | if (expected_outcome == .build_fail) { |
| 200 | 200 | const result = try process.run(arena, io, .{ |
| 201 | 201 | .argv = build_args.items, |
| 202 | .cwd = tmp_dir_path, | |
| 202 | .cwd = .{ .path = tmp_dir_path }, | |
| 203 | 203 | .environ_map = environ_map, |
| 204 | 204 | }); |
| 205 | 205 | switch (result.term) { |
| ... | ... | @@ -255,7 +255,7 @@ fn printOutput( |
| 255 | 255 | const result = try process.run(arena, io, .{ |
| 256 | 256 | .argv = run_args, |
| 257 | 257 | .environ_map = environ_map, |
| 258 | .cwd = tmp_dir_path, | |
| 258 | .cwd = .{ .path = tmp_dir_path }, | |
| 259 | 259 | }); |
| 260 | 260 | switch (result.term) { |
| 261 | 261 | .exited => |exit_code| { |
| ... | ... | @@ -373,7 +373,7 @@ fn printOutput( |
| 373 | 373 | const result = try process.run(arena, io, .{ |
| 374 | 374 | .argv = test_args.items, |
| 375 | 375 | .environ_map = environ_map, |
| 376 | .cwd = tmp_dir_path, | |
| 376 | .cwd = .{ .path = tmp_dir_path }, | |
| 377 | 377 | }); |
| 378 | 378 | switch (result.term) { |
| 379 | 379 | .exited => |exit_code| { |
| ... | ... | @@ -428,7 +428,7 @@ fn printOutput( |
| 428 | 428 | const result = try process.run(arena, io, .{ |
| 429 | 429 | .argv = test_args.items, |
| 430 | 430 | .environ_map = environ_map, |
| 431 | .cwd = tmp_dir_path, | |
| 431 | .cwd = .{ .path = tmp_dir_path }, | |
| 432 | 432 | }); |
| 433 | 433 | switch (result.term) { |
| 434 | 434 | .exited => |exit_code| { |
| ... | ... | @@ -503,7 +503,7 @@ fn printOutput( |
| 503 | 503 | const result = try process.run(arena, io, .{ |
| 504 | 504 | .argv = build_args.items, |
| 505 | 505 | .environ_map = environ_map, |
| 506 | .cwd = tmp_dir_path, | |
| 506 | .cwd = .{ .path = tmp_dir_path }, | |
| 507 | 507 | }); |
| 508 | 508 | switch (result.term) { |
| 509 | 509 | .exited => |exit_code| { |
| ... | ... | @@ -1126,7 +1126,7 @@ fn run( |
| 1126 | 1126 | const result = try process.run(allocator, io, .{ |
| 1127 | 1127 | .argv = args, |
| 1128 | 1128 | .environ_map = environ_map, |
| 1129 | .cwd = cwd, | |
| 1129 | .cwd = .{ .path = cwd }, | |
| 1130 | 1130 | }); |
| 1131 | 1131 | switch (result.term) { |
| 1132 | 1132 | .exited => |exit_code| { |
tools/incr-check.zig+3-6| ... | ... | @@ -202,8 +202,7 @@ pub fn main(init: std.process.Init) !void { |
| 202 | 202 | .stdout = .pipe, |
| 203 | 203 | .stderr = .pipe, |
| 204 | 204 | .progress_node = zig_prog_node, |
| 205 | .cwd_dir = tmp_dir, | |
| 206 | .cwd = tmp_dir_path, | |
| 205 | .cwd = .{ .path = tmp_dir_path }, | |
| 207 | 206 | }); |
| 208 | 207 | defer child.kill(io); |
| 209 | 208 | |
| ... | ... | @@ -533,8 +532,7 @@ const Eval = struct { |
| 533 | 532 | |
| 534 | 533 | const result = std.process.run(eval.arena, io, .{ |
| 535 | 534 | .argv = argv, |
| 536 | .cwd_dir = eval.tmp_dir, | |
| 537 | .cwd = eval.tmp_dir_path, | |
| 535 | .cwd = .{ .path = eval.tmp_dir_path }, | |
| 538 | 536 | }) catch |err| { |
| 539 | 537 | if (is_foreign) { |
| 540 | 538 | // Chances are the foreign executor isn't available. Skip this evaluation. |
| ... | ... | @@ -626,8 +624,7 @@ const Eval = struct { |
| 626 | 624 | |
| 627 | 625 | const result = std.process.run(eval.arena, eval.io, .{ |
| 628 | 626 | .argv = eval.cc_child_args.items, |
| 629 | .cwd_dir = eval.tmp_dir, | |
| 630 | .cwd = eval.tmp_dir_path, | |
| 627 | .cwd = .{ .path = eval.tmp_dir_path }, | |
| 631 | 628 | .progress_node = child_prog_node, |
| 632 | 629 | }) catch |err| { |
| 633 | 630 | eval.fatal("failed to spawn zig cc for '{s}': {t}", .{ c_path, err }); |