nohup: make the substitute stdin unreadable like GNU - #14655
costajohnt wants to merge 3 commits into
Conversation
When stdin is a terminal, nohup replaces it with /dev/null. It was opened read-only, so a command that went on to read stdin got a silent EOF and exited 0 (`nohup cat`, `nohup date --file -`). GNU opens /dev/null write-only on purpose: "Make the substitute file descriptor unreadable, so that commands that mistakenly attempt to read from standard input can report an error." Do the same, so such a read fails with EBADF and the command exits 1 as it does under GNU nohup. Fixes uutils#14556
|
GNU testsuite comparison: |
|
There is a file named as |
| // EOF (GNU opens /dev/null write-only). Since nohup execs the command, the | ||
| // exit status is the command's own. | ||
| #[test] | ||
| #[cfg(any( |
There was a problem hiding this comment.
No real reason, I copied the gating from the tests above. Switched it to cfg(unix).
|
Good point, I think Windows has the same issue. Rust's Also merged main to pick up the xattr fix for the OpenBSD |
When stdin is a terminal,
nohupreplaces it with/dev/null. We opened it read-only, so a command that went on to read from stdin got a silent EOF and exited 0:GNU opens
/dev/nullwrite-only on purpose. From the manual: "Make the substitute file descriptor unreadable, so that commands that mistakenly attempt to read from standard input can report an error." Under GNU nohup the same command exits 1 andnohup.outholdscat: stdin: Bad file descriptor.This change opens
/dev/nullwithOpenOptions::new().write(true)inreplace_fds()so a read on the substitute stdin fails withEBADF, matching GNU. stdout and stderr handling is unchanged.The Windows side (
platform/windows.rs) usesStdio::null()for the child's stdin and is left as is; I did not find an equivalent of an unreadable handle there.Testing:
test_nohup_replaced_stdin_is_not_readableintests/by-util/test_nohup.rsrunsnohup catunderterminal_simulation(true), asserts exit status 1 and thatnohup.outcontainsBad file descriptor. It fails onmain(exit 0) and passes with this change. Gated on the same target set as the sibling pty tests (apple, linux, android, freebsd, openbsd).cargo test --features nohup --no-default-features --test tests -- test_nohup: 8 passed on macOS.cargo fmt --all -- --check,cargo clippy -p uu_nohup --all-targets -- -D warnings,cargo clippy --features nohup --no-default-features --all-targets -- -D warnings: clean.script -q /dev/nullon macOS:nohup catandnohup gdate --file -both now exit 1 with the read error innohup.out, same asgnohup.tests/misc/nohup.shnever reads stdin after the redirection, so no GNU test result should change. Not run locally (Linux only).Fixes #14556
Reproduces against GNU coreutils 9.11 on Linux and macOS (
gnohup catunder a pty exits 1 withcat: stdin: Bad file descriptor). The Cygwin report in the issue thread that could not reproduce was on GNU 9.0.