From patchwork Tue Oct 5 07:46:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Carlo_Marcelo_Arenas_Bel=C3=B3n?= X-Patchwork-Id: 12535731 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7FE2C433EF for ; Tue, 5 Oct 2021 07:47:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C3B261038 for ; Tue, 5 Oct 2021 07:47:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232730AbhJEHsw (ORCPT ); Tue, 5 Oct 2021 03:48:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232658AbhJEHsv (ORCPT ); Tue, 5 Oct 2021 03:48:51 -0400 Received: from mail-qt1-x82f.google.com (mail-qt1-x82f.google.com [IPv6:2607:f8b0:4864:20::82f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 69521C061745 for ; Tue, 5 Oct 2021 00:47:01 -0700 (PDT) Received: by mail-qt1-x82f.google.com with SMTP id l13so18327782qtv.3 for ; Tue, 05 Oct 2021 00:47:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mNZUoeZVtRiLew/B7fEkYU1ykQVl0liTvhOa9hwHydM=; b=gi1wiSEFyn30hlQZih0IlnCiknHDVgsuTX8A/+quxO26i1WGzzN2dhhv+tyHyZZCzH Mz06ahT74rSLPVpnJ1yfZCuxAMCNR3IfrWHe39YuJjqwJEShIdGdk6uw0aECEWFqR/9L 18gEWVskZNuE7ufUa65Qrrny2XXGLH7Zv21INweISDU2IIkZfLNiOTNODMiE/P1ogJOv K6RVI6np1g2s0JaeSTzAsho1T1aeHw/D2tpU8ZVp2TiTlng/jq8QynMuIozv8ETUSCOR g/2ucttUVh76pCaytIve+QbhQJJeyB5EwwI0pUN+vWAt19HJCmMxm/sywIsMo79LNWsK w2/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mNZUoeZVtRiLew/B7fEkYU1ykQVl0liTvhOa9hwHydM=; b=iFeQOyDqSZrQzgu3jGnWUnzzPPvK6/mvFXIiEFmdZjUzmsMS435zmcOhpD0Uo6Mw2G YpuUTSrEtipxsafhxcNXKiE7r6fBbR7uQoFDpq71q73uzn+orFb9sLYEpIFEuqLUg60c fRSbRwaxzVyCvFssyXO29S+UouSZELJ91bUEsSDQhiLz32MFj4KuTPAl6xtUaDS7uBvI XL4FfJdJMOiJm6e1TMLShVm3cNqG79bKpdPSfQ4j1/9oLfRLKZUSlbT7oPDhGlyPpQX4 iaX7whaMSq86p826kaWntDBaqAvPze7ql2ASe0IfIQZ9t8BtM2qtlKpxZWssMAJ0pLdd wZWg== X-Gm-Message-State: AOAM531PO3XlZ0YR/fK7L0j2iqU4NaL7CC/AyzTJ/C61KbyUG8D7RxIb RzLehHfvFrzaGC/vpCjmPIFIWtpQGFUsvg== X-Google-Smtp-Source: ABdhPJxq6vS41POWtoXo26dGmym4749K9o12x4s427pIJTQPRmAyCuw6sCO2DmG+y5YGo5CNLBit+g== X-Received: by 2002:ac8:1011:: with SMTP id z17mr18356660qti.388.1633420020005; Tue, 05 Oct 2021 00:47:00 -0700 (PDT) Received: from carlos-mbp.lan (104-1-92-200.lightspeed.sntcca.sbcglobal.net. [104.1.92.200]) by smtp.gmail.com with ESMTPSA id c16sm8779285qkk.113.2021.10.05.00.46.59 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Oct 2021 00:46:59 -0700 (PDT) From: =?utf-8?q?Carlo_Marcelo_Arenas_Bel=C3=B3n?= To: git@vger.kernel.org Cc: johannes.schindelin@gmx.de, gitster@pobox.com, =?utf-8?q?Carlo_Marcelo_A?= =?utf-8?q?renas_Bel=C3=B3n?= Subject: [PATCH v2 1/2] terminal: teach git how to save/restore its terminal settings Date: Tue, 5 Oct 2021 00:46:47 -0700 Message-Id: <20211005074648.86032-2-carenas@gmail.com> X-Mailer: git-send-email 2.33.0.955.gee03ddbf0e In-Reply-To: <20211005074648.86032-1-carenas@gmail.com> References: <20211004072600.74241-1-carenas@gmail.com> <20211005074648.86032-1-carenas@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Currently, git will share its console with all its children (unless they create their own), and is therefore possible that any of them that might change the settings for it could affect its operations once completed. Refactor the platform specific functionality to save the terminal settings and expand it to also do so for the output handler. This will allow for the state of the terminal to be saved and restored around a child that might misbehave (ex vi) which will be implemented next. Signed-off-by: Carlo Marcelo Arenas Belón --- v2: - remove unnecessary forward declaration for restore_term per Junio - reword first paragraph with hopefully better grammar compat/terminal.c | 75 +++++++++++++++++++++++++++++++++++++---------- compat/terminal.h | 3 ++ 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/compat/terminal.c b/compat/terminal.c index 43b73ddc75..5b903e7c7e 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -8,8 +8,6 @@ #if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE) -static void restore_term(void); - static void restore_term_on_signal(int sig) { restore_term(); @@ -25,7 +23,7 @@ static void restore_term_on_signal(int sig) static int term_fd = -1; static struct termios old_term; -static void restore_term(void) +void restore_term(void) { if (term_fd < 0) return; @@ -35,15 +33,22 @@ static void restore_term(void) term_fd = -1; } +int save_term(int full_duplex) +{ + if (term_fd < 0) + term_fd = open("/dev/tty", O_RDWR); + + return (term_fd < 0) ? -1 : tcgetattr(term_fd, &old_term); +} + static int disable_bits(tcflag_t bits) { struct termios t; - term_fd = open("/dev/tty", O_RDWR); - if (tcgetattr(term_fd, &t) < 0) + if (save_term(0) < 0) goto error; - old_term = t; + t = old_term; sigchain_push_common(restore_term_on_signal); t.c_lflag &= ~bits; @@ -75,9 +80,10 @@ static int enable_non_canonical(void) static int use_stty = 1; static struct string_list stty_restore = STRING_LIST_INIT_DUP; static HANDLE hconin = INVALID_HANDLE_VALUE; -static DWORD cmode; +static HANDLE hconout = INVALID_HANDLE_VALUE; +static DWORD cmode_in, cmode_out; -static void restore_term(void) +void restore_term(void) { if (use_stty) { int i; @@ -97,9 +103,42 @@ static void restore_term(void) if (hconin == INVALID_HANDLE_VALUE) return; - SetConsoleMode(hconin, cmode); + SetConsoleMode(hconin, cmode_in); + CloseHandle(hconin); + if (cmode_out) { + assert(hconout != INVALID_HANDLE_VALUE); + SetConsoleMode(hconout, cmode_out); + CloseHandle(hconout); + } + + hconin = hconout = INVALID_HANDLE_VALUE; +} + +int save_term(int full_duplex) +{ + hconin = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hconin == INVALID_HANDLE_VALUE) + return -1; + + if (full_duplex) { + hconout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hconout == INVALID_HANDLE_VALUE) + goto error; + + GetConsoleMode(hconout, &cmode_out); + } + + GetConsoleMode(hconin, &cmode_in); + use_stty = 0; + return 0; +error: CloseHandle(hconin); hconin = INVALID_HANDLE_VALUE; + return -1; } static int disable_bits(DWORD bits) @@ -135,15 +174,11 @@ static int disable_bits(DWORD bits) use_stty = 0; } - hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (hconin == INVALID_HANDLE_VALUE) + if (save_term(0) < 0) return -1; - GetConsoleMode(hconin, &cmode); sigchain_push_common(restore_term_on_signal); - if (!SetConsoleMode(hconin, cmode & ~bits)) { + if (!SetConsoleMode(hconin, cmode_in & ~bits)) { CloseHandle(hconin); hconin = INVALID_HANDLE_VALUE; return -1; @@ -361,6 +396,16 @@ int read_key_without_echo(struct strbuf *buf) #else +int save_term(int full_duplex) +{ + /* full_duplex == 1, but no support available */ + return -full_duplex; +} + +void restore_term(void) +{ +} + char *git_terminal_prompt(const char *prompt, int echo) { return getpass(prompt); diff --git a/compat/terminal.h b/compat/terminal.h index a9d52b8464..e1770c575b 100644 --- a/compat/terminal.h +++ b/compat/terminal.h @@ -1,6 +1,9 @@ #ifndef COMPAT_TERMINAL_H #define COMPAT_TERMINAL_H +int save_term(int full_duplex); +void restore_term(void); + char *git_terminal_prompt(const char *prompt, int echo); /* Read a single keystroke, without echoing it to the terminal */ From patchwork Tue Oct 5 07:46:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Carlo_Marcelo_Arenas_Bel=C3=B3n?= X-Patchwork-Id: 12535733 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 607FEC433FE for ; Tue, 5 Oct 2021 07:47:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3533A610FC for ; Tue, 5 Oct 2021 07:47:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232758AbhJEHsx (ORCPT ); Tue, 5 Oct 2021 03:48:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232723AbhJEHsw (ORCPT ); Tue, 5 Oct 2021 03:48:52 -0400 Received: from mail-qk1-x72d.google.com (mail-qk1-x72d.google.com [IPv6:2607:f8b0:4864:20::72d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D895C061745 for ; Tue, 5 Oct 2021 00:47:02 -0700 (PDT) Received: by mail-qk1-x72d.google.com with SMTP id f130so18976349qke.6 for ; Tue, 05 Oct 2021 00:47:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nOrp5ZTPPQdxtudpsovyCRa1xu2IRcZLByex6oagzQE=; b=i1DKWaBCw5DBbUaLNk4axqoa7ITpIxsH71MwCxiAjiec7OCoAgpriFf4U7fLLur+gi LJ1HZdeyt67eXgVNLG8RaOjix9s/3LIFu2oSKuIpkn+ROj3qaxoJXgQNTkbx0Xy6xTO5 t8Mk/qLwnaaSywXpKjyYlz2ooEIZrp9FE8ZCeHeQH7IL5gJexfQtVdkJbRccEPB+DZBk yQCdcZPLqPkZH+bjd8WmnEVby6cCmQnIBj93SDjwsnXA1/rQARpodDJITwYTAfQJ33r6 0YhNGyjD/EUrUkHcWusbayueiXhqyOs14W6d0kll2DtdgbyjJXqO9oY+0BgrAbPRyeIO 6eWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nOrp5ZTPPQdxtudpsovyCRa1xu2IRcZLByex6oagzQE=; b=ELaZEDp07FHr/CHf4b8iTG7CtXRlOWFVvGl2YASSL9aLqG8VvH2v7lOp7cRS0k432v S+MKKZ8s9GYEXwIiUD3+z2e5LYUDFLExT6FrKsgdTsgVJQkM9hPPLWdyNquiRGm12uB2 yE5t4awm/HDjhotvNw9NtibfTWY/+X8NlNWBxQ8w9nJpvEdH69Rdl/Npi+29dR9kuaqW ODLsMYiZF8udrBmef2tVZMBxjf8YaHNJbVrqcmmO2Tyrqk0ecKZx/I7NwKlQjkNQFyJ/ sA30tWYiIJvQLMwgWNt69YyJP19kfY201L/U+1cQnomtU+YGsF7nz0gcXQoF/WtWuwfX ZN6g== X-Gm-Message-State: AOAM533nBVm6xLS6CGBd+6h9+vFOrzdS01yu4cF5Wvhh+Oxjcr3I4twt uhZyQgkFUbSsFsfp5MEdZFMeIHPFgb7s0w== X-Google-Smtp-Source: ABdhPJymX9EUzjR6JvAnfcQkTHy5XAYFe91ANoMJ1ODrOHDR1XxWw0g8+/ADJF/CnV5r1qo2T6Hneg== X-Received: by 2002:a37:7d7:: with SMTP id 206mr13775072qkh.432.1633420021103; Tue, 05 Oct 2021 00:47:01 -0700 (PDT) Received: from carlos-mbp.lan (104-1-92-200.lightspeed.sntcca.sbcglobal.net. [104.1.92.200]) by smtp.gmail.com with ESMTPSA id c16sm8779285qkk.113.2021.10.05.00.47.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Oct 2021 00:47:00 -0700 (PDT) From: =?utf-8?q?Carlo_Marcelo_Arenas_Bel=C3=B3n?= To: git@vger.kernel.org Cc: johannes.schindelin@gmx.de, gitster@pobox.com, =?utf-8?q?Carlo_Marcelo_A?= =?utf-8?q?renas_Bel=C3=B3n?= Subject: [PATCH v2 2/2] editor: save and reset terminal after calling EDITOR Date: Tue, 5 Oct 2021 00:46:48 -0700 Message-Id: <20211005074648.86032-3-carenas@gmail.com> X-Mailer: git-send-email 2.33.0.955.gee03ddbf0e In-Reply-To: <20211005074648.86032-1-carenas@gmail.com> References: <20211004072600.74241-1-carenas@gmail.com> <20211005074648.86032-1-carenas@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org When EDITOR is invoked to modify a commit message, it will likely change the terminal settings, and if it misbehaves will leave the terminal output damaged as shown in a recent report from Windows Terminal[1] Instead use the functions provided by compat/terminal to save the settings and recover safely. [1] https://github.com/microsoft/terminal/issues/9359 Signed-off-by: Carlo Marcelo Arenas Belón Signed-off-by: Junio C Hamano --- editor.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/editor.c b/editor.c index 6303ae0ab0..be7441e7e0 100644 --- a/editor.c +++ b/editor.c @@ -3,6 +3,7 @@ #include "strbuf.h" #include "run-command.h" #include "sigchain.h" +#include "compat/terminal.h" #ifndef DEFAULT_EDITOR #define DEFAULT_EDITOR "vi" @@ -50,6 +51,8 @@ const char *git_sequence_editor(void) static int launch_specified_editor(const char *editor, const char *path, struct strbuf *buffer, const char *const *env) { + int term_fail; + if (!editor) return error("Terminal is dumb, but EDITOR unset"); @@ -83,7 +86,10 @@ static int launch_specified_editor(const char *editor, const char *path, p.env = env; p.use_shell = 1; p.trace2_child_class = "editor"; + term_fail = save_term(1); if (start_command(&p) < 0) { + if (!term_fail) + restore_term(); strbuf_release(&realpath); return error("unable to start editor '%s'", editor); } @@ -91,6 +97,8 @@ static int launch_specified_editor(const char *editor, const char *path, sigchain_push(SIGINT, SIG_IGN); sigchain_push(SIGQUIT, SIG_IGN); ret = finish_command(&p); + if (!term_fail) + restore_term(); strbuf_release(&realpath); sig = ret - 128; sigchain_pop(SIGINT);