Skip to content

Set a terminal type for dumping tools when their output is not a terminal - #1018

Merged
mnadareski merged 2 commits into
SabreTools:masterfrom
gmipf:fix/tool-console-size
Jul 24, 2026
Merged

Set a terminal type for dumping tools when their output is not a terminal#1018
mnadareski merged 2 commits into
SabreTools:masterfrom
gmipf:fix/tool-console-size

Conversation

@gmipf

@gmipf gmipf commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Problem

Aaru 5 queries the console width (Console.WindowWidth) while drawing progress. When its standard output is not a terminal, that width can only come from the TERM/terminfo fallback, and when TERM is unset it comes back as 0. Aaru 5 then evaluates new string(' ', width - 1) and throws ArgumentOutOfRangeException on the very first progress update, before it reads a single sector.

MPF hands Aaru 5 a non-terminal stdout in two independent situations:

  1. GUI — the Linux tool-output console (added in Add live tool output console for the Linux GUI #998) redirects the tool's stdout to a pipe so it can be shown in a window.
  2. CLIMPF.CLI launches the tool with UseShellExecute = true, so the tool inherits MPF.CLI's own stdout. When MPF.CLI itself runs without a terminal (a script, a service, cron, or mpf-cli … > log), the tool inherits that non-terminal. This path predates Add live tool output console for the Linux GUI #998 and is not specific to the GUI.

Whether it bites also depends on the environment's TERM:

Launched from TERM seen by the tool Aaru 5 result
GNOME menu (GNOME Shell 50.1) (unset) aborts before first read
KDE Plasma menu dumb (has a terminfo width) dumps fine
a terminal xterm etc. dumps fine

So from GNOME — or any environment that does not export TERM, including non-interactive service/cron contexts — Aaru 5 cannot dump at all, while the same build works from KDE or a terminal.

Fix

When the tool's stdout will not be a terminal and the environment has no TERM, set TERM to a type with a known width. This covers both the redirected (GUI) path and the inherited-output (CLI) path. A real terminal's TERM is left untouched. The inherited-output check is limited to .NET 5+ on non-Windows: TERM is meaningless on Windows, and there an environment entry cannot be combined with UseShellExecute.

#if NET5_0_OR_GREATER
bool inheritsRedirectedOutput = !redirect && !OperatingSystem.IsWindows() && Console.IsOutputRedirected;
#else
bool inheritsRedirectedOutput = false;
#endif

if ((redirect || inheritsRedirectedOutput)
    && string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TERM")))
{
    startInfo.EnvironmentVariables["TERM"] = "xterm";
}

Testing

Measured on real hardware (Plextor PX-760A, audio CD) in a clean VM, driving the real BaseExecutionContext.ExecuteInternalProgram path with TERM unset (the GNOME / service condition). Images are time-boxed, so sizes are not comparable between tools:

Tool (via MPF.CLI, TERM unset, no terminal) before after
Aaru 5.4.2 ArgumentOutOfRangeException, no image dumps (≈102 MB)
redumper dumps (≈229 MB) dumps (≈229 MB)
DiscImageCreator dumps (≈61 MB) dumps (≈61 MB)
Aaru 6.0.0-beta.1 not invokable by MPF today¹ not invokable by MPF today¹
  • Only Aaru 5 is affected: redumper and DiscImageCreator are native tools that do not use the managed console-width API, and they are unchanged by this PR.
  • ¹ MPF invokes Aaru with 5.x syntax (--verbose True media dump …); Aaru 6 rejects it at parse time (Unexpected option 'verbose'), so it never reaches this code. Mentioned only for completeness.
  • The CLI path is pre-existing: I built MPF.CLI at the commit just before my first contribution and reproduced the identical crash (ArgumentOutOfRangeExceptionAaru.Progress.ClearCurrentConsoleLine()) under the same condition, and confirmed it dumps with TERM=xterm. This change does not introduce the CLI behavior; it fixes it.
  • Builds across the full TargetFrameworks set (net20 … net10.0) with no warnings; MPF.ExecutionContexts.Test 615 passed and MPF.Frontend.Test 562 passed.

Prepared with AI assistance (Claude Opus 4.8) and reviewed before submission.

gmipf and others added 2 commits July 21, 2026 12:08
…ng TERM

When the Linux tool-output console is active, a dumping tool's stdout is a pipe
instead of a terminal. Some tools (notably Aaru 5) query the console width while
drawing progress; on a non-terminal that width can only come from the
TERM/terminfo fallback, and when TERM is unset it returns 0, so the tool does
`new string(' ', width - 1)` and throws before the first read.

Apps launched from a GNOME session inherit no TERM (measured on GNOME Shell 50.1:
menu launches get no TERM), so Aaru 5 aborts there; KDE happens to set TERM=dumb,
which carries a terminfo width, so it works. Set TERM to a type with a known
width when the environment has none, only on the redirected path, so a tool
always gets a usable width. A real terminal's TERM is left untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A tool started with UseShellExecute inherits the frontend's stdout, so MPF.CLI
run with its output redirected -- from a script, a cron job, or a service --
hands the tool a non-terminal as well, even though nothing is redirected here.
The previous commit only covered the case where an output sink is attached, so
the CLI kept aborting.

Measured on a Plextor PX-760A with an audio CD and Aaru 5.4.2 as the dumping
program. With output redirected and TERM unset, MPF.CLI produced a zero-byte
image and Aaru threw ArgumentOutOfRangeException from
Aaru.Progress.ClearCurrentConsoleLine(); with this change the same invocation
dumps normally. Running from a real terminal is unaffected, and a terminal that
already provides TERM is still left alone.

The added check is limited to .NET 5 and newer on non-Windows: TERM carries no
meaning on Windows, and an environment entry cannot be combined with
UseShellExecute there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gmipf

gmipf commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

I've expanded this PR. The original commit fixed the GUI console path (#998); I then found the same Aaru 5 crash on the MPF.CLI path, which is independent of #998 and long-standing (the tool inherits MPF.CLI's stdout via UseShellExecute). Rather than open a second PR touching the same lines, I extended the fix here to cover both and updated the title and description accordingly. Everything is measured on real hardware in a clean VM across all four dumping tools; details are in the updated description.

Generated with Claude Opus 4.8.

@gmipf gmipf changed the title Set a terminal type for redirected tools so they don't abort when TERM is unset Set a terminal type for dumping tools when their output is not a terminal Jul 23, 2026
@gmipf gmipf closed this Jul 23, 2026
@gmipf gmipf reopened this Jul 23, 2026
@mnadareski
mnadareski merged commit c9849cf into SabreTools:master Jul 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants