| author | |
| committer | |
| log | 47343f9bcfb820b24d7e249c5cf52b80c3f9df83 |
| tree | db06a34c55c407181dcfbb4ee229ff1f5579d77a |
| parent | 2c2ecd624ad6d85d005f4728f834c0e3377f8f99 |
Tests that fs.selfExePath follows symlinks by comparing it to the path of the File returned from fs.openSelfExe4 files changed, 79 insertions(+), 0 deletions(-)
test/standalone.zig+4| ... | @@ -198,6 +198,10 @@ pub const build_cases = [_]BuildCase{ | ... | @@ -198,6 +198,10 @@ pub const build_cases = [_]BuildCase{ |
| 198 | .build_root = "test/standalone/windows_spawn", | 198 | .build_root = "test/standalone/windows_spawn", |
| 199 | .import = @import("standalone/windows_spawn/build.zig"), | 199 | .import = @import("standalone/windows_spawn/build.zig"), |
| 200 | }, | 200 | }, |
| 201 | .{ | ||
| 202 | .build_root = "test/standalone/self_exe_symlink", | ||
| 203 | .import = @import("standalone/self_exe_symlink/build.zig"), | ||
| 204 | }, | ||
| 201 | .{ | 205 | .{ |
| 202 | .build_root = "test/standalone/c_compiler", | 206 | .build_root = "test/standalone/c_compiler", |
| 203 | .import = @import("standalone/c_compiler/build.zig"), | 207 | .import = @import("standalone/c_compiler/build.zig"), |
test/standalone/self_exe_symlink/build.zig created+43| ... | @@ -0,0 +1,43 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub const requires_symlinks = true; | ||
| 4 | |||
| 5 | pub fn build(b: *std.Build) void { | ||
| 6 | const test_step = b.step("test", "Test it"); | ||
| 7 | b.default_step = test_step; | ||
| 8 | |||
| 9 | const optimize: std.builtin.OptimizeMode = .Debug; | ||
| 10 | const target: std.zig.CrossTarget = .{}; | ||
| 11 | |||
| 12 | // The test requires getFdPath in order to to get the path of the | ||
| 13 | // File returned by openSelfExe | ||
| 14 | if (!std.os.isGetFdPathSupportedOnTarget(target.getOs())) return; | ||
| 15 | |||
| 16 | const main = b.addExecutable(.{ | ||
| 17 | .name = "main", | ||
| 18 | .root_source_file = .{ .path = "main.zig" }, | ||
| 19 | .optimize = optimize, | ||
| 20 | .target = target, | ||
| 21 | }); | ||
| 22 | |||
| 23 | const create_symlink_exe = b.addExecutable(.{ | ||
| 24 | .name = "create-symlink", | ||
| 25 | .root_source_file = .{ .path = "create-symlink.zig" }, | ||
| 26 | .optimize = optimize, | ||
| 27 | .target = target, | ||
| 28 | }); | ||
| 29 | |||
| 30 | var run_create_symlink = b.addRunArtifact(create_symlink_exe); | ||
| 31 | run_create_symlink.addArtifactArg(main); | ||
| 32 | const symlink_path = run_create_symlink.addOutputFileArg("main-symlink"); | ||
| 33 | run_create_symlink.expectExitCode(0); | ||
| 34 | run_create_symlink.skip_foreign_checks = true; | ||
| 35 | |||
| 36 | var run_from_symlink = std.Build.Step.Run.create(b, "run symlink"); | ||
| 37 | run_from_symlink.addFileArg(symlink_path); | ||
| 38 | run_from_symlink.expectExitCode(0); | ||
| 39 | run_from_symlink.skip_foreign_checks = true; | ||
| 40 | run_from_symlink.step.dependOn(&run_create_symlink.step); | ||
| 41 | |||
| 42 | test_step.dependOn(&run_from_symlink.step); | ||
| 43 | } | ||
test/standalone/self_exe_symlink/create-symlink.zig created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() anyerror!void { | ||
| 4 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 5 | defer if (gpa.deinit() == .leak) @panic("found memory leaks"); | ||
| 6 | const allocator = gpa.allocator(); | ||
| 7 | |||
| 8 | var it = try std.process.argsWithAllocator(allocator); | ||
| 9 | defer it.deinit(); | ||
| 10 | _ = it.next() orelse unreachable; // skip binary name | ||
| 11 | const exe_path = it.next() orelse unreachable; | ||
| 12 | const symlink_path = it.next() orelse unreachable; | ||
| 13 | |||
| 14 | try std.fs.cwd().symLink(exe_path, symlink_path, .{}); | ||
| 15 | } | ||
test/standalone/self_exe_symlink/main.zig created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() !void { | ||
| 4 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 5 | defer std.debug.assert(gpa.deinit() == .ok); | ||
| 6 | const allocator = gpa.allocator(); | ||
| 7 | |||
| 8 | const self_path = try std.fs.selfExePathAlloc(allocator); | ||
| 9 | defer allocator.free(self_path); | ||
| 10 | |||
| 11 | var self_exe = try std.fs.openSelfExe(.{}); | ||
| 12 | defer self_exe.close(); | ||
| 13 | var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; | ||
| 14 | const self_exe_path = try std.os.getFdPath(self_exe.handle, &buf); | ||
| 15 | |||
| 16 | try std.testing.expectEqualStrings(self_exe_path, self_path); | ||
| 17 | } | ||