diff --git a/pkg/urbit/daemon/main.c b/pkg/urbit/daemon/main.c index 290b56befa..ee91948225 100644 --- a/pkg/urbit/daemon/main.c +++ b/pkg/urbit/daemon/main.c @@ -753,6 +753,18 @@ main(c3_i argc, } } + #if defined(U3_OS_mingw) + // Initialize event used to transmit Ctrl-C to worker process + // + { + SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE}; + if ( NULL == (u3_Host.cev_u = CreateEvent(&sa, FALSE, FALSE, NULL)) ) { + u3l_log("boot: failed to create Ctrl-C event: %d\r\n", GetLastError()); + exit(1); + } + } + #endif + // Initialize OpenSSL for client and server // { diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index 56edece23a..20f2b98778 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -319,6 +319,9 @@ c3_d now_d; // event tick uv_loop_t* lup_u; // libuv event loop u3_usig* sig_u; // signal list + #if defined(U3_OS_mingw) + HANDLE cev_u; // Ctrl-C event handle + #endif u3_utty* uty_u; // linked terminal list u3_opts ops_u; // commandline options c3_i xit_i; // exit code for shutdown diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index 99f40032b9..ca11a7bc36 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -590,6 +590,10 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i) case SIGINT: { u3l_log("\r\ninterrupt\r\n"); u3_term_ef_ctlc(); + + #if defined(U3_OS_mingw) + PulseEvent(u3_Host.cev_u); + #endif break; } diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index e8fb65d8a8..25ffe60962 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -1145,6 +1145,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) c3_c key_c[256]; c3_c wag_c[11]; c3_c hap_c[11]; + c3_c cev_c[11]; c3_i err_i; sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64 "", @@ -1173,7 +1174,13 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u) arg_c[6] = "0"; } + #if defined(U3_OS_mingw) + sprintf(cev_c, "%u", u3_Host.cev_u); + arg_c[7] = cev_c; + arg_c[8] = 0; + #else arg_c[7] = 0; + #endif uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0); uv_timer_init(u3L, &god_u->out_u.tim_u); diff --git a/pkg/urbit/worker/main.c b/pkg/urbit/worker/main.c index c62ccd6e93..216d0c0470 100644 --- a/pkg/urbit/worker/main.c +++ b/pkg/urbit/worker/main.c @@ -155,6 +155,18 @@ _cw_serf_exit(void) u3t_trace_close(); } +#if defined(U3_OS_mingw) +extern void rsignal_raise(int); + +/* _mingw_ctrlc_cb(): invoked when the lord signals the Ctrl-C event +*/ +static void +_mingw_ctrlc_cb(PVOID param, BOOLEAN timedOut) +{ + rsignal_raise(SIGINT); +} +#endif + /* _cw_serf_commence(); initialize and run serf */ static void @@ -163,7 +175,23 @@ _cw_serf_commence(c3_i argc, c3_c* argv[]) c3_i inn_i, out_i; _cw_serf_stdio(&inn_i, &out_i); + #if defined(U3_OS_mingw) + c3_assert( 8 == argc ); + + // Initialize serf's end of Ctrl-C handling + // + { + HANDLE h; + if ( 1 != sscanf(argv[7], "%u", &h) ) { + fprintf(stderr, "serf: Ctrl-C event: bad handle %s: %s\r\n", argv[7], strerror(errno)); + } else + if ( !RegisterWaitForSingleObject(&h, h, _mingw_ctrlc_cb, NULL, INFINITE, 0) ) { + fprintf(stderr, "serf: Ctrl-C event: RegisterWaitForSingleObject(%u) failed (%d)\r\n", h, GetLastError()); + } + } + #else c3_assert( 7 == argc ); + #endif uv_loop_t* lup_u = uv_default_loop(); c3_c* dir_c = argv[2]; @@ -435,7 +463,11 @@ _cw_usage(c3_i argc, c3_c* argv[]) " cue persistent state:\n" " %s queu \n\n" " run as a 'serf':\n" - " %s serf \n", + " %s serf " + #if defined(U3_OS_mingw) + " " + #endif + "\n", argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0]); }