| ... | ... | @@ -378,7 +378,7 @@ pub const File = struct { |
| 378 | 378 | if (build_options.only_c) unreachable; |
| 379 | 379 | if (base.file != null) return; |
| 380 | 380 | const emit = base.options.emit orelse return; |
| 381 | | if (base.child_pid != null) { |
| 381 | if (base.child_pid) |pid| { |
| 382 | 382 | // If we try to open the output file in write mode while it is running, |
| 383 | 383 | // it will return ETXTBSY. So instead, we copy the file, atomically rename it |
| 384 | 384 | // over top of the exe path, and then proceed normally. This changes the inode, |
| ... | ... | @@ -388,6 +388,11 @@ pub const File = struct { |
| 388 | 388 | }); |
| 389 | 389 | try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); |
| 390 | 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 | 397 | base.file = try emit.directory.handle.createFile(emit.sub_path, .{ |
| 393 | 398 | .truncate = false, |
| ... | ... | @@ -437,6 +442,13 @@ pub const File = struct { |
| 437 | 442 | } |
| 438 | 443 | f.close(); |
| 439 | 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 | 453 | .c, .spirv, .nvptx => {}, |
| 442 | 454 | } |