diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index ff7841647..4394dbe59 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -546,7 +546,7 @@ pub fn jumpToPrompt(self: *Exec, delta: isize) !void { /// Called when the child process exited abnormally but before /// the surface is notified. -pub fn childExitedAbnormally(self: *Exec) !void { +pub fn childExitedAbnormally(self: *Exec, exit_code: u32, runtime_ms: u64) !void { // Build up our command for the error message const command = try std.mem.join( self.alloc, @@ -555,6 +555,11 @@ pub fn childExitedAbnormally(self: *Exec) !void { ); defer self.alloc.free(command); + const runtime_str = try std.fmt.allocPrint(self.alloc, "{d} ms", .{runtime_ms}); + defer self.alloc.free(runtime_str); + const exit_code_str = try std.fmt.allocPrint(self.alloc, "{d}", .{exit_code}); + defer self.alloc.free(exit_code_str); + // Modify the terminal to show our error message. This // requires grabbing the renderer state lock. self.renderer_state.mutex.lock(); @@ -586,14 +591,28 @@ pub fn childExitedAbnormally(self: *Exec) !void { try t.setAttribute(.{ .bold = {} }); try t.printString("Ghostty failed to launch the requested command:"); try t.setAttribute(.{ .unset = {} }); - try t.setAttribute(.{ .faint = {} }); t.carriageReturn(); try t.linefeed(); + try t.linefeed(); + try t.setAttribute(.{ .bold = {} }); try t.printString(command); try t.setAttribute(.{ .unset = {} }); t.carriageReturn(); try t.linefeed(); try t.linefeed(); + try t.printString("Runtime: "); + try t.setAttribute(.{ .@"8_fg" = .bright_red }); + try t.printString(runtime_str); + try t.setAttribute(.{ .unset = {} }); + t.carriageReturn(); + try t.linefeed(); + try t.printString("Exit code: "); + try t.setAttribute(.{ .@"8_fg" = .bright_red }); + try t.printString(exit_code_str); + try t.setAttribute(.{ .unset = {} }); + t.carriageReturn(); + try t.linefeed(); + try t.linefeed(); try t.printString("Press any key to close the window."); // Hide the cursor @@ -777,7 +796,7 @@ fn processExit( _: *xev.Completion, r: xev.Process.WaitError!u32, ) xev.CallbackAction { - const code = r catch unreachable; + const exit_code = r catch unreachable; const ev = ev_.?; ev.process_exited = true; @@ -791,7 +810,7 @@ fn processExit( }; log.debug( "child process exited status={} runtime={}ms", - .{ code, runtime_ms orelse 0 }, + .{ exit_code, runtime_ms orelse 0 }, ); // If our runtime was below some threshold then we assume that this @@ -802,7 +821,7 @@ fn processExit( if (comptime !builtin.target.isDarwin()) { // If our exit code is zero, then the command was successful // and we don't ever consider it abnormal. - if (code == 0) break :runtime; + if (exit_code == 0) break :runtime; } // Our runtime always has to be under the threshold to be @@ -817,7 +836,7 @@ fn processExit( // information so it can show a better error message. _ = ev.writer_mailbox.push(.{ .child_exited_abnormally = .{ - .code = code, + .exit_code = exit_code, .runtime_ms = runtime, }, }, .{ .forever = {} }); diff --git a/src/termio/Thread.zig b/src/termio/Thread.zig index 516102f3f..61b2e3fba 100644 --- a/src/termio/Thread.zig +++ b/src/termio/Thread.zig @@ -186,7 +186,7 @@ fn drainMailbox(self: *Thread) !void { .jump_to_prompt => |v| try self.impl.jumpToPrompt(v), .start_synchronized_output => self.startSynchronizedOutput(), .linefeed_mode => |v| self.flags.linefeed_mode = v, - .child_exited_abnormally => try self.impl.childExitedAbnormally(), + .child_exited_abnormally => |v| try self.impl.childExitedAbnormally(v.exit_code, v.runtime_ms), .write_small => |v| try self.impl.queueWrite(v.data[0..v.len], self.flags.linefeed_mode), .write_stable => |v| try self.impl.queueWrite(v, self.flags.linefeed_mode), .write_alloc => |v| { diff --git a/src/termio/message.zig b/src/termio/message.zig index e6c8fc76f..ce6db8238 100644 --- a/src/termio/message.zig +++ b/src/termio/message.zig @@ -67,7 +67,7 @@ pub const Message = union(enum) { /// close because termio can use this to update the terminal /// with an error message. child_exited_abnormally: struct { - code: u32, + exit_code: u32, runtime_ms: u64, },