| ... | @@ -378,7 +378,7 @@ pub const File = struct { | ... | @@ -378,7 +378,7 @@ pub const File = struct { |
| 378 | if (build_options.only_c) unreachable; | 378 | if (build_options.only_c) unreachable; |
| 379 | if (base.file != null) return; | 379 | if (base.file != null) return; |
| 380 | const emit = base.options.emit orelse return; | 380 | const emit = base.options.emit orelse return; |
| 381 | if (base.child_pid != null) { | 381 | if (base.child_pid) |pid| { |
| 382 | // If we try to open the output file in write mode while it is running, | 382 | // If we try to open the output file in write mode while it is running, |
| 383 | // it will return ETXTBSY. So instead, we copy the file, atomically rename it | 383 | // it will return ETXTBSY. So instead, we copy the file, atomically rename it |
| 384 | // over top of the exe path, and then proceed normally. This changes the inode, | 384 | // over top of the exe path, and then proceed normally. This changes the inode, |
| ... | @@ -388,6 +388,11 @@ pub const File = struct { | ... | @@ -388,6 +388,11 @@ pub const File = struct { |
| 388 | }); | 388 | }); |
| 389 | try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); | 389 | try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); |
| 390 | try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); | 390 | try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); |
| | 391 | |
| | 392 | switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0, 0))) { |
| | 393 | .SUCCESS => {}, |
| | 394 | else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}), |
| | 395 | } |
| 391 | } | 396 | } |
| 392 | base.file = try emit.directory.handle.createFile(emit.sub_path, .{ | 397 | base.file = try emit.directory.handle.createFile(emit.sub_path, .{ |
| 393 | .truncate = false, | 398 | .truncate = false, |
| ... | @@ -437,6 +442,13 @@ pub const File = struct { | ... | @@ -437,6 +442,13 @@ pub const File = struct { |
| 437 | } | 442 | } |
| 438 | f.close(); | 443 | f.close(); |
| 439 | base.file = null; | 444 | base.file = null; |
| | 445 | |
| | 446 | if (base.child_pid) |pid| { |
| | 447 | switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0, 0))) { |
| | 448 | .SUCCESS => {}, |
| | 449 | else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}), |
| | 450 | } |
| | 451 | } |
| 440 | }, | 452 | }, |
| 441 | .c, .spirv, .nvptx => {}, | 453 | .c, .spirv, .nvptx => {}, |
| 442 | } | 454 | } |