1212// global lock
1313static RThreadLock * Glock = NULL ;
1414
15+ // global state for signal handler to flush partial JSON on kill
16+ static R2RState * Gstate = NULL ;
17+ static const char * Goutput_file = NULL ;
18+
1519#define JSON_TEST_FILE_DEFAULT "bins/elf/crackme0x00b"
1620#define TIMEOUT_DEFAULT (60 * 60)
1721#define STRV (x ) #x
@@ -1063,6 +1067,16 @@ static void r2r_write_output(R2RState *state, const char *output_file) {
10631067 R_LOG_ERROR ("Cannot write to %s" , output_file );
10641068 }
10651069 free (output );
1070+ state -> test_results = NULL ;
1071+ }
1072+
1073+ static void flush_partial_json (int sig ) {
1074+ R2RState * state = Gstate ;
1075+ const char * output_file = Goutput_file ;
1076+ if (state && output_file && state -> test_results ) {
1077+ r2r_write_output (state , output_file );
1078+ }
1079+ r_sys_exit (1 , true);
10661080}
10671081
10681082static RThreadFunctionRet worker_th (RThread * th ) {
@@ -1259,6 +1273,14 @@ int main(int argc, char **argv) {
12591273 if (opt .log_mode ) {
12601274 r2r_setup_log_mode (& state );
12611275 }
1276+ if (opt .output_file ) {
1277+ Gstate = & state ;
1278+ Goutput_file = opt .output_file ;
1279+ #if R2__UNIX__
1280+ r_sys_signal (SIGTERM , flush_partial_json );
1281+ r_sys_signal (SIGINT , flush_partial_json );
1282+ #endif
1283+ }
12621284 ut64 time_start = r_time_now_mono ();
12631285 if (!r2r_run_workers (& state , & opt )) {
12641286 ret = -1 ;
@@ -1269,6 +1291,7 @@ int main(int argc, char **argv) {
12691291 }
12701292 if (opt .output_file ) {
12711293 r2r_write_output (& state , opt .output_file );
1294+ Gstate = NULL ;
12721295 }
12731296 if (opt .interactive ) {
12741297 interact (& state );
0 commit comments