diff options
author | 2019-05-20 15:42:29 +0300 | |
---|---|---|
committer | 2019-05-20 15:42:29 +0300 | |
commit | 0232ddd00be27f42da43ce9d7312f05580c2ebc6 (patch) | |
tree | c8c6e3ad8d75e0056569ef469ecf8601a2e67eca /src | |
parent | 18953ca0b4742306b36c9abf243ef0599985b45e (diff) | |
download | usurpation-0232ddd00be27f42da43ce9d7312f05580c2ebc6.tar.gz usurpation-0232ddd00be27f42da43ce9d7312f05580c2ebc6.tar.bz2 usurpation-0232ddd00be27f42da43ce9d7312f05580c2ebc6.zip |
daemon: improve cleanup code.
Resolves all memory leaks that can be possibly resolved, glib
nonwithstanding.
Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon/main.c | 19 | ||||
-rw-r--r-- | src/daemon/purple.c | 61 | ||||
-rw-r--r-- | src/daemon/settings.c | 3 | ||||
-rw-r--r-- | src/daemon/settings_private.h | 1 |
4 files changed, 71 insertions, 13 deletions
diff --git a/src/daemon/main.c b/src/daemon/main.c index 41e798b..94e59fd 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -21,11 +21,18 @@ #include <unistd.h> #include <time.h> +#include <stdlib.h> #include <stdio.h> #include "settings.h" #include "net.h" #include "purple.h" +static struct _state { + int nd; +} _progstate; + +void cleanup(void); + /* the logic is a placeholder right now */ int main(int argc, char **argv) { @@ -34,8 +41,9 @@ int main(int argc, char **argv) printf("Usurpation daemon version %s starting\n", version); + atexit(cleanup); settings_init(); - net_init(setting_port()); /* TODO: get port from settings. */ + _progstate.nd = net_init(setting_port()); if (purple_init() && setting_verbose()) { fprintf(stderr, "libpurple initialization failed\n"); } @@ -52,4 +60,13 @@ int main(int argc, char **argv) /* noop */ } + + return 0; +} + +void cleanup(void) +{ + purple_close(); + net_close(_progstate.nd); + settings_cleanup(); } diff --git a/src/daemon/purple.c b/src/daemon/purple.c index 6b73774..882ea61 100644 --- a/src/daemon/purple.c +++ b/src/daemon/purple.c @@ -120,6 +120,35 @@ static void pthread_mutex_unlock_thunk(void *arg) (void) pthread_mutex_unlock(mutex); } +static void purple_account_destroy_thunk(void *arg) +{ + PurpleAccount *account = arg; + + purple_account_destroy(account); +} + +static void purple_core_destroy(void *arg) +{ + (void) arg; + + purple_timeout_add(0, purple_core_quit_cb, NULL); +} + +static void g_main_loop_unref_thunk(void *arg) +{ + GMainLoop *loop = arg; + + g_main_loop_unref(loop); +} + +static void g_main_loop_quit_thunk(void *arg) +{ + GMainLoop *loop = arg; + + g_main_loop_quit(loop); +} + + static void *purple_spawn(void *disregard) { GMainLoop *loop; @@ -131,16 +160,21 @@ static void *purple_spawn(void *disregard) (void) disregard; pthread_cleanup_push(pthread_mutex_unlock_thunk, &state.mutex); - pthread_cleanup_push(free, progname); - pthread_cleanup_push(free, user); - pthread_cleanup_push(free, password); - pthread_cleanup_push(free, proto); progname = setting_progname(); + pthread_cleanup_push(free, progname); + user = setting_im_user(); + pthread_cleanup_push(free, user); + password = setting_im_password(); + pthread_cleanup_push(free, password); + proto = setting_im_proto(); + pthread_cleanup_push(free, proto); + loop = g_main_loop_new(NULL, FALSE); + pthread_cleanup_push(g_main_loop_unref_thunk, loop); /* avoid an unholy army of libpurple's DNS resolver process zombies */ signal(SIGCHLD, SIG_IGN); @@ -158,22 +192,31 @@ static void *purple_spawn(void *disregard) purple_core_set_ui_ops(&core_uiops); purple_eventloop_set_ui_ops(&eventloops); - purple_core_init(setting_progname()); + purple_core_init(progname); purple_prefs_load(); - state.account = purple_account_new(setting_im_user(), setting_im_proto()); - purple_account_set_password(state.account, setting_im_password()); - purple_account_set_enabled(state.account, setting_progname(), TRUE); + pthread_cleanup_push(purple_core_destroy, NULL); + + state.account = purple_account_new(user, proto); + purple_account_set_password(state.account, password); + purple_account_set_enabled(state.account, progname, TRUE); + + pthread_cleanup_push(purple_account_destroy_thunk, state.account); g_main_loop_run(loop); + pthread_cleanup_push(g_main_loop_quit_thunk, loop); pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); - return NULL; + pthread_exit(NULL); } /* diff --git a/src/daemon/settings.c b/src/daemon/settings.c index 5809139..5314fef 100644 --- a/src/daemon/settings.c +++ b/src/daemon/settings.c @@ -38,7 +38,6 @@ */ void settings_init(void) { - atexit(free_strings); unset_flag(flag_daemonize); settings.port = 6996; settings.verboselevel = USURP_VERBOSITY; @@ -220,7 +219,7 @@ static void set_im_proto(const void * const arg) settings.im_proto = strdup(a); } -static void free_strings(void) +void settings_cleanup(void) { free(settings.progname); free(settings.im_user); diff --git a/src/daemon/settings_private.h b/src/daemon/settings_private.h index 3e091ab..69ed25a 100644 --- a/src/daemon/settings_private.h +++ b/src/daemon/settings_private.h @@ -48,7 +48,6 @@ static void set_flag(unsigned int flag); static void unset_flag(unsigned int flag); static int setting_readconf(const char * const path); static int setting_handle_config_entry(const char * const entry, const char * const value); -static void free_strings(void); static void set_daemonize(const void * const arg); static void set_port(const void * const arg); |