* [PATCH] Ensure restore_term works correctly with DUPLEX @ 2025-06-17 18:56 James Duley via GitGitGadget 2025-06-17 19:18 ` Junio C Hamano 2025-06-23 9:35 ` Phillip Wood 0 siblings, 2 replies; 7+ messages in thread From: James Duley via GitGitGadget @ 2025-06-17 18:56 UTC (permalink / raw) To: git; +Cc: James Duley, James Duley From: James Duley <jagduley@gmail.com> Previously, if save_term/restore_term was called with the DUPLEX flag and then without the flag, an assertion was hit. > Assertion failed: hconout != INVALID_HANDLE_VALUE, > file compat/terminal.c, line 283 This is because save_term doesn't set cmode_out when not DUPLEX, so an old version of cmode_out was being used. Therefore, hconout is the correct thing for restore to check to decide whether to restore stdout console mode. I saw this on Windows with interactive.singleKey when doing `git add -p`. Specifically, after hitting `e` to edit in vim, once on to the prompt for the next hunk, pressing any key results in the assertion. Signed-off-by: James Duley <jagduley@gmail.com> --- Ensure restore_term works correctly with DUPLEX Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2000%2Fparched%2Frestore-term-windows-fix-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2000/parched/restore-term-windows-fix-v1 Pull-Request: https://github.com/git/git/pull/2000 compat/terminal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compat/terminal.c b/compat/terminal.c index 584f27bf7e1..72b184555ff 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -279,8 +279,7 @@ void restore_term(void) SetConsoleMode(hconin, cmode_in); CloseHandle(hconin); - if (cmode_out) { - assert(hconout != INVALID_HANDLE_VALUE); + if (hconout != INVALID_HANDLE_VALUE) { SetConsoleMode(hconout, cmode_out); CloseHandle(hconout); } base-commit: 16bd9f20a403117f2e0d9bcda6c6e621d3763e77 -- gitgitgadget ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Ensure restore_term works correctly with DUPLEX 2025-06-17 18:56 [PATCH] Ensure restore_term works correctly with DUPLEX James Duley via GitGitGadget @ 2025-06-17 19:18 ` Junio C Hamano 2025-06-18 10:07 ` Carlo Marcelo Arenas Belón 2025-06-23 9:35 ` Phillip Wood 1 sibling, 1 reply; 7+ messages in thread From: Junio C Hamano @ 2025-06-17 19:18 UTC (permalink / raw) To: James Duley via GitGitGadget Cc: git, James Duley, Carlo Marcelo Arenas Belón, Johannes Schindelin "James Duley via GitGitGadget" <gitgitgadget@gmail.com> writes: > From: James Duley <jagduley@gmail.com> > > Previously, if save_term/restore_term was called with the DUPLEX flag > and then without the flag, an assertion was hit. >> Assertion failed: hconout != INVALID_HANDLE_VALUE, >> file compat/terminal.c, line 283 > > This is because save_term doesn't set cmode_out when not DUPLEX, > so an old version of cmode_out was being used. > Therefore, hconout is the correct thing for restore to check > to decide whether to restore stdout console mode. > > I saw this on Windows with interactive.singleKey when doing `git add -p`. > Specifically, after hitting `e` to edit in vim, once on to the prompt > for the next hunk, pressing any key results in the assertion. > > Signed-off-by: James Duley <jagduley@gmail.com> > --- > Ensure restore_term works correctly with DUPLEX Ran "git log -L247,290:compat/terminal.c" to find commits that touched this Windows specific area of the code to see who might be capable of reviewing this change, as I am certainly not one of them. e22b245e (terminal: teach git how to save/restore its terminal settings, 2021-10-05) is where the assert being removed came from, it seems. The author of that commit should be CC'ed if we want to ask for a quicker review. I'll also add Git-for-Windows maintainer as well. Thanks. > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2000%2Fparched%2Frestore-term-windows-fix-v1 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2000/parched/restore-term-windows-fix-v1 > Pull-Request: https://github.com/git/git/pull/2000 > > compat/terminal.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/compat/terminal.c b/compat/terminal.c > index 584f27bf7e1..72b184555ff 100644 > --- a/compat/terminal.c > +++ b/compat/terminal.c > @@ -279,8 +279,7 @@ void restore_term(void) > > SetConsoleMode(hconin, cmode_in); > CloseHandle(hconin); > - if (cmode_out) { > - assert(hconout != INVALID_HANDLE_VALUE); > + if (hconout != INVALID_HANDLE_VALUE) { > SetConsoleMode(hconout, cmode_out); > CloseHandle(hconout); > } > > base-commit: 16bd9f20a403117f2e0d9bcda6c6e621d3763e77 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Ensure restore_term works correctly with DUPLEX 2025-06-17 19:18 ` Junio C Hamano @ 2025-06-18 10:07 ` Carlo Marcelo Arenas Belón 2025-06-18 20:38 ` James Duley 0 siblings, 1 reply; 7+ messages in thread From: Carlo Marcelo Arenas Belón @ 2025-06-18 10:07 UTC (permalink / raw) To: Junio C Hamano Cc: James Duley via GitGitGadget, git, James Duley, Johannes Schindelin On Tue, Jun 17, 2025 at 12:18:07PM -0800, Junio C Hamano wrote: > "James Duley via GitGitGadget" <gitgitgadget@gmail.com> writes: > > > This is because save_term doesn't set cmode_out when not DUPLEX, > > so an old version of cmode_out was being used. To fully address that bug though, something like the following (untested) needs to be squashed on top, right?: ---- diff --git a/compat/terminal.c b/compat/terminal.c index 72b184555f..8a197ffea1 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -279,7 +279,7 @@ void restore_term(void) SetConsoleMode(hconin, cmode_in); CloseHandle(hconin); - if (hconout != INVALID_HANDLE_VALUE) { + if (cmode_out && hconout != INVALID_HANDLE_VALUE) { SetConsoleMode(hconout, cmode_out); CloseHandle(hconout); } @@ -299,11 +299,15 @@ int save_term(enum save_term_flags flags) hconout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hconout == INVALID_HANDLE_VALUE) + if (hconout == INVALID_HANDLE_VALUE) { + cmode_out = 0; goto error; + } GetConsoleMode(hconout, &cmode_out); } + else + cmode_out = 0; GetConsoleMode(hconin, &cmode_in); use_stty = 0; It would be nice to know, if the problem with vi that this was meant to address, and that needs further changes, that are only in the git for windows fork is stll relevant, so this could be cleaned further. Carlo ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Ensure restore_term works correctly with DUPLEX 2025-06-18 10:07 ` Carlo Marcelo Arenas Belón @ 2025-06-18 20:38 ` James Duley 2025-06-18 23:43 ` Carlo Marcelo Arenas Belón 0 siblings, 1 reply; 7+ messages in thread From: James Duley @ 2025-06-18 20:38 UTC (permalink / raw) To: Carlo Marcelo Arenas Belón Cc: Junio C Hamano, James Duley via GitGitGadget, git, Johannes Schindelin On Wed, 18 Jun 2025 at 22:07, Carlo Marcelo Arenas Belón <carenas@gmail.com> wrote: > > On Tue, Jun 17, 2025 at 12:18:07PM -0800, Junio C Hamano wrote: > > "James Duley via GitGitGadget" <gitgitgadget@gmail.com> writes: > > > > > This is because save_term doesn't set cmode_out when not DUPLEX, > > > so an old version of cmode_out was being used. > > To fully address that bug though, something like the following > (untested) needs to be squashed on top, right?: > > ---- > diff --git a/compat/terminal.c b/compat/terminal.c > index 72b184555f..8a197ffea1 100644 > --- a/compat/terminal.c > +++ b/compat/terminal.c > @@ -279,7 +279,7 @@ void restore_term(void) > > SetConsoleMode(hconin, cmode_in); > CloseHandle(hconin); > - if (hconout != INVALID_HANDLE_VALUE) { > + if (cmode_out && hconout != INVALID_HANDLE_VALUE) { > SetConsoleMode(hconout, cmode_out); > CloseHandle(hconout); > } > @@ -299,11 +299,15 @@ int save_term(enum save_term_flags flags) > hconout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, > FILE_SHARE_WRITE, NULL, OPEN_EXISTING, > FILE_ATTRIBUTE_NORMAL, NULL); > - if (hconout == INVALID_HANDLE_VALUE) > + if (hconout == INVALID_HANDLE_VALUE) { > + cmode_out = 0; > goto error; > + } > > GetConsoleMode(hconout, &cmode_out); > } > + else > + cmode_out = 0; > > GetConsoleMode(hconin, &cmode_in); > use_stty = 0; > > It would be nice to know, if the problem with vi that this was meant to > address, and that needs further changes, that are only in the git for > windows fork is stll relevant, so this could be cleaned further. > > Carlo I thought about something like that, but I figured: * restore_term is only called if save_term is successful * hconout is always invalid before save_term is called * 0 might be a valid cmode_out that should be restored This is my first patch so I didn't realize git-for-windows had a separate fork. That makes sense now because I couldn't find where save_term was called from in this repo. To test this works I had downloaded the artifacts from https://github.com/git/git/actions/runs/15692373534/job/44210362705 but is that right? If I should submit this patch to the git-for-windows fork, please let me know. Or, if someone, who knows what they're doing, wants to pick this up, they're more than welcome. James Duley ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Ensure restore_term works correctly with DUPLEX 2025-06-18 20:38 ` James Duley @ 2025-06-18 23:43 ` Carlo Marcelo Arenas Belón 2025-06-23 9:42 ` Phillip Wood 0 siblings, 1 reply; 7+ messages in thread From: Carlo Marcelo Arenas Belón @ 2025-06-18 23:43 UTC (permalink / raw) To: James Duley Cc: Junio C Hamano, James Duley via GitGitGadget, git, Johannes Schindelin On Thu, Jun 19, 2025 at 08:38:29AM -0800, James Duley wrote: > On Wed, 18 Jun 2025 at 22:07, Carlo Marcelo Arenas Belón > <carenas@gmail.com> wrote: > > > > On Tue, Jun 17, 2025 at 12:18:07PM -0800, Junio C Hamano wrote: > > > "James Duley via GitGitGadget" <gitgitgadget@gmail.com> writes: > > > > > > > This is because save_term doesn't set cmode_out when not DUPLEX, > > > > so an old version of cmode_out was being used. > > > > To fully address that bug though, something like the following > > (untested) needs to be squashed on top, right?: > > > > ---- > > diff --git a/compat/terminal.c b/compat/terminal.c > > index 72b184555f..8a197ffea1 100644 > > --- a/compat/terminal.c > > +++ b/compat/terminal.c > > @@ -279,7 +279,7 @@ void restore_term(void) > > > > SetConsoleMode(hconin, cmode_in); > > CloseHandle(hconin); > > - if (hconout != INVALID_HANDLE_VALUE) { > > + if (cmode_out && hconout != INVALID_HANDLE_VALUE) { > > SetConsoleMode(hconout, cmode_out); > > CloseHandle(hconout); > > } > > @@ -299,11 +299,15 @@ int save_term(enum save_term_flags flags) > > hconout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, > > FILE_SHARE_WRITE, NULL, OPEN_EXISTING, > > FILE_ATTRIBUTE_NORMAL, NULL); > > - if (hconout == INVALID_HANDLE_VALUE) > > + if (hconout == INVALID_HANDLE_VALUE) { > > + cmode_out = 0; > > goto error; > > + } > > > > GetConsoleMode(hconout, &cmode_out); > > } > > + else > > + cmode_out = 0; > > > > GetConsoleMode(hconin, &cmode_in); > > use_stty = 0; > > > > It would be nice to know, if the problem with vi that this was meant to > > address, and that needs further changes, that are only in the git for > > windows fork is stll relevant, so this could be cleaned further. > > > > Carlo > > I thought about something like that, but I figured: > * restore_term is only called if save_term is successful > * hconout is always invalid before save_term is called but it is not always set to invalid at the end of restore_term() so it can't be relied upon either. > * 0 might be a valid cmode_out that should be restored cmode_out == 0 is not a valid mode that should be restored, and indeed the original code was (ab)using that fact to decide if SetConsoleMode(hcounout) would be called at all (as a proxy to know if DUPLEX was used or not), hence why it is a bug not to update it, as you pointed out and found unexpectally, sorry about that. > This is my first patch so I didn't realize git-for-windows had a > separate fork. That makes sense now because I couldn't find where > save_term was called from in this repo. To test this works I had > downloaded the artifacts from > https://github.com/git/git/actions/runs/15692373534/job/44210362705 > but is that right? If I should submit this patch to the git-for-windows > fork, please let me know. Or, if someone, who knows what they're > doing, wants to pick this up, they're more than welcome. You are going to need to get the Git for Windows SDK installed to be able to apply this patch and build your own version of GfW. IMHO getting the change that makes "cmode_out" reliable again (which would include both our changes) should be a good start regardless, and at least that change could be submitted here. Carlo ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Ensure restore_term works correctly with DUPLEX 2025-06-18 23:43 ` Carlo Marcelo Arenas Belón @ 2025-06-23 9:42 ` Phillip Wood 0 siblings, 0 replies; 7+ messages in thread From: Phillip Wood @ 2025-06-23 9:42 UTC (permalink / raw) To: Carlo Marcelo Arenas Belón, James Duley Cc: Junio C Hamano, James Duley via GitGitGadget, git, Johannes Schindelin On 19/06/2025 00:43, Carlo Marcelo Arenas Belón wrote: > On Thu, Jun 19, 2025 at 08:38:29AM -0800, James Duley wrote: >> On Wed, 18 Jun 2025 at 22:07, Carlo Marcelo Arenas Belón >> <carenas@gmail.com> wrote: >>> >> I thought about something like that, but I figured: >> * restore_term is only called if save_term is successful >> * hconout is always invalid before save_term is called > > but it is not always set to invalid at the end of restore_term() > so it can't be relied upon either. Are you sure about that? It looks to me like the only time we don't reset hconout is when we use stty in which case I think hconout is already set to the invalid handle value. >> * 0 might be a valid cmode_out that should be restored > > cmode_out == 0 is not a valid mode that should be restored, cmode_out is a bitfield. The documentation for SetConsoleMode() says the mode parameter "can be one or more of the following values" which implies zero is not a valid mode. It seems very hacky to be relying on that when we can just check if the output handle is valid though. > and > indeed the original code was (ab)using that fact to decide if > SetConsoleMode(hcounout) would be called at all (as a proxy to > know if DUPLEX was used or not), hence why it is a bug not to > update it, as you pointed out and found unexpectally, sorry > about that. > >> This is my first patch so I didn't realize git-for-windows had a >> separate fork. That makes sense now because I couldn't find where >> save_term was called from in this repo. To test this works I had >> downloaded the artifacts from >> https://github.com/git/git/actions/runs/15692373534/job/44210362705 >> but is that right? If I should submit this patch to the git-for-windows >> fork, please let me know. Or, if someone, who knows what they're >> doing, wants to pick this up, they're more than welcome. > > You are going to need to get the Git for Windows SDK installed to > be able to apply this patch and build your own version of GfW. > > IMHO getting the change that makes "cmode_out" reliable again (which > would include both our changes) should be a good start regardless, > and at least that change could be submitted here. Yes, this change should absolutely be submitted here as it is fixing code that is upstream of git-for-windows. Thanks Phillip > > Carlo > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Ensure restore_term works correctly with DUPLEX 2025-06-17 18:56 [PATCH] Ensure restore_term works correctly with DUPLEX James Duley via GitGitGadget 2025-06-17 19:18 ` Junio C Hamano @ 2025-06-23 9:35 ` Phillip Wood 1 sibling, 0 replies; 7+ messages in thread From: Phillip Wood @ 2025-06-23 9:35 UTC (permalink / raw) To: James Duley via GitGitGadget, git Cc: James Duley, Carlo Marcelo Arenas Belón, Junio C Hamano Hi James On 17/06/2025 19:56, James Duley via GitGitGadget wrote: > From: James Duley <jagduley@gmail.com> > > Previously, if save_term/restore_term was called with the DUPLEX flag > and then without the flag, an assertion was hit. >> Assertion failed: hconout != INVALID_HANDLE_VALUE, >> file compat/terminal.c, line 283 > > This is because save_term doesn't set cmode_out when not DUPLEX, > so an old version of cmode_out was being used. > Therefore, hconout is the correct thing for restore to check > to decide whether to restore stdout console mode. I found this paragraph (especially the first sentence) rather hard to understand - it was only after I'd figured out what the problem was by reading the code that I could understand what it was saying. As I understand it the problem is caused by calling save_term(SAVE_TERM_DUPLEX); restore_term(); save_term(0); restore_term(); The first call to save_term() sets hconout to a valid handle and cmode_out to a non-zero value. The first call to restore_term() then sets hconout to INVALID_HANDLE_VALUE but leaves cmode_out unchanged. The second call to save_term does not touch hconout or cmode_out. The second call to restore_term() then hits the assertion because cmode_out is non-zero but hconout is an invalid handle. I think it would be helpful to include an explanation like that in the commit message. I agree with you diagnosis and the proposed fix - using the filehandle to tell whether we should restore the output settings is much cleaner that looking at the mode. I would suggest that we should also set hconout to INVALID_HANDLE_VALUE when save_term() is called without SAVE_TERM_DUPLEX to avoid any problems with call sequences like save_term(SAVE_TERM_DUPLEX); save_term(0); restore_term(); Thanks for reporting and working on this Phillip > I saw this on Windows with interactive.singleKey when doing `git add -p`. > Specifically, after hitting `e` to edit in vim, once on to the prompt > for the next hunk, pressing any key results in the assertion. > > Signed-off-by: James Duley <jagduley@gmail.com> > --- > Ensure restore_term works correctly with DUPLEX > > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2000%2Fparched%2Frestore-term-windows-fix-v1 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2000/parched/restore-term-windows-fix-v1 > Pull-Request: https://github.com/git/git/pull/2000 > > compat/terminal.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/compat/terminal.c b/compat/terminal.c > index 584f27bf7e1..72b184555ff 100644 > --- a/compat/terminal.c > +++ b/compat/terminal.c > @@ -279,8 +279,7 @@ void restore_term(void) > > SetConsoleMode(hconin, cmode_in); > CloseHandle(hconin); > - if (cmode_out) { > - assert(hconout != INVALID_HANDLE_VALUE); > + if (hconout != INVALID_HANDLE_VALUE) { > SetConsoleMode(hconout, cmode_out); > CloseHandle(hconout); > } > > base-commit: 16bd9f20a403117f2e0d9bcda6c6e621d3763e77 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-06-23 9:42 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-17 18:56 [PATCH] Ensure restore_term works correctly with DUPLEX James Duley via GitGitGadget 2025-06-17 19:18 ` Junio C Hamano 2025-06-18 10:07 ` Carlo Marcelo Arenas Belón 2025-06-18 20:38 ` James Duley 2025-06-18 23:43 ` Carlo Marcelo Arenas Belón 2025-06-23 9:42 ` Phillip Wood 2025-06-23 9:35 ` Phillip Wood
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox