diff --git a/src/local.c b/src/local.c index 71942909..20e1f543 100644 --- a/src/local.c +++ b/src/local.c @@ -940,6 +940,9 @@ static void signal_cb(EV_P_ ev_signal *w, int revents) switch (w->signum) { case SIGINT: case SIGTERM: +#ifndef __MINGW32__ + case SIGUSR1: +#endif ev_unloop(EV_A_ EVUNLOOP_ALL); } } @@ -1281,6 +1284,27 @@ int main(int argc, char **argv) #else +static int running = 0; +static ev_timer state_watcher; + +static void state_timeout_cb(EV_P_ ev_timer *watcher, int revents) +{ + if (!running) { + ev_timer_stop(EV_A_ watcher); + ev_unloop(EV_A_ EVUNLOOP_ALL); + } +} + +int stop_ss_local_server() { + int ret = running ? 0 : -1; + running = 0; + return ret; +} + +int is_ss_local_server_running() { + return running; +} + int start_ss_local_server(profile_t profile) { srand(time(NULL)); @@ -1329,6 +1353,12 @@ int start_ss_local_server(profile_t profile) ev_signal_start(EV_DEFAULT, &sigint_watcher); ev_signal_start(EV_DEFAULT, &sigterm_watcher); +#ifndef __MINGW32__ + struct ev_signal sigusr1_watcher; + ev_signal_init(&sigusr1_watcher, signal_cb, SIGUSR1); + ev_signal_start(EV_DEFAULT, &sigusr1_watcher); +#endif + // Setup keys LOGI("initializing ciphers... %s", method); int m = enc_init(password, method); @@ -1381,6 +1411,10 @@ int start_ss_local_server(profile_t profile) // Init connections cork_dllist_init(&connections); + // Init state watcher + ev_timer_init(&state_watcher, state_timeout_cb, 1, 1); + ev_timer_start(loop, &state_watcher); + // Enter the loop ev_run(loop, 0); diff --git a/src/shadowsocks.h b/src/shadowsocks.h index 1492887e..705f1465 100644 --- a/src/shadowsocks.h +++ b/src/shadowsocks.h @@ -77,6 +77,26 @@ extern "C" { */ int start_ss_local_server(profile_t profile); +/* + * Stop the current shadowsocks local server. + * + * If failed, -1 is returned. Otherwise 0 is returned. + * + * This function is not thread safe. It's usable only if the server started + * in the same process. + */ +int stop_ss_local_server(); + +/* + * Get the state of the current shadowsocks local server. + * + * If running, 1 is returned. Otherwise, 0 is returned. + * + * This function is not thread safe. It's usable only if the server started + * in the same process. + */ +int is_ss_local_server_running(); + #ifdef __cplusplus } #endif