From 58a131426a9171528c51c0915b8b249903bca37a Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Wed, 18 Jun 2014 15:54:05 -0400 Subject: [PATCH] better handling of fatal errors --- src/chat.c | 11 ++-- src/dns.c | 18 +++---- src/friendlist.c | 2 +- src/global_commands.c | 2 +- src/groupchat.c | 29 ++++------ src/line_info.c | 14 ++--- src/prompt.c | 20 +++---- src/toxic.c | 123 +++++++++++++++++++----------------------- src/toxic.h | 16 +++++- src/windows.c | 14 ++--- 10 files changed, 106 insertions(+), 143 deletions(-) diff --git a/src/chat.c b/src/chat.c index be5eb4a..f64c8ae 100644 --- a/src/chat.c +++ b/src/chat.c @@ -874,11 +874,8 @@ static void chat_onInit(ToxWindow *self, Tox *m) ctx->hst = malloc(sizeof(struct history)); ctx->log = malloc(sizeof(struct chatlog)); - if (ctx->log == NULL || ctx->hst == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (ctx->log == NULL || ctx->hst == NULL) + exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY); memset(ctx->hst, 0, sizeof(struct history)); memset(ctx->log, 0, sizeof(struct chatlog)); @@ -951,9 +948,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum) ret.chatwin = chatwin; ret.stb = stb; } else { - endwin(); - fprintf(stderr, "calloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); + exit_toxic_err("failed in new_chat", FATALERR_MEMORY); } ret.num = friendnum; diff --git a/src/dns.c b/src/dns.c index e9a266a..ba7f5f1 100644 --- a/src/dns.c +++ b/src/dns.c @@ -57,7 +57,7 @@ static struct dns3_server { }, }; -struct _thread_data { +static struct _thread_data { ToxWindow *self; uint8_t id_bin[TOX_FRIEND_ADDRESS_SIZE]; uint8_t addr[MAX_STR_SIZE]; @@ -276,7 +276,7 @@ void *dns3_lookup_thread(void *data) void dns3_lookup(ToxWindow *self, Tox *m, uint8_t *id_bin, uint8_t *addr, uint8_t *msg) { if (t_data.busy) { - uint8_t *err = "Please wait for previous DNS lookup to finish."; + uint8_t *err = "Please wait for previous user lookup to finish."; line_info_add(self, NULL, NULL, NULL, err, SYS_MSG, 0, 0); return; } @@ -288,15 +288,9 @@ void dns3_lookup(ToxWindow *self, Tox *m, uint8_t *id_bin, uint8_t *addr, uint8_ t_data.m = m; t_data.busy = 1; - if (pthread_create(&dns_thread.tid, NULL, dns3_lookup_thread, NULL) != 0) { - endwin(); - fprintf(stderr, "DNS thread creation failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (pthread_create(&dns_thread.tid, NULL, dns3_lookup_thread, NULL) != 0) + exit_toxic_err("failed in dns3_lookup", FATALERR_THREAD_CREATE); - if (pthread_mutex_init(&dns_thread.lock, NULL) != 0) { - endwin(); - fprintf(stderr, "DNS thread mutex creation failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (pthread_mutex_init(&dns_thread.lock, NULL) != 0) + exit_toxic_err("failed in dns3_lookup", FATALERR_MUTEX_INIT); } diff --git a/src/friendlist.c b/src/friendlist.c index 9e602a6..19e35c7 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -56,7 +56,7 @@ extern struct user_settings *user_settings; ToxicFriend friends[MAX_FRIENDS_NUM]; static int friendlist_index[MAX_FRIENDS_NUM] = {0}; -struct _pendingDel { +static struct _pendingDel { int num; bool active; } pendingdelete; diff --git a/src/global_commands.c b/src/global_commands.c index 59235d0..cb0aa52 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -438,7 +438,7 @@ void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a void cmd_quit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { - exit_toxic(m); + exit_toxic_success(m); } void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) diff --git a/src/groupchat.c b/src/groupchat.c index eb79fc0..2a048a1 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -260,16 +260,14 @@ static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], ui groupchats[gnum].peer_name_lengths = malloc(sizeof(uint16_t) * npeers); groupchats[gnum].oldpeer_name_lengths = malloc(sizeof(uint16_t) * npeers); + if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL + || groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) { + exit_toxic_err("failed in copy_peernames", FATALERR_MEMORY); + } + memset(groupchats[gnum].peer_names, 0, sizeof(uint8_t) * npeers * N); memset(groupchats[gnum].peer_name_lengths, 0, sizeof(uint16_t) * npeers); - if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL - || groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } - uint16_t unknown_len = strlen(UNKNOWN_NAME); int i; @@ -649,11 +647,8 @@ static void groupchat_onInit(ToxWindow *self, Tox *m) ctx->hst = malloc(sizeof(struct history)); ctx->log = malloc(sizeof(struct chatlog)); - if (ctx->log == NULL || ctx->hst == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (ctx->log == NULL || ctx->hst == NULL) + exit_toxic_err("failed in groupchat_onInit", FATALERR_MEMORY); memset(ctx->hst, 0, sizeof(struct history)); memset(ctx->log, 0, sizeof(struct chatlog)); @@ -688,14 +683,10 @@ ToxWindow new_group_chat(Tox *m, int groupnum) ChatContext *chatwin = calloc(1, sizeof(ChatContext)); - if (chatwin != NULL) - ret.chatwin = chatwin; - else { - endwin(); - fprintf(stderr, "calloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (chatwin == NULL) + exit_toxic_err("failed in new_group_chat", FATALERR_MEMORY); + ret.chatwin = chatwin; ret.num = groupnum; return ret; diff --git a/src/line_info.c b/src/line_info.c index b79b61c..a6442f0 100644 --- a/src/line_info.c +++ b/src/line_info.c @@ -40,11 +40,8 @@ void line_info_init(struct history *hst) { hst->line_root = malloc(sizeof(struct line_info)); - if (hst->line_root == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (hst->line_root == NULL) + exit_toxic_err("failed in line_info_init", FATALERR_MEMORY); memset(hst->line_root, 0, sizeof(struct line_info)); hst->line_start = hst->line_root; @@ -133,11 +130,8 @@ void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *na struct history *hst = self->chatwin->hst; struct line_info *new_line = malloc(sizeof(struct line_info)); - if (new_line == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (new_line == NULL) + exit_toxic_err("failed in line_info_add", FATALERR_MEMORY); memset(new_line, 0, sizeof(struct line_info)); diff --git a/src/prompt.c b/src/prompt.c index dbaf731..3609574 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -468,11 +468,8 @@ static void prompt_onInit(ToxWindow *self, Tox *m) ctx->log = malloc(sizeof(struct chatlog)); ctx->hst = malloc(sizeof(struct history)); - if (ctx->log == NULL || ctx->hst == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (ctx->log == NULL || ctx->hst == NULL) + exit_toxic_err("failed in prompt_onInit", FATALERR_MEMORY); memset(ctx->log, 0, sizeof(struct chatlog)); memset(ctx->hst, 0, sizeof(struct history)); @@ -508,14 +505,11 @@ ToxWindow new_prompt(void) ChatContext *chatwin = calloc(1, sizeof(ChatContext)); StatusBar *stb = calloc(1, sizeof(StatusBar)); - if (stb != NULL && chatwin != NULL) { - ret.chatwin = chatwin; - ret.stb = stb; - } else { - endwin(); - fprintf(stderr, "calloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (stb == NULL || chatwin == NULL) + exit_toxic_err("failed in new_prompt", FATALERR_MEMORY); + + ret.chatwin = chatwin; + ret.stb = stb; return ret; } diff --git a/src/toxic.c b/src/toxic.c index 8ee9976..6eb4254 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -89,18 +89,47 @@ static void ignore_SIGINT(int sig) return; } +void exit_toxic_success(Tox *m) +{ + store_data(m, DATA_FILE); + close_all_file_senders(); + kill_all_windows(); + log_disable(prompt->chatwin->log); + line_info_cleanup(prompt->chatwin->hst); + free(DATA_FILE); + free(prompt->stb); + free(prompt->chatwin->log); + free(prompt->chatwin->hst); + free(prompt->chatwin); + free(user_settings); +#ifdef _SUPPORT_AUDIO + terminate_audio(); +#endif /* _SUPPORT_AUDIO */ + tox_kill(m); + endwin(); + fprintf(stderr, "Toxic session ended gracefully.\n"); + exit(EXIT_SUCCESS); +} + +void exit_toxic_err(const char *errmsg, int retcode) +{ + if (errmsg == NULL) + errmsg = "No error message"; + + endwin(); + fprintf(stderr, "Toxic session aborted with return code %d (%s)\n", retcode, errmsg); + exit(retcode); +} + static void init_term(void) { signal(SIGWINCH, on_window_resize); #if HAVE_WIDECHAR - if (setlocale(LC_ALL, "") == NULL) { - fprintf(stderr, "Could not set your locale, plese check your locale settings or" - "disable wide char support\n"); - exit(EXIT_FAILURE); - } - + if (setlocale(LC_ALL, "") == NULL) + exit_toxic_err("Could not set your locale, plese check your locale settings or" + "disable wide char support", FATALERR_LOCALE_SET); #endif initscr(); @@ -394,17 +423,13 @@ static void load_data(Tox *m, char *path) if (buf == NULL) { fclose(fd); - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); + exit_toxic_err("failed in load_data", FATALERR_MEMORY); } if (fread(buf, len, 1, fd) != 1) { free(buf); fclose(fd); - endwin(); - fprintf(stderr, "fread() failed. Aborting...\n"); - exit(EXIT_FAILURE); + exit_toxic_err("failed in load_data", FATALERR_FREAD); } tox_load(m, buf, len); @@ -415,35 +440,11 @@ static void load_data(Tox *m, char *path) } else { int st; - if ((st = store_data(m, path)) != 0) { - endwin(); - fprintf(stderr, "Store messenger failed with return code: %d\n", st); - exit(EXIT_FAILURE); - } + if ((st = store_data(m, path)) == 0) + exit_toxic_err("failed in load_data", FATALERR_STORE_DATA); } } -void exit_toxic(Tox *m) -{ - store_data(m, DATA_FILE); - close_all_file_senders(); - kill_all_windows(); - log_disable(prompt->chatwin->log); - line_info_cleanup(prompt->chatwin->hst); - free(DATA_FILE); - free(prompt->stb); - free(prompt->chatwin->log); - free(prompt->chatwin->hst); - free(prompt->chatwin); - free(user_settings); -#ifdef _SUPPORT_AUDIO - terminate_audio(); -#endif /* _SUPPORT_AUDIO */ - tox_kill(m); - endwin(); - exit(EXIT_SUCCESS); -} - static void do_toxic(Tox *m, ToxWindow *prompt) { pthread_mutex_lock(&Winthread.lock); @@ -523,7 +524,7 @@ static void parse_args(int argc, char *argv[]) case 'h': default: print_usage(); - exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); } } } @@ -548,15 +549,12 @@ int main(int argc, char *argv[]) } else { DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); - if (DATA_FILE != NULL) { - strcpy(DATA_FILE, user_config_dir); - strcat(DATA_FILE, CONFIGDIR); - strcat(DATA_FILE, "data"); - } else { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (DATA_FILE == NULL) + exit_toxic_err("failed in main", FATALERR_MEMORY); + + strcpy(DATA_FILE, user_config_dir); + strcat(DATA_FILE, CONFIGDIR); + strcat(DATA_FILE, "data"); } } @@ -565,11 +563,8 @@ int main(int argc, char *argv[]) /* init user_settings struct and load settings from conf file */ user_settings = malloc(sizeof(struct user_settings)); - if (user_settings == NULL) { - endwin(); - fprintf(stderr, "malloc() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (user_settings == NULL) + exit_toxic_err("failed in main", FATALERR_MEMORY); memset(user_settings, 0, sizeof(struct user_settings)); @@ -579,11 +574,8 @@ int main(int argc, char *argv[]) Tox *m = init_tox(arg_opts.use_ipv4); init_term(); - if (m == NULL) { - endwin(); - fprintf(stderr, "Failed to initialize network. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (m == NULL) + exit_toxic_err("failed in main", FATALERR_NETWORKINIT); if (!arg_opts.ignore_data_file) load_data(m, DATA_FILE); @@ -591,17 +583,12 @@ int main(int argc, char *argv[]) prompt = init_windows(m); /* create new thread for ncurses stuff */ - if (pthread_mutex_init(&Winthread.lock, NULL) != 0) { - endwin(); - fprintf(stderr, "Mutex init failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (pthread_mutex_init(&Winthread.lock, NULL) != 0) + exit_toxic_err("failed in main", FATALERR_MUTEX_INIT); - if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) { - endwin(); - fprintf(stderr, "Thread creation failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) + exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); + uint8_t *msg; diff --git a/src/toxic.h b/src/toxic.h index 166998d..a6000d9 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -42,7 +42,6 @@ #define TIME_STR_SIZE 16 #define EXIT_SUCCESS 0 -#define EXIT_FAILURE 1 /* ASCII key codes */ #define T_KEY_KILL 0x0B /* ctrl-k */ @@ -60,10 +59,25 @@ enum { MOVE_DOWN, } KEY_DIRS; +typedef enum _FATAL_ERRS { + FATALERR_MEMORY = -1, + FATALERR_FREAD = -2, + FATALERR_THREAD_CREATE = -3, + FATALERR_MUTEX_INIT = -4, + FATALERR_LOCALE_SET = -5, + FATALERR_STORE_DATA = -6, + FATALERR_NETWORKINIT = -7, + FATALERR_INFLOOP = -8, + FATALERR_WININIT = -9, +} FATAL_ERRS; + /* Fixes text color problem on some terminals. Uncomment if necessary */ /* #define URXVT_FIX */ +void exit_toxic_success(Tox *m); +void exit_toxic_err(const char *errmsg, int retcode); + void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); void on_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata); void on_message(Tox *m, int32_t friendnumber, uint8_t *string, uint16_t length, void *userdata); diff --git a/src/windows.c b/src/windows.c index 1aa7f2d..1295248 100644 --- a/src/windows.c +++ b/src/windows.c @@ -284,11 +284,8 @@ void set_next_window(int ch) if (active_window->window) return; - if (active_window == inf) { /* infinite loop check */ - endwin(); - fprintf(stderr, "set_next_window() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (active_window == inf) /* infinite loop check */ + exit_toxic_err("failed in set_next_window", FATALERR_INFLOOP); } } @@ -304,11 +301,8 @@ ToxWindow *init_windows(Tox *m) { int n_prompt = add_window(m, new_prompt()); - if (n_prompt == -1 || add_window(m, new_friendlist()) == -1) { - endwin(); - fprintf(stderr, "add_window() failed. Aborting...\n"); - exit(EXIT_FAILURE); - } + if (n_prompt == -1 || add_window(m, new_friendlist()) == -1) + exit_toxic_err("failed in init_windows", FATALERR_WININIT); prompt = &windows[n_prompt]; active_window = prompt;