diff --git a/src/common.h b/src/common.h index a8d7b1c6..cb3155e4 100644 --- a/src/common.h +++ b/src/common.h @@ -152,8 +152,6 @@ typedef enum { RESOURCE_XA } resource_presence_t; -extern gboolean background_mode; - gboolean string_to_verbosity(const char* cmd, int* verbosity, gchar** err_msg); gboolean create_dir(const char* name); diff --git a/src/profanity.c b/src/profanity.c index c31bac14..f841f158 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -70,9 +70,6 @@ static void _connect_default(const char* const account); pthread_mutex_t lock; static gboolean force_quit = FALSE; -// main.c (prof_run section) -gboolean background_mode = FALSE; - void prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_file, gchar* theme_name, gchar** commands) { @@ -98,44 +95,42 @@ prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_f log_stderr_handler(); session_check_autoaway(); - if (!background_mode) { - line = commands ? *commands : inp_readline(); - if (commands && line && memcmp(line, "/sleep", 6) == 0) { - if (!g_timer_is_active(waittimer)) { - gchar* err_msg; - if (strtoi_range(line + 7, &waittime, 0, 300, &err_msg)) { - g_timer_start(waittimer); - /* Increase the minimal runtime by the waiting time - * so we can be sure there's runtime left after executing - * the last command. - */ - min_runtime += waittime; - } else { - log_error("%s", err_msg); - g_free(err_msg); - commands = NULL; - } - } else if (g_timer_elapsed(waittimer, NULL) >= waittime) { - g_timer_stop(waittimer); - commands++; - if (!(*commands)) - commands = NULL; - } - cont = TRUE; - } else if (line) { - ProfWin* window = wins_get_current(); - cont = cmd_process_input(window, line); - if (commands) { - commands++; - if (!(*commands)) - commands = NULL; + line = commands ? *commands : inp_readline(); + if (commands && line && memcmp(line, "/sleep", 6) == 0) { + if (!g_timer_is_active(waittimer)) { + gchar* err_msg; + if (strtoi_range(line + 7, &waittime, 0, 300, &err_msg)) { + g_timer_start(waittimer); + /* Increase the minimal runtime by the waiting time + * so we can be sure there's runtime left after executing + * the last command. + */ + min_runtime += waittime; } else { - free(line); - line = NULL; + log_error("%s", err_msg); + g_free(err_msg); + commands = NULL; } - } else { - cont = TRUE; + } else if (g_timer_elapsed(waittimer, NULL) >= waittime) { + g_timer_stop(waittimer); + commands++; + if (!(*commands)) + commands = NULL; } + cont = TRUE; + } else if (line) { + ProfWin* window = wins_get_current(); + cont = cmd_process_input(window, line); + if (commands) { + commands++; + if (!(*commands)) + commands = NULL; + } else { + free(line); + line = NULL; + } + } else { + cont = TRUE; } #ifdef HAVE_LIBOTR @@ -146,11 +141,7 @@ prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_f session_process_events(); iq_autoping_check(); - editor_process(wins_get_current()); - - if (!background_mode) { - ui_update(); - } + ui_update(); while (g_main_context_iteration(NULL, FALSE)) ; #ifdef HAVE_GTK diff --git a/src/tools/editor.c b/src/tools/editor.c index 344e666b..5fbbc871 100644 --- a/src/tools/editor.c +++ b/src/tools/editor.c @@ -69,183 +69,6 @@ _editor_exit_cb(GPid pid, gint status, gpointer data) g_spawn_close_pid(pid); } -EditorTask editor_task = { 0, FALSE, NULL, NULL, PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL }; - -void* -editor_thread(void* arg) -{ - EditorTask* task = (EditorTask*)arg; - auto_gcharv gchar** argv = g_strsplit(task->editor_cmd, " ", 0); - - pid_t pid = fork(); - if (pid == 0) { - execvp(argv[0], argv); - log_error("[Editor] Failed to exec %s", argv[0]); - _exit(EXIT_FAILURE); - } - - pthread_mutex_lock(&task->mutex); - if (pid > 0) { - task->pid = pid; - int status; - // Unlock mutex to avoid deadlock on the main loop - pthread_mutex_unlock(&task->mutex); - waitpid(pid, &status, 0); - pthread_mutex_lock(&task->mutex); - - gsize length; - if (!g_file_get_contents(task->filename, &task->result, &length, &task->error)) { - log_error("[Editor] could not read from %s: %s", task->filename, - task->error ? task->error->message : "No GLib error given"); - task->result = g_strdup(""); // Ensure valid result - } else { - g_strchomp(task->result); - if (remove(task->filename) != 0) { - log_error("[Editor] error during file deletion of %s", task->filename); - } else { - log_debug("[Editor] deleted file: %s", task->filename); - } - } - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - task->error = g_error_new(G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Editor process failed with status %d", WEXITSTATUS(status)); - } - } else { - task->error = g_error_new(G_FILE_ERROR, G_FILE_ERROR_FAILED, "Fork failed: %s", strerror(errno)); - task->result = g_strdup(""); // Ensure valid result - } - - task->active = FALSE; - pthread_mutex_unlock(&task->mutex); - - return NULL; -} - -// Returns true if an error occurred -gboolean -get_message_from_editor_async(gchar* message) -{ - // Check if editor is already running - pthread_mutex_lock(&editor_task.mutex); - if (editor_task.active) { - pthread_mutex_unlock(&editor_task.mutex); - log_error("[Editor] Editor already running"); - return TRUE; - } - pthread_mutex_unlock(&editor_task.mutex); - - // Create temporary file - auto_gchar gchar* filename = NULL; - GError* glib_error = NULL; - const char* jid = connection_get_barejid(); - if (jid) { - filename = files_file_in_account_data_path(DIR_EDITOR, jid, "compose.md"); - } else { - log_debug("[Editor] could not get JID"); - auto_gchar gchar* data_dir = files_get_data_path(DIR_EDITOR); - if (!create_dir(data_dir)) { - log_error("[Editor] could not create directory %s", data_dir); - return TRUE; - } - filename = g_strdup_printf("%s/compose.md", data_dir); - } - if (!filename) { - log_error("[Editor] something went wrong while creating compose file"); - return TRUE; - } - - // Write message to file - gsize messagelen = message ? strlen(message) : 0; - if (!g_file_set_contents(filename, message ? message : "", messagelen, &glib_error)) { - log_error("[Editor] could not write to %s: %s", filename, - glib_error ? glib_error->message : "No GLib error given"); - if (glib_error) { - g_error_free(glib_error); - } - return TRUE; - } - - // Prepare editor command - auto_gchar gchar* editor = prefs_get_string(PREF_COMPOSE_EDITOR); - auto_gchar gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename); - - // Suspend NCurses - def_prog_mode(); - endwin(); - - // Initialize thread task - pthread_mutex_lock(&editor_task.mutex); - editor_task.active = TRUE; - editor_task.result = NULL; - editor_task.error = NULL; - g_free(editor_task.filename); - g_free(editor_task.editor_cmd); - editor_task.filename = g_strdup(filename); - editor_task.editor_cmd = g_strdup(editor_with_filename); - pthread_mutex_unlock(&editor_task.mutex); - - // Set background mode - background_mode = TRUE; - log_debug("[Editor] Entering background mode"); - - // Start editor thread - if (pthread_create(&editor_task.thread, NULL, editor_thread, &editor_task) != 0) { - pthread_mutex_lock(&editor_task.mutex); - editor_task.active = FALSE; - editor_task.error = g_error_new(G_FILE_ERROR, G_FILE_ERROR_FAILED, - "Failed to create editor thread: %s", strerror(errno)); - g_free(editor_task.filename); - g_free(editor_task.editor_cmd); - editor_task.filename = NULL; - editor_task.editor_cmd = NULL; - pthread_mutex_unlock(&editor_task.mutex); - background_mode = FALSE; - log_debug("[Editor] Exiting background mode"); - reset_prog_mode(); - doupdate(); - log_error("[Editor] Failed to create editor thread"); - return TRUE; - } - - return FALSE; -} - -void -editor_process(ProfWin* window) -{ - pthread_mutex_lock(&editor_task.mutex); - if (editor_task.active) { - pthread_mutex_unlock(&editor_task.mutex); - return; - } - if (!editor_task.result) { - pthread_mutex_unlock(&editor_task.mutex); - return; - } - - g_strchomp(editor_task.result); - rl_replace_line(editor_task.result, 0); - rl_point = rl_end; - rl_forced_update_display(); - reset_prog_mode(); - doupdate(); - ui_resize(); - g_free(editor_task.result); - g_free(editor_task.filename); - g_free(editor_task.editor_cmd); - editor_task.result = NULL; - editor_task.filename = NULL; - editor_task.editor_cmd = NULL; - if (editor_task.error) { - log_error("[Editor] %s", editor_task.error->message); - g_error_free(editor_task.error); - editor_task.error = NULL; - } - pthread_mutex_unlock(&editor_task.mutex); - background_mode = FALSE; - log_debug("[Editor] Exiting background mode"); -} - // Returns a message via callback once the editor is closed. // Returns true if an error occurred. gboolean diff --git a/src/tools/editor.h b/src/tools/editor.h index 9e47ebfb..a6ef0cef 100644 --- a/src/tools/editor.h +++ b/src/tools/editor.h @@ -13,23 +13,7 @@ #include "ui/win_types.h" #include -typedef struct -{ - pid_t pid; // Editor process PID - gboolean active; // Thread running - gchar* result; // Edited message - GError* error; // Error if any - pthread_mutex_t mutex; // Protect access - pthread_t thread; // Editor thread - gchar* filename; // Temporary file path - gchar* editor_cmd; // Editor command with filename -} EditorTask; -extern EditorTask editor_task; - -gboolean get_message_from_editor(gchar* message, gchar** returned_message); -gboolean get_message_from_editor_async(gchar* message); -void editor_process(ProfWin* window); gboolean launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* data), void* user_data); #endif diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c index 0a9ea14d..a741627a 100644 --- a/src/xmpp/roster_list.c +++ b/src/xmpp/roster_list.c @@ -113,6 +113,7 @@ roster_destroy(void) roster_pending_presence = NULL; } +// Consumes `resource` on every return path. Callers must null their own pointer afterwards. gboolean roster_update_presence(const char* const barejid, Resource* resource, GDateTime* last_activity) { @@ -135,9 +136,7 @@ roster_update_presence(const char* const barejid, Resource* resource, GDateTime* PContact contact = roster_get_contact(barejid); if (contact == NULL) { - /* Don't lose resource when there is no owner. */ resource_destroy(resource); - resource = NULL; return FALSE; } if (!_datetimes_equal(p_contact_last_activity(contact), last_activity)) {