Skip to content

mitogen/parent: first stage: Bail out if stdin/stdout is not accessible#1395

Open
mhartmay wants to merge 3 commits into
mitogen-hq:masterfrom
mhartmay:bail-out-stdin-stdout
Open

mitogen/parent: first stage: Bail out if stdin/stdout is not accessible#1395
mhartmay wants to merge 3 commits into
mitogen-hq:masterfrom
mhartmay:bail-out-stdin-stdout

Conversation

@mhartmay
Copy link
Copy Markdown
Contributor

@mhartmay mhartmay commented Dec 18, 2025

Bail out if STDIN or STDOUT is closed or unavailable, as these streams are
required for the communication with the parent process. Without this check, the
later os.pipe() calls in the first stage may return file descriptors 0 and 1,
leading to a confusing and hard-to-diagnose situation.

@mhartmay
Copy link
Copy Markdown
Contributor Author

@moreati Will rebase as soon as the other PR #1389 has been merged.

@moreati
Copy link
Copy Markdown
Member

moreati commented Dec 18, 2025

Will rebase as soon as the other PR #1389 has been merged.

Recommend you wait until I've also done a release.

@mhartmay mhartmay force-pushed the bail-out-stdin-stdout branch 2 times, most recently from 0b33371 to 840b9ed Compare December 18, 2025 16:32
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Bail out if STDIN or STDOUT is closed or unavailable, as these streams are
required for the communication with the parent process. Without this check, the
later `os.pipe()` calls in the first_stage may return file descriptors 0 and 1,
leading to a confusing and hard-to-diagnose situation.

-SSH command size: 838
+SSH command size: 850

-mitogen.parent        99240  96.9KiB  51244 50.0KiB 51.6%  12956 12.7KiB 13.1%
+mitogen.parent        99496  97.2KiB  51275 50.1KiB 51.5%  12964 12.7KiB 13.0%

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
@mhartmay mhartmay force-pushed the bail-out-stdin-stdout branch from 840b9ed to 0efd2c3 Compare December 18, 2025 19:33
@mhartmay
Copy link
Copy Markdown
Contributor Author

Will rebase as soon as the other PR #1389 has been merged.

Recommend you wait until I've also done a release.

Done.

@moreati
Copy link
Copy Markdown
Member

moreati commented Dec 19, 2025

Thank you, I'll look at this over Christmas.

Comment thread mitogen/parent.py
Comment on lines +1420 to +1422
# Bail out in case STDIN or STDOUT is not accessible (e.g. closed).
# Otherwise, os.pipe() could reuse file descriptors 0 or 1, leading to
# unexpected behavior that is difficult to diagnose.
Copy link
Copy Markdown
Member

@moreati moreati Jan 27, 2026

Choose a reason for hiding this comment

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

reuse file descriptors 0 or 1, leading to unexpected behavior that is difficult to diagnose.

Note to self: If this occured it would be more acute than I realised. This assumption - that fd 0, 1, 2 are stdio - is made/relied just a few lines down, in the first stage. Let alone elsewhere in Mitogen, or other code bases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Open (to me) questions:

  1. Can it occur? Could fd 0 (stdin) and/or fd 1 (stdout) be closed at theis point?
  2. Has it occured?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It can be constructed (see my test cases), if those cases are relevant - I'm not sure. And I've checked the FDs by writing the FD numbers to a file (as stdout/stderr is not available).

Comment thread mitogen/parent.py
@@ -1455,6 +1459,10 @@ def _first_stage():
f.write(C)
f.close()
os.write(1,'MITO001\n'.encode())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Pre-existing: Assumes fd 1 is stdout

Comment thread mitogen/parent.py
# stream with "[1234 refs]" during exit.
# If STDERR is already closed an OSError is raised, but no one cares
# as STDERR is closed and the exit status is not forwarded.
os.close(2)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Pre-existing: Assumes fd 1 is stderr

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