Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix process#251 #257

Merged
merged 2 commits into from
Aug 4, 2022
Merged

Fix process#251 #257

merged 2 commits into from
Aug 4, 2022

Conversation

bgamari
Copy link
Contributor

@bgamari bgamari commented Aug 4, 2022

Previously to spawn a process with a closed standard handle, we
would use posix_spawn_file_action_addclose. However, it turns out that
POSIX specifies that spawnp() may fail if addclose() is used on an
fd that is already closed. While glibc and musl appear to ignore this
aspect of the specification, Darwin indeed follows it leading to #251.

This behavior is rather unfortunate as
posix_spawn_file_action_addclose is a convenient way to close a handle
in a subprocess in a race-free manner (e.g. unlike O_CLOEXEC, which is
global). To avoid #251 we must first use
posix_spawn_file_action_addopen on the fd (e.g. opening /dev/null)
to be closed to ensure that it is valid, which has the side-effect of
closing the inherited fd. We can then safely use
posix_spawn_file_action_addclose to close the fd.

Fixes #251.

Previously to spawn a process with a closed standard handle, we
would use `posix_spawn_file_action_addclose`. However, it turns out that
POSIX specifies that `spawnp()` may fail if `addclose()` is used on an
fd that is already closed. While glibc and musl appear to ignore this
aspect of the specification, Darwin indeed follows it leading to haskell#251.

This behavior is rather unfortunate as
`posix_spawn_file_action_addclose` is a convenient way to close a handle
in a subprocess in a race-free manner (e.g. unlike `O_CLOEXEC`, which is
global). To avoid haskell#251 we must first use
`posix_spawn_file_action_addopen` on the fd (e.g. opening `/dev/null`)
to be closed to ensure that it is valid, which has the side-effect of
closing the inherited fd. We can then safely use
`posix_spawn_file_action_addclose` to close the fd.

Fixes haskell#251.
@bgamari
Copy link
Contributor Author

bgamari commented Aug 4, 2022

Unfortunately I found that the current Cabal-driven testsuite isn't particularly well-suited to test this, consequently I ended up adding a test in GHC's testsuite. Testing this locally as we speak.

@bgamari
Copy link
Contributor Author

bgamari commented Aug 4, 2022

I have confirmed that the test reproduces #251 on Darwin without this change and that the change fixes it.

@bgamari bgamari merged commit fad8c8d into haskell:master Aug 4, 2022
@bgamari
Copy link
Contributor Author

bgamari commented Aug 4, 2022

Note that I ultimately opted not to make the addopen/addclose behavior conditional on platform since technically spawnp failing in this case is what is mandated by POSIX.

@hasufell
Copy link
Member

Is this released? I can't find it in https://hackage.haskell.org/package/process-1.6.15.0/changelog

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.

MacOS: posix_spawnp: invalid argument (Bad file descriptor)
2 participants