refactor(profanity): extract _handle_suspend_signals; tighten comments
All checks were successful
CI Code / Check spelling (pull_request) Successful in 17s
CI Code / Check coding style (pull_request) Successful in 32s
CI Code / Code Coverage (pull_request) Successful in 3m36s
CI Code / Linux (debian) (pull_request) Successful in 4m45s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m56s
CI Code / Linux (arch) (pull_request) Successful in 6m39s

Main loop now calls a single helper for cont/suspend/Ctrl-Z
state instead of inlining the signal-handling block. Comment blocks in
profanity.c / editor.c / inputwin.c shortened to trailing form.
This commit is contained in:
2026-05-31 15:24:12 +03:00
parent b90dec5be3
commit 62d9c57925
3 changed files with 33 additions and 42 deletions

View File

@@ -70,12 +70,38 @@ static void _connect_default(const char* const account);
pthread_mutex_t lock;
static gboolean force_quit = FALSE;
// Signal-driven flags consumed by the main loop. SIGTSTP and a STOPPED editor
// child → drop the process group to the shell (mutt-style). SIGCONT →
// refresh curses on return.
static volatile sig_atomic_t suspend_requested = FALSE;
static volatile sig_atomic_t cont_requested = FALSE;
static void
_handle_suspend_signals(void)
{
if (cont_requested) {
cont_requested = FALSE;
if (!editor_is_active()) {
clearok(stdscr, TRUE);
ui_resize();
}
}
if (editor_check_stopped()) {
log_info("[Editor] stopped; aborting back to profanity");
suspend_requested = FALSE;
editor_emergency_kill();
} else if (suspend_requested) {
suspend_requested = FALSE;
if (editor_is_active()) {
log_info("[Editor] SIGTSTP from vim group; deferring to next poll");
} else {
log_info("[Suspend] dropping to shell");
if (!isendwin()) {
endwin();
}
kill(0, SIGSTOP);
}
}
}
void
prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_file, gchar* theme_name, gchar** commands)
{
@@ -99,36 +125,7 @@ prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_f
int waittime = 0;
while (cont && !force_quit) {
log_stderr_handler();
// Resume from fg after SIGSTOP. Vim handles its own refresh.
if (cont_requested) {
cont_requested = FALSE;
if (!editor_is_active()) {
clearok(stdscr, TRUE);
ui_resize();
}
}
// Editor STOPPED → abort. Plain Ctrl-Z → drop to shell. While editor
// is active, swallow suspend_requested (race: vim's kill(0,SIGTSTP)
// beats waitpid seeing STOPPED) — next poll catches it.
if (editor_check_stopped()) {
log_info("[Editor] stopped; aborting back to profanity");
suspend_requested = FALSE;
editor_emergency_kill();
} else if (suspend_requested) {
suspend_requested = FALSE;
if (editor_is_active()) {
log_info("[Editor] SIGTSTP from vim group; deferring to next poll");
} else {
log_info("[Suspend] dropping to shell");
if (!isendwin()) {
endwin();
}
kill(0, SIGSTOP);
}
}
_handle_suspend_signals();
session_check_autoaway();
line = commands ? *commands : inp_readline();

View File

@@ -32,9 +32,7 @@ typedef struct EditorContext
void* user_data;
} EditorContext;
// Re-entrancy guard (lost in the async-editor rewrite). Prevents a plugin
// from spawning a second editor that would fight the first for the terminal.
static gboolean editor_active = FALSE;
static gboolean editor_active = FALSE; // re-entrancy guard
static pid_t editor_pid = 0;
static void

View File

@@ -320,9 +320,7 @@ inp_get_line(void)
while (!line) {
line = inp_readline();
ui_update();
// Let the editor child watch dispatch — otherwise a prompt raised
// mid-editor-session deadlocks here.
while (g_main_context_iteration(NULL, FALSE))
while (g_main_context_iteration(NULL, FALSE)) // non-blocking; bounded by ready sources
;
}
status_bar_clear_prompt();
@@ -352,9 +350,7 @@ inp_get_password(void)
while (!password) {
password = inp_readline();
ui_update();
// Let the editor child watch dispatch — otherwise a prompt raised
// mid-editor-session deadlocks here.
while (g_main_context_iteration(NULL, FALSE))
while (g_main_context_iteration(NULL, FALSE)) // non-blocking; bounded by ready sources
;
}
get_password = FALSE;