diff --git a/src/tools/editor.c b/src/tools/editor.c index 2974ed74..48a44514 100644 --- a/src/tools/editor.c +++ b/src/tools/editor.c @@ -25,6 +25,8 @@ #include "ui/ui.h" #include "xmpp/xmpp.h" +extern char** environ; + typedef struct EditorContext { gchar* filename; @@ -140,6 +142,22 @@ launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* dat GSource* sigchld_warmup = g_child_watch_source_new(getpid()); g_source_unref(sigchld_warmup); + // Build the editor's env without LINES/COLUMNS pre-fork, so the child only + // reassigns environ instead of calling unsetenv() between fork and exec. + // The editor's (n)curses then reads the live window via ioctl(TIOCGWINSZ). + gsize env_len = 0; + while (environ[env_len]) { + env_len++; + } + gchar** editor_env = g_new0(gchar*, env_len + 1); + gsize env_kept = 0; + for (gsize i = 0; i < env_len; i++) { + if (g_str_has_prefix(environ[i], "LINES=") || g_str_has_prefix(environ[i], "COLUMNS=")) { + continue; + } + editor_env[env_kept++] = environ[i]; + } + pid_t pid = fork(); if (pid == -1) { log_error("[Editor] Failed to fork: %s", strerror(errno)); @@ -148,12 +166,15 @@ launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* dat ui_resize(); cons_show_error("Failed to start editor: %s", strerror(errno)); g_strfreev(editor_argv); + g_free(editor_env); // array only; strings are borrowed from environ g_free(ctx->filename); g_free(ctx); return TRUE; } else if (pid == 0) { // Child process: Inherits TTY from parent + environ = editor_env; // live TIOCGWINSZ size, not the inherited LINES/COLUMNS + // SIGTSTP=SIG_DFL lets vim's :stop / Ctrl-Z work; profanity catches // the STOPPED state via editor_check_stopped() and drops to the shell. signal(SIGINT, SIG_DFL); @@ -170,6 +191,7 @@ launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* dat editor_pid = pid; g_child_watch_add((GPid)pid, _editor_exit_cb, ctx); g_strfreev(editor_argv); + g_free(editor_env); // frees the parent's array only; the child keeps its own COW copy until execvp return FALSE; }