1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-16 04:03:02 +01:00

better handling of fatal errors

This commit is contained in:
Jfreegman 2014-06-18 15:54:05 -04:00
parent 72e9e7d9c4
commit 58a131426a
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
10 changed files with 106 additions and 143 deletions

View File

@ -874,11 +874,8 @@ static void chat_onInit(ToxWindow *self, Tox *m)
ctx->hst = malloc(sizeof(struct history)); ctx->hst = malloc(sizeof(struct history));
ctx->log = malloc(sizeof(struct chatlog)); ctx->log = malloc(sizeof(struct chatlog));
if (ctx->log == NULL || ctx->hst == NULL) { if (ctx->log == NULL || ctx->hst == NULL)
endwin(); exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(ctx->hst, 0, sizeof(struct history)); memset(ctx->hst, 0, sizeof(struct history));
memset(ctx->log, 0, sizeof(struct chatlog)); memset(ctx->log, 0, sizeof(struct chatlog));
@ -951,9 +948,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
ret.chatwin = chatwin; ret.chatwin = chatwin;
ret.stb = stb; ret.stb = stb;
} else { } else {
endwin(); exit_toxic_err("failed in new_chat", FATALERR_MEMORY);
fprintf(stderr, "calloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
} }
ret.num = friendnum; ret.num = friendnum;

View File

@ -57,7 +57,7 @@ static struct dns3_server {
}, },
}; };
struct _thread_data { static struct _thread_data {
ToxWindow *self; ToxWindow *self;
uint8_t id_bin[TOX_FRIEND_ADDRESS_SIZE]; uint8_t id_bin[TOX_FRIEND_ADDRESS_SIZE];
uint8_t addr[MAX_STR_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) void dns3_lookup(ToxWindow *self, Tox *m, uint8_t *id_bin, uint8_t *addr, uint8_t *msg)
{ {
if (t_data.busy) { 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); line_info_add(self, NULL, NULL, NULL, err, SYS_MSG, 0, 0);
return; 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.m = m;
t_data.busy = 1; t_data.busy = 1;
if (pthread_create(&dns_thread.tid, NULL, dns3_lookup_thread, NULL) != 0) { if (pthread_create(&dns_thread.tid, NULL, dns3_lookup_thread, NULL) != 0)
endwin(); exit_toxic_err("failed in dns3_lookup", FATALERR_THREAD_CREATE);
fprintf(stderr, "DNS thread creation failed. Aborting...\n");
exit(EXIT_FAILURE);
}
if (pthread_mutex_init(&dns_thread.lock, NULL) != 0) { if (pthread_mutex_init(&dns_thread.lock, NULL) != 0)
endwin(); exit_toxic_err("failed in dns3_lookup", FATALERR_MUTEX_INIT);
fprintf(stderr, "DNS thread mutex creation failed. Aborting...\n");
exit(EXIT_FAILURE);
}
} }

View File

@ -56,7 +56,7 @@ extern struct user_settings *user_settings;
ToxicFriend friends[MAX_FRIENDS_NUM]; ToxicFriend friends[MAX_FRIENDS_NUM];
static int friendlist_index[MAX_FRIENDS_NUM] = {0}; static int friendlist_index[MAX_FRIENDS_NUM] = {0};
struct _pendingDel { static struct _pendingDel {
int num; int num;
bool active; bool active;
} pendingdelete; } pendingdelete;

View File

@ -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]) 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]) void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])

View File

@ -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].peer_name_lengths = malloc(sizeof(uint16_t) * npeers);
groupchats[gnum].oldpeer_name_lengths = malloc(sizeof(uint16_t) * npeers); groupchats[gnum].oldpeer_name_lengths = malloc(sizeof(uint16_t) * npeers);
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 if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL
|| groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) { || groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) {
endwin(); exit_toxic_err("failed in copy_peernames", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
} }
memset(groupchats[gnum].peer_names, 0, sizeof(uint8_t) * npeers * N);
memset(groupchats[gnum].peer_name_lengths, 0, sizeof(uint16_t) * npeers);
uint16_t unknown_len = strlen(UNKNOWN_NAME); uint16_t unknown_len = strlen(UNKNOWN_NAME);
int i; int i;
@ -649,11 +647,8 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
ctx->hst = malloc(sizeof(struct history)); ctx->hst = malloc(sizeof(struct history));
ctx->log = malloc(sizeof(struct chatlog)); ctx->log = malloc(sizeof(struct chatlog));
if (ctx->log == NULL || ctx->hst == NULL) { if (ctx->log == NULL || ctx->hst == NULL)
endwin(); exit_toxic_err("failed in groupchat_onInit", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(ctx->hst, 0, sizeof(struct history)); memset(ctx->hst, 0, sizeof(struct history));
memset(ctx->log, 0, sizeof(struct chatlog)); 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)); ChatContext *chatwin = calloc(1, sizeof(ChatContext));
if (chatwin != NULL) if (chatwin == NULL)
ret.chatwin = chatwin; exit_toxic_err("failed in new_group_chat", FATALERR_MEMORY);
else {
endwin();
fprintf(stderr, "calloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
ret.chatwin = chatwin;
ret.num = groupnum; ret.num = groupnum;
return ret; return ret;

View File

@ -40,11 +40,8 @@ void line_info_init(struct history *hst)
{ {
hst->line_root = malloc(sizeof(struct line_info)); hst->line_root = malloc(sizeof(struct line_info));
if (hst->line_root == NULL) { if (hst->line_root == NULL)
endwin(); exit_toxic_err("failed in line_info_init", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(hst->line_root, 0, sizeof(struct line_info)); memset(hst->line_root, 0, sizeof(struct line_info));
hst->line_start = hst->line_root; 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 history *hst = self->chatwin->hst;
struct line_info *new_line = malloc(sizeof(struct line_info)); struct line_info *new_line = malloc(sizeof(struct line_info));
if (new_line == NULL) { if (new_line == NULL)
endwin(); exit_toxic_err("failed in line_info_add", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(new_line, 0, sizeof(struct line_info)); memset(new_line, 0, sizeof(struct line_info));

View File

@ -468,11 +468,8 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
ctx->log = malloc(sizeof(struct chatlog)); ctx->log = malloc(sizeof(struct chatlog));
ctx->hst = malloc(sizeof(struct history)); ctx->hst = malloc(sizeof(struct history));
if (ctx->log == NULL || ctx->hst == NULL) { if (ctx->log == NULL || ctx->hst == NULL)
endwin(); exit_toxic_err("failed in prompt_onInit", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(ctx->log, 0, sizeof(struct chatlog)); memset(ctx->log, 0, sizeof(struct chatlog));
memset(ctx->hst, 0, sizeof(struct history)); memset(ctx->hst, 0, sizeof(struct history));
@ -508,14 +505,11 @@ ToxWindow new_prompt(void)
ChatContext *chatwin = calloc(1, sizeof(ChatContext)); ChatContext *chatwin = calloc(1, sizeof(ChatContext));
StatusBar *stb = calloc(1, sizeof(StatusBar)); StatusBar *stb = calloc(1, sizeof(StatusBar));
if (stb != NULL && chatwin != NULL) { if (stb == NULL || chatwin == NULL)
exit_toxic_err("failed in new_prompt", FATALERR_MEMORY);
ret.chatwin = chatwin; ret.chatwin = chatwin;
ret.stb = stb; ret.stb = stb;
} else {
endwin();
fprintf(stderr, "calloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
return ret; return ret;
} }

View File

@ -89,18 +89,47 @@ static void ignore_SIGINT(int sig)
return; 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) static void init_term(void)
{ {
signal(SIGWINCH, on_window_resize); signal(SIGWINCH, on_window_resize);
#if HAVE_WIDECHAR #if HAVE_WIDECHAR
if (setlocale(LC_ALL, "") == NULL) { if (setlocale(LC_ALL, "") == NULL)
fprintf(stderr, "Could not set your locale, plese check your locale settings or" exit_toxic_err("Could not set your locale, plese check your locale settings or"
"disable wide char support\n"); "disable wide char support", FATALERR_LOCALE_SET);
exit(EXIT_FAILURE);
}
#endif #endif
initscr(); initscr();
@ -394,17 +423,13 @@ static void load_data(Tox *m, char *path)
if (buf == NULL) { if (buf == NULL) {
fclose(fd); fclose(fd);
endwin(); exit_toxic_err("failed in load_data", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
} }
if (fread(buf, len, 1, fd) != 1) { if (fread(buf, len, 1, fd) != 1) {
free(buf); free(buf);
fclose(fd); fclose(fd);
endwin(); exit_toxic_err("failed in load_data", FATALERR_FREAD);
fprintf(stderr, "fread() failed. Aborting...\n");
exit(EXIT_FAILURE);
} }
tox_load(m, buf, len); tox_load(m, buf, len);
@ -415,33 +440,9 @@ static void load_data(Tox *m, char *path)
} else { } else {
int st; int st;
if ((st = store_data(m, path)) != 0) { if ((st = store_data(m, path)) == 0)
endwin(); exit_toxic_err("failed in load_data", FATALERR_STORE_DATA);
fprintf(stderr, "Store messenger failed with return code: %d\n", st);
exit(EXIT_FAILURE);
} }
}
}
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) static void do_toxic(Tox *m, ToxWindow *prompt)
@ -523,7 +524,7 @@ static void parse_args(int argc, char *argv[])
case 'h': case 'h':
default: default:
print_usage(); print_usage();
exit(EXIT_FAILURE); exit(EXIT_SUCCESS);
} }
} }
} }
@ -548,15 +549,12 @@ int main(int argc, char *argv[])
} else { } else {
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
if (DATA_FILE != NULL) { if (DATA_FILE == NULL)
exit_toxic_err("failed in main", FATALERR_MEMORY);
strcpy(DATA_FILE, user_config_dir); strcpy(DATA_FILE, user_config_dir);
strcat(DATA_FILE, CONFIGDIR); strcat(DATA_FILE, CONFIGDIR);
strcat(DATA_FILE, "data"); strcat(DATA_FILE, "data");
} else {
endwin();
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
} }
} }
@ -565,11 +563,8 @@ int main(int argc, char *argv[])
/* init user_settings struct and load settings from conf file */ /* init user_settings struct and load settings from conf file */
user_settings = malloc(sizeof(struct user_settings)); user_settings = malloc(sizeof(struct user_settings));
if (user_settings == NULL) { if (user_settings == NULL)
endwin(); exit_toxic_err("failed in main", FATALERR_MEMORY);
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(user_settings, 0, sizeof(struct user_settings)); 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); Tox *m = init_tox(arg_opts.use_ipv4);
init_term(); init_term();
if (m == NULL) { if (m == NULL)
endwin(); exit_toxic_err("failed in main", FATALERR_NETWORKINIT);
fprintf(stderr, "Failed to initialize network. Aborting...\n");
exit(EXIT_FAILURE);
}
if (!arg_opts.ignore_data_file) if (!arg_opts.ignore_data_file)
load_data(m, DATA_FILE); load_data(m, DATA_FILE);
@ -591,17 +583,12 @@ int main(int argc, char *argv[])
prompt = init_windows(m); prompt = init_windows(m);
/* create new thread for ncurses stuff */ /* create new thread for ncurses stuff */
if (pthread_mutex_init(&Winthread.lock, NULL) != 0) { if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
endwin(); exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);
fprintf(stderr, "Mutex init 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);
if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) {
endwin();
fprintf(stderr, "Thread creation failed. Aborting...\n");
exit(EXIT_FAILURE);
}
uint8_t *msg; uint8_t *msg;

View File

@ -42,7 +42,6 @@
#define TIME_STR_SIZE 16 #define TIME_STR_SIZE 16
#define EXIT_SUCCESS 0 #define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
/* ASCII key codes */ /* ASCII key codes */
#define T_KEY_KILL 0x0B /* ctrl-k */ #define T_KEY_KILL 0x0B /* ctrl-k */
@ -60,10 +59,25 @@ enum {
MOVE_DOWN, MOVE_DOWN,
} KEY_DIRS; } 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. /* Fixes text color problem on some terminals.
Uncomment if necessary */ Uncomment if necessary */
/* #define URXVT_FIX */ /* #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_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_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); void on_message(Tox *m, int32_t friendnumber, uint8_t *string, uint16_t length, void *userdata);

View File

@ -284,11 +284,8 @@ void set_next_window(int ch)
if (active_window->window) if (active_window->window)
return; return;
if (active_window == inf) { /* infinite loop check */ if (active_window == inf) /* infinite loop check */
endwin(); exit_toxic_err("failed in set_next_window", FATALERR_INFLOOP);
fprintf(stderr, "set_next_window() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
} }
} }
@ -304,11 +301,8 @@ ToxWindow *init_windows(Tox *m)
{ {
int n_prompt = add_window(m, new_prompt()); int n_prompt = add_window(m, new_prompt());
if (n_prompt == -1 || add_window(m, new_friendlist()) == -1) { if (n_prompt == -1 || add_window(m, new_friendlist()) == -1)
endwin(); exit_toxic_err("failed in init_windows", FATALERR_WININIT);
fprintf(stderr, "add_window() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
prompt = &windows[n_prompt]; prompt = &windows[n_prompt];
active_window = prompt; active_window = prompt;