diff --git a/inc/lektor/common.h b/inc/lektor/common.h index fc797c50e74e5b0a31340008c0b720973df55be9..34e3bd09aaf3691f3eb76ce49d22bce04aedf9a4 100644 --- a/inc/lektor/common.h +++ b/inc/lektor/common.h @@ -137,8 +137,7 @@ typedef volatile enum { #define not_implemented() __not_implemented(__func__,__FILE__,__LINE__) extern void __not_implemented(const char *func, char *file, int line); -#define UNUSED(...) __unused((void *) __VA_ARGS__) -void __unused(void *, ...); +#define UNUSED __attribute__((unused)) long get_mtime(const char *path); diff --git a/inc/lektor/net.h b/inc/lektor/net.h index 1bfb4c336682b204b12c550ccc4e9ba62aedf1b2..386b2a1beb1c0bde2ab52dd713cbcf7a27eec246 100644 --- a/inc/lektor/net.h +++ b/inc/lektor/net.h @@ -52,16 +52,28 @@ struct lkt_state { char port[LKT_LINE_MAX]; struct queue queue; + /* The database */ volatile sqlite3 *db; const char *kara_prefix; + /* Internal event flags */ mpd_idle_flag mpd_idle_events; pthread_mutex_t lock; + /* Modules */ struct lkt_module window_mod; struct lkt_module repo_mod; + /* For uptime */ time_t start_date; + + /* Signal handlers for this server. + * Catch them all! */ + void (*__signal_INT )(struct lkt_state *); + void (*__signal_ILL )(struct lkt_state *); + void (*__signal_QUIT)(struct lkt_state *); + void (*__signal_USR1)(struct lkt_state *); + void (*__signal_USR2)(struct lkt_state *); }; /* Send a message to the connected client. */ diff --git a/src/base/commands.c b/src/base/commands.c index 98c2ca2374204fe5512fee4603d0ccc1b17a6fd8..7cf09f54390993fdf09ed61d766d8ca2d1274b5c 100644 --- a/src/base/commands.c +++ b/src/base/commands.c @@ -19,8 +19,7 @@ #include <unistd.h> inline bool -command_restart(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *__argv[LKT_MESSAGE_ARGS_MAX]) +command_restart(struct lkt_state *srv, size_t c, char UNUSED *__argv[LKT_MESSAGE_ARGS_MAX]) { const char *const argv[] = { executable_name, NULL }; struct lkt_queue_state sta; @@ -53,9 +52,8 @@ command_restart(struct lkt_state *srv, size_t c, } bool -command_update(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]) +command_update(struct lkt_state *srv, size_t c, char UNUSED *argv[LKT_MESSAGE_ARGS_MAX]) { - UNUSED(argv); RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false); srv->mpd_idle_events |= MPD_IDLE_UPDATE; srv->mpd_idle_events |= MPD_IDLE_DATABASE; @@ -63,10 +61,9 @@ command_update(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX] } bool -command_rescan(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX], - int __attribute__((unused)) forced) +command_rescan(struct lkt_state *srv, size_t c, char UNUSED *argv[LKT_MESSAGE_ARGS_MAX], + int UNUSED forced) { - UNUSED(argv); RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false); srv->mpd_idle_events |= MPD_IDLE_UPDATE; srv->mpd_idle_events |= MPD_IDLE_DATABASE; @@ -74,23 +71,16 @@ command_rescan(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX] } bool -command_kill(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *argv[LKT_MESSAGE_ARGS_MAX]) +command_kill(struct lkt_state *srv, size_t c, char UNUSED *argv[LKT_MESSAGE_ARGS_MAX]) { RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false); - LOG_INFO("GENERAL", "Stopping lektord"); - MOD_PROC(srv->repo_mod, "free"); - MOD_PROC(srv->window_mod, "free"); - close(srv->fds[0].fd); - lkt_queue_free(&srv->queue); - database_close_all(); - LOG_INFO("GENERAL", "lektord will now exit"); - exit(EXIT_SUCCESS); + srv->__signal_INT(srv); + LOG_ERROR("FATAL", "The SIGINT handler returned, now exiting"); + exit(EXIT_FAILURE); } bool -command_currentsong(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_currentsong(struct lkt_state *srv, size_t c, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { struct lkt_message *out; struct kara_metadata kara; @@ -118,8 +108,7 @@ command_currentsong(struct lkt_state *srv, size_t c, } bool -command_stats(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_stats(struct lkt_state *srv, size_t c, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { struct lkt_message *out = lkt_message_new(); int is_updating = 0, artists = 0, albums = 0, songs = 0; @@ -149,8 +138,7 @@ command_stats(struct lkt_state *srv, size_t c, } bool -command_status(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_status(struct lkt_state *srv, size_t c, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { struct lkt_message *out; struct lkt_queue_state queue_state; @@ -191,7 +179,7 @@ command_status(struct lkt_state *srv, size_t c, } bool -command_next(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_next(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { srv->mpd_idle_events |= MPD_IDLE_PLAYER; char filepath[PATH_MAX]; @@ -206,7 +194,7 @@ command_next(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSA } bool -command_pause(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_pause(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { srv->mpd_idle_events |= MPD_IDLE_PLAYER; if (!database_queue_toggle_pause(srv->db)) @@ -215,7 +203,7 @@ command_pause(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESS } bool -command_previous(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_previous(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { srv->mpd_idle_events |= MPD_IDLE_PLAYER; char filepath[PATH_MAX]; @@ -241,7 +229,7 @@ __play_that_file(struct lkt_state *win, int pos) } bool -command_play(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_play(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { char *endptr, err; long pos = 1; @@ -311,7 +299,7 @@ command_playid(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) bool -command_stop(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_stop(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { RETURN_UNLESS(database_queue_stop(srv->db), "DB error on stop", false); MOD_PROC(srv->window_mod, "close"); @@ -348,7 +336,7 @@ command_addid(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) } inline bool -command_clear(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_clear(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { srv->mpd_idle_events |= MPD_IDLE_PLAYER; return command_stop(srv, args) && @@ -356,7 +344,7 @@ command_clear(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESS } inline bool -command_crop(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_crop(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { srv->mpd_idle_events |= MPD_IDLE_PLAYER; return database_queue_crop(srv->db); @@ -414,8 +402,7 @@ command_move(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) } bool -command_help(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_help(struct lkt_state *srv, size_t c, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { struct lkt_message *out; out = lkt_message_new(); @@ -593,8 +580,7 @@ command_find(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX], } bool -command_plt_list(struct lkt_state *srv, size_t c, - char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX], +command_plt_list(struct lkt_state *srv, size_t c, char UNUSED *args[LKT_MESSAGE_ARGS_MAX], int cont) { struct lkt_search search = { @@ -628,11 +614,10 @@ command_plt_ctx(struct lkt_state *srv, size_t c, } bool -command_set_playback_option(struct lkt_state *srv, size_t c, enum lkt_playback_option opt, +command_set_playback_option(struct lkt_state *srv, size_t UNUSED c, enum lkt_playback_option opt, char *args[LKT_MESSAGE_MAX]) { RETURN_UNLESS(srv, "Invalid argument", false); - UNUSED(c); long val; char *endptr, ret = false; @@ -798,7 +783,7 @@ command_plt_add_uri(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) } bool -command_shuffle(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX]) +command_shuffle(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX]) { RETURN_UNLESS(database_queue_shuffle(srv->db), "Failed to shuffle", false); srv->mpd_idle_events |= MPD_IDLE_PLAYER; @@ -888,9 +873,9 @@ command_user_add(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MA /* Stickers */ static bool -sticker_send(struct lkt_state *srv, size_t c, char *name, char *type, int id, int value) +sticker_send(struct lkt_state *srv, size_t c, char *name, char UNUSED *type, + int id, int value) { - UNUSED(type); struct lkt_message *msg = lkt_message_new(); msg->data_len = safe_snprintf(msg->data, LKT_MESSAGE_ARGS_MAX, "%d: %s -> %d\n", id, name, value); lkt_state_send(srv, c, msg); diff --git a/src/main/lkt.c b/src/main/lkt.c index ade01eadd79185d9367f69b4c35b7467a26e1155..f6c0987ca2c0b8398f4edb2abee19296cb914196 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -947,7 +947,7 @@ search_get__(struct cmd_args *args) exit(EXIT_SUCCESS); else if (STR_NMATCH(buff, "ACK", 3)) exit(EXIT_FAILURE); - UNUSED(write(1, buff, strlen(buff))); + (void) write(1, buff, strlen(buff)); } } diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c index 8825ee294c37f988e19ed897809e69ca7bfe34e9..ff9d752a98775409ca5d747b30941ab368f35654 100644 --- a/src/module/module_sdl2.c +++ b/src/module/module_sdl2.c @@ -62,24 +62,21 @@ static bool module_sdl2_new(struct module_sdl2_window **, struct queue *, volati *********************/ static inline void * -get_proc_address_mpv(void *fn_ctx, const char *name) +get_proc_address_mpv(void UNUSED *fn_ctx, const char *name) { - UNUSED(fn_ctx); return SDL_GL_GetProcAddress(name); } static inline void -on_mpv_events(void *ctx) +on_mpv_events(void UNUSED *ctx) { - UNUSED(ctx); SDL_Event event = { .type = wakeup_on_mpv_events }; SDL_PushEvent(&event); } static inline void -on_mpv_render_update(void *ctx) +on_mpv_render_update(void UNUSED *ctx) { - UNUSED(ctx); SDL_Event event = { .type = wakeup_on_mpv_render_update }; SDL_PushEvent(&event); } diff --git a/src/net/listen.c b/src/net/listen.c index 0a227239af1257c790507f9183500eeb51a39323..4e81d14b8d02b5631235ad35dc493d64adb16aca 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -9,6 +9,7 @@ #include <sqlite3.h> +#include <signal.h> #include <strings.h> #include <sched.h> #include <arpa/inet.h> @@ -788,6 +789,102 @@ redo: goto redo; } +/******************* + * Signal handlers * + *******************/ + +static int __lkt_signal_INT = 0; /* SIGINT => close the server */ +static int __lkt_signal_QUIT = 0; /* SIGQUIT => close the server */ +static int __lkt_signal_ILL = 0; /* SIGILL => NoT veRy HappY */ +static int __lkt_signal_USR1 = 0; /* SIGUSR1 => not used */ +static int __lkt_signal_USR2 = 0; /* SIGUSR2 => not used */ + +static void +__signal_handler(int sig) +{ +#define __HANDLE(signal) \ + case SIG##signal: \ + LOG_INFO("SIGNAL", "Got signal SIG"#signal); \ + __lkt_signal_##signal = 1; \ + break; + + switch (sig) { + __HANDLE(INT) + __HANDLE(ILL) + __HANDLE(QUIT) + __HANDLE(USR1) + __HANDLE(USR2) + default: + LOG_WARN("SIGNAL", "Not handled signal %d", sig); + break; + } + +#undef __HANDLE +} + +static void +__lkt_handle_INT(struct lkt_state *srv) +{ + LOG_INFO("GENERAL", "Stopping lektord"); + MOD_PROC(srv->repo_mod, "free"); + MOD_PROC(srv->window_mod, "free"); + close(srv->fds[0].fd); + lkt_queue_free(&srv->queue); + database_close_all(); + LOG_INFO("GENERAL", "lektord will now exit"); + + /* Register default handle for SIGINT, so if you double ctrl+c it exit like + * it crashed. */ + LOG_INFO("SIGNAL", "Now use default handler for SIGINT and SIGQUIT"); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + + exit(EXIT_SUCCESS); +} + +static void +__lkt_handle_ILL(struct lkt_state UNUSED *srv) +{ + LOG_ERROR("SIGNAL", "Handle the SIGILL, I will try to exit normally"); + __lkt_handle_INT(srv); +} + +static void +__lkt_handle_USR1(struct lkt_state UNUSED *srv) +{ +} + +static void +__lkt_handle_USR2(struct lkt_state UNUSED *srv) +{ +} + +static inline void +handle_signals(struct lkt_state *srv) +{ +#define __HANDLE(srv, signal) \ + if (__lkt_signal_##signal) { \ + LOG_INFO("SIGNAL", "Server in handle phase for signal SIG"#signal); \ + if (srv->__signal_##signal) \ + srv->__signal_##signal(srv); \ + else \ + LOG_WARN("SIGNAL", "No signal handler in server for SIG"#signal); \ + } \ + __lkt_signal_##signal = 0; + + __HANDLE(srv, INT) + __HANDLE(srv, ILL) + __HANDLE(srv, QUIT) + __HANDLE(srv, USR1) + __HANDLE(srv, USR2) + +#undef __HANDLE +} + +/**************************** + * The server main function * + ****************************/ + void lkt_listen(struct lkt_state *srv) { @@ -796,6 +893,19 @@ lkt_listen(struct lkt_state *srv) srv->clients = calloc(srv->fds_max, sizeof(struct lkt_client)); memset(srv->clients, 0, srv->fds_max * sizeof(struct lkt_client)); + LOG_INFO("SIGNAL", "Register signal handlers for signals..."); + srv->__signal_INT = __lkt_handle_INT; + srv->__signal_QUIT = __lkt_handle_INT; + srv->__signal_USR1 = __lkt_handle_USR1; + srv->__signal_USR2 = __lkt_handle_USR2; + srv->__signal_ILL = __lkt_handle_ILL; + signal(SIGINT, __signal_handler); + signal(SIGILL, __signal_handler); + signal(SIGUSR1, __signal_handler); + signal(SIGUSR2, __signal_handler); + signal(SIGQUIT, __signal_handler); + LOG_INFO("SIGNAL", "Signal handlers registered"); + if ((srv->fds[0].fd = init_listening_socket(srv->host, srv->port)) < 0) return; @@ -810,6 +920,7 @@ lkt_listen(struct lkt_state *srv) /* Listen */ for (;;) { + handle_signals(srv); if (handle_network_events(srv) < 0) break; if (handle_idle_events(srv) < 0)