From: "Theo de Raadt" Subject: Re: nohup: fix error messages when stderr unavailable To: mcq Cc: tech@openbsd.org Date: Fri, 06 Feb 2026 20:15:15 -0700 mcq 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) {