Skip to content

tsort: handle stdout write errors without panicking#12065

Open
dragutreis wants to merge 1 commit intouutils:mainfrom
dragutreis:fix/tsort-stdout-write-error
Open

tsort: handle stdout write errors without panicking#12065
dragutreis wants to merge 1 commit intouutils:mainfrom
dragutreis:fix/tsort-stdout-write-error

Conversation

@dragutreis
Copy link
Copy Markdown

Fixes #12006

Avoid a panic in tsort when stdout is unwritable (for example, redirected to /dev/full). Previously an unchecked println! was used which could panic on write errors. Replaced that with a writeln! wrapped in error handling so the program continues generating cycle diagnostics even if writing to stdout fails.

Cycle diagnostics are still always written to stderr; any write errors are recorded and cause the program to exit with status 1 after processing completes.

Tested with /etc/pacman.conf and printf "a b\nb a\n" | tsort > /dev/full in both cases.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/tail-n0f (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/cut/bounded-memory is now passing!
Congrats! The gnu test tests/printf/printf-surprise is now passing!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 28, 2026

Merging this PR will not alter performance

✅ 97 untouched benchmarks
⏩ 261 skipped benchmarks1


Comparing dragutreis:fix/tsort-stdout-write-error (cf31a00) with main (ead174f)2

Open in CodSpeed

Footnotes

  1. 261 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (5316f58) during the generation of this report, so ead174f was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Comment thread src/uu/tsort/src/tsort.rs Outdated
Comment thread src/uu/tsort/src/tsort.rs Outdated
Comment thread src/uu/tsort/src/tsort.rs Outdated
Comment thread src/uu/tsort/src/tsort.rs Outdated
Comment thread src/uu/tsort/src/tsort.rs Outdated
Comment thread src/uu/tsort/src/tsort.rs
Comment thread src/uu/tsort/src/tsort.rs Outdated
}

g.run_tsort();
g.run_tsort().map_err(|e| USimpleError::new(1, format!("write error: {e}")))?;
Copy link
Copy Markdown
Contributor

@xtqqczze xtqqczze Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it would be better if run_tsort returned Result<(), TsortError> instead

Suggested change
g.run_tsort().map_err(|e| USimpleError::new(1, format!("write error: {e}")))?;
g.run_tsort()?;

You'd need to add a TsortError variant:

    #[error("{}", translate!("tsort-error-write", "error" => strip_errno(.0)))]
    Write(io::Error),

and update src/uu/tsort/locales/en-US.ftl, src/uu/tsort/locales/en-FR.ftl

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Author

@dragutreis dragutreis Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, will do, thanks for the suggestion.

Comment thread src/uu/tsort/src/tsort.rs Outdated
Comment on lines 151 to 153
/// Wrapper for bubbling up IO errors
#[error("{0}")]
IO(#[from] io::Error),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Wrapper for bubbling up IO errors
#[error("{0}")]
IO(#[from] io::Error),

is it unused?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it, lemme double check 1 sec.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have made a mistake, I messed up my local branch state while testing the suggestion. Pushed to the PR on accident.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at this point you probably want to rebase to fixup the history, feel free to add me as co-author :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, thanks a lot!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, will do

@dragutreis dragutreis force-pushed the fix/tsort-stdout-write-error branch 2 times, most recently from 01918ef to 60be635 Compare April 29, 2026 13:50
Comment thread src/uu/tsort/src/tsort.rs
IO(#[from] io::Error),
/// Read error.
#[error("{}", translate!("tsort-error-read", "error" => strip_errno(.0)))]
Read(io::Error),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: separate with newline (amend last commit)

Co-authored-by: xtqqczze <45661989+xtqqczze@users.noreply.github.com>
Co-authored-by: oech3 <79379754+oech3@users.noreply.github.com>
@dragutreis dragutreis force-pushed the fix/tsort-stdout-write-error branch from 60be635 to cf31a00 Compare April 29, 2026 15:10
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.

tsort file > /dev/full panics

3 participants