On Sat, Mar 28, 2026 at 07:24:44AM +0100, Klaas van Aarsen wrote:
> Thanks for your timely responses.
> 
> However, it seems we cannot use errno after getch() returns ERR. In our
> testing, when a SIGHUP occurs, the underlying read() call simply returns 0
> (EOF) rather than a system error.
> Since ncurses appears to map both EOF and a halfdelay timeout to the same
> ERR value without setting errno, we lose the ability to distinguish between
> 'no input' and 'terminal gone.'
> 
> We could use napms() to throttle the CPU, but that leaves the process alive
> in a 'zombie' state until a user manually kills it.
> We really want to detect the disconnection and terminate gracefully.
> 
> It looks as if we are forced to set a global volatile sig_atomic_t flag on
> SIGHUP and check it manually every time getch() returns ERR.

If fileno(stdin) is actually closed, the read should set errno to EBADF (9).
You could close it in a signal handler for SIGHUP (that's safe), and check
error on ERR return from wgetch.

I seem to recall some discussion many years ago (e.g., ~20) where the
terminal was defunct, but didn't actually close the input -- I think
the responsibility for that should be in the calling application since
_it_ has to know what's a graceful way to shut down.
 
But if you're already getting ERR from wgetch (as indicated in the initial
report), I don't see what state stdin might be in if there's no errno set.

> Does ncurses provide any internal mechanism to distinguish an EOF from a
> timeout, or is the signal-flag approach the standard way to handle this in
> a curses application?
> 
> 
> 
> On Sat, Mar 28, 2026 at 12:30 AM G. Branden Robinson <
> [email protected]> wrote:
> 
> > At 2026-03-27T18:23:57-0400, Thomas Dickey wrote:
> > > On Fri, Mar 27, 2026 at 06:40:42PM +0100, Klaas van Aarsen wrote:
> > > > We have a bug in the Angband code related to getch of ncurses (
> > > > https://github.com/angband/angband/pull/6559).
> > > > It turns out that getch returns ERR when the terminal connection is
> > > > broken (SIGHUP). The code currently interprets it as a timeout (set
> > > > by halfdelay) and spins on input, leaving a zombie process with 100%
> > > > CPU.  The man page on getch only mentions that errno might be EINTR
> > > > if the getch call is interrupted, but nothing on a broken terminal
> > > > connection.  How might we detect that the terminal connection is
> > > > broken?
> > [...]
> > > ...mixing getch with fgets doesn't appear to be a good idea, since
> > > ncurses doesn't use the input stream -- only the file descriptor.
> > > Expect some difference in behavior.
> >
> > The ncurses man pages explain this, too.
> >
> > ncurses(3NCURSES):
> >
> > ENVIRONMENT
> > ...
> >    NCURSES_NO_SETBUF
> >      (Obsolete) Prior to internal changes developed in ncurses 5.9
> >      (patches 20120825 through 20130126), the library used setbuf(3) to
> >      enable fully buffered output when initializing the terminal.  This
> >      was done, as in SVr4 curses, to increase performance.  For testing
> >      purposes, both of ncurses and of certain applications, this feature
> >      was made optional.  Setting this variable disabled output
> >      buffering, leaving the output stream in the original (usually line‐
> >      buffered) mode.
> >
> >      Nowadays, ncurses performs its own buffering and does not require
> >      this workaround; it does not modify the buffering of the standard
> >      output stream.  This approach makes the library’s handling of
> >      keyboard‐initiated signals more robust.  A drawback is that certain
> >      unconventional programs mixed stdio(3) calls with ncurses calls and
> >      (usually) got the behavior they expected.  This is no longer the
> >      case; ncurses does not write to the standard output file descriptor
> >      through a stdio‐buffered stream.
> >
> >      As a special case, low‐level API calls such as putp(3NCURSES) still
> >      use the standard output stream.  High‐level curses calls such as
> >      printw(3NCURSES) do not.
> >
> > Regards,
> > Branden
> >

-- 
Thomas E. Dickey <[email protected]>
https://invisible-island.net

Attachment: signature.asc
Description: PGP signature

Reply via email to