From 6822652f16c748114e127d31918ac31ff2dcfe47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magn=C3=BAs=20Sm=C3=A1ri=20Sm=C3=A1rason?= Date: Tue, 14 Jul 2026 18:55:49 +0000 Subject: [PATCH] melt: non-zero exit when interrupted by a signal (#547) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit melt caught SIGINT/SIGTERM (and SIGHUP/SIGPIPE on non-Windows) via stop_handler, which sets the producer "done" property for a graceful stop but then let main() return 0 — so a Ctrl-C'd, incomplete render reported success and callers could not detect it. Record the signal in a volatile sig_atomic_t and, after the output is finalized, restore the default handler and re-raise it so the exit status reflects the signal (130 for SIGINT, 143 for SIGTERM, etc.), mirroring the existing abnormal_exit_handler in this file (term_exit then signal(SIG_DFL) then raise). On Windows, surface EXIT_FAILURE. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/melt/melt.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/melt/melt.c b/src/melt/melt.c index 66c064eb0..2e1351faa 100644 --- a/src/melt/melt.c +++ b/src/melt/melt.c @@ -45,9 +45,11 @@ #include "io.h" static mlt_producer melt = NULL; +static volatile sig_atomic_t stop_signum = 0; static void stop_handler(int signum) { + stop_signum = signum; if (melt) { mlt_properties properties = MLT_PRODUCER_PROPERTIES(melt); mlt_properties_set_int(properties, "done", 1); @@ -1138,5 +1140,17 @@ int main(int argc, char **argv) // Flush all open writable streams fflush(NULL); + // Interrupted by a signal: the render is incomplete. Restore the default + // handler and re-raise so the exit status reflects the signal (e.g. 130 for + // SIGINT), mirroring abnormal_exit_handler above. (#547) + if (stop_signum && !error) { +#ifndef _WIN32 + term_exit(); + signal(stop_signum, SIG_DFL); + raise(stop_signum); +#endif + error = EXIT_FAILURE; // Windows: no re-raise, so surface a non-zero status + } + return error; }