Index | Thread | Search

From:
mcq <mcq@disroot.org>
Subject:
Re: nohup: fix error messages when stderr unavailable
To:
Theo de Raadt <deraadt@openbsd.org>
Cc:
tech@openbsd.org
Date:
Sat, 07 Feb 2026 12:56:19 -0600

Download raw body.

Thread
On 2026-02-06 19:15, Theo de Raadt wrote:

> But I don't think you have understood correctly how kernel+libc handles
> fd0-2, with the FILE* on top of that...

you're correct. apologies for the original "bug fix." thank you for the
detailed explanation. i didn't originally understand the fd behavior.

after more testing, i see by the time fprintf(stdin, ...) line
executes, the file descriptors do indeed point to the same file. i was
confusing the file with the underlying fd behavior.

> I think this extremely weird code is as correct as it can be, unless it
> stops using the stdio layer.

i'm curious about this. would reimplementing the file without using the
stdio layer be worth the effort? or should this ancient code stay
untouched because it works fine?

> Have you considered that it is behaving correctly?

originally, i hadn't fully considred that. i was too quick to assume
i found a bug.

> You think you've found a bug in ancient code? How did it work
> 10, 20, 30 year ago?

honestly, grabbing a copy yields most of the exact same behavior.

> 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):

(do take this with a grain of salt, i didn't actually test the nohup.c
file. the test case where
if (isatty(STDERR_FILENO) || errno == EBADF &&
dup2(STDOUT_FILENO, STDERR_FILENO == -1) executes is actually very
hard to obtain in practice.)

actually, i did some testing in my own files, and i found that the
commit 1.18 is actually correct. isatty does set EBADF when called
on closed fds, so it's not checking stale values.

after more testing in read only directories where redirection to the
user's home directory occurs, i found when you close stderr, the
message:

"sending output to nohup.out"

is written to nohup.out and the user never sees it inside the
terminal. i think this is because open reuses fd 2 and never
closes it. when this line executes:

fprintf(stderr, "sending output to %s\n"), p);
writes to fd 2 -> into nohup.out

i assume this is intentional?

> As a general rule, extending behaviours must be done with great care
> because even minor changes can have unexpectedly great impact on real
> life programs.
> 
> not calling you Jia Tan, but your mail is weak on making your case.  
> it's
> worse -- you don't even try to show that it is important.  why is it 
> not
> important enough for you to show where it is important?

i understand the concern. i should have tested further, and thought
about the implications of small changes' impact on running systems.
as for my mail, it wasn't even correct in the first place, but worse,
as you stated i didn't even try to explain why the change made
sense.

thank you for your patience.