Download raw body.
nohup: fix error messages when stderr unavailable
mcq <mcq@disroot.org> wrote:
> Hello bugs@,
>
> i've found bugs in the binary nohup.
>
> when stderr is closed or in a tty when nohup fails the error message is lost.
>
> two bugs fixed:
>
> 1. fprintf writes to stdin instead of stdout when dup2 fails
Yes it looks very weird.
But I don't think you have understood correctly how kernel+libc handles
fd0-2, with the FILE* on top of that, and I think this extremely weird
code is as correct as it can be, unless it stops using the stdio layer.
> 2. errx writes to stderr (which is closed) when nohup fails
I think this is related to what I replied above.
> Both now write to stdout when stderr is unavailble
That's a strange sentence. stdout is a libc stdio thing. It maps to fd 2.
But fd 0, fd 1, and fd 2 are the same object because they are dups.
> tested with stderr closed (in a terminal emulator,) and a TTY, also in a read only
> directory.
Have you considered that it is behaving correctly? This code has
received very little changes from historic code. You think you've found
a bug in ancient code? How did it work 10, 20, 30year ago? Can you grab an
old copy and test? Are your thoughts about the precise behaviour beyond
what it has promised for decades?
Or is there a problem in commit 1.18? This chunk which inspects errno
bothers me a little bit, because the errno which is being looked at is
not from isatty() [which if it succeeds returns 0, and does not update
errno] but is against the value retained from a previous system call
failure (no idea which one might have returned -1 EBADF, or I doubt
anyone returned EBADF, in which case this no-ops the isatty() call):
- if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
+ if ((isatty(STDERR_FILENO) || errno == EBADF) &&
+ dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
nohup: fix error messages when stderr unavailable