aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
authorgbc dev <gbc@localhost>2026-07-17 19:45:03 +0200
committergbc dev <gbc@localhost>2026-07-17 19:45:03 +0200
commita3dd7fa747d631831e920aa55ed03e7954ca6517 (patch)
tree9fdff7c99c45a28d445befb2ce5bc11772ad0608 /src/main.c
parentmain: --serial-sock PATH - link port over a unix socket (net + live display) (diff)
downloadsl0pboy-a3dd7fa747d631831e920aa55ed03e7954ca6517.tar.gz
sl0pboy-a3dd7fa747d631831e920aa55ed03e7954ca6517.tar.xz
sl0pboy-a3dd7fa747d631831e920aa55ed03e7954ca6517.zip
main: silence stderr while the live sixel display is up
Runtime chatter (link reconnect notices, input debug, cart warnings) was landing mid-sixel-stream and corrupting the picture. Redirect fd 2 to /dev/null for the duration of the display loop; restored on exit so the final stats line still prints. Startup errors before the display begins are unaffected.
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index 1dba964..e95ab95 100644
--- a/src/main.c
+++ b/src/main.c
@@ -216,6 +216,12 @@ int main(int argc, char **argv) {
gb->serial_in_fd = serial_fd;
gb->serial_out_fd = serial_fd;
gb->serial_no_eof = true;
+ gb->serial_sock_path = serial_sock; // enables auto-reconnect (gb.c)
+ // A dead peer must degrade the link, not kill the emulator: without
+ // this, a write() after the bridge goes away raises SIGPIPE and the
+ // whole Game Boy silently dies - exactly the "GB left and never came
+ // back" failure mode.
+ signal(SIGPIPE, SIG_IGN);
fprintf(stderr, "link port <-> %s\n", serial_sock);
}
@@ -288,6 +294,8 @@ int main(int argc, char **argv) {
}
}
if (raw_tty) tcsetattr(STDIN_FILENO, TCSANOW, &saved_tio);
+ fprintf(stderr, "[sl0pboy] headless loop exit: %s\n",
+ gb->poweroff ? "guest poweroff" : "signal");
if (shot_frames >= 0) { // --headless --shot FILE: dump final LCD
int cw, ch; const u8 *cap = render_capture_frame(gb, &cw, &ch);
FILE *pf = fopen(shot_path, "wb");
@@ -327,6 +335,17 @@ int main(int argc, char **argv) {
if (chrome && !sixel)
fprintf(stderr, "note: --chrome only affects live display in --sixel mode "
"(it still applies to --shot / recordings)\n");
+ // A sixel stream is fragile: any stray stderr text (link reconnect notices,
+ // input debug, cart warnings) lands mid-stream and corrupts the picture.
+ // Silence stderr while the live sixel display is up; restored on exit so
+ // the final stats line still prints.
+ int saved_stderr = -1;
+ if (sixel) {
+ fflush(stderr);
+ saved_stderr = dup(STDERR_FILENO);
+ int devnull = open("/dev/null", O_WRONLY);
+ if (devnull >= 0) { dup2(devnull, STDERR_FILENO); close(devnull); }
+ }
term_init();
// The emulator always advances every GB frame at the paced native rate so
@@ -389,6 +408,11 @@ int main(int argc, char **argv) {
}
term_restore();
+ if (saved_stderr >= 0) { // un-silence stderr (sixel mode)
+ fflush(stderr);
+ dup2(saved_stderr, STDERR_FILENO);
+ close(saved_stderr);
+ }
input_close_fifo();
control_close();
double elapsed = now_sec() - start_time;