Debian Bug report logs - #339518
ncurses: doesn't retry on EINTR when setting tty to noecho in initscr()

version graph

Package: libncurses5; Maintainer for libncurses5 is Craig Small <csmall@debian.org>; Source for libncurses5 is src:ncurses.

Reported by: pmaydell@chiark.greenend.org.uk

Date: Wed, 16 Nov 2005 21:03:05 UTC

Severity: normal

Found in version libncurses5/5.4-4

Fixed in version ncurses/5.5-2

Done: Daniel Jacobowitz <dan@debian.org>

Bug is archived. No further changes may be made.

Toggle useless messages

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to debian-bugs-dist@lists.debian.org, Daniel Jacobowitz <ncurses-maint@debian.org>:
Bug#339518; Package libncurses5. Full text and rfc822 format available.

Acknowledgement sent to pmaydell@chiark.greenend.org.uk:
New Bug report received and forwarded. Copy sent to Daniel Jacobowitz <ncurses-maint@debian.org>. Full text and rfc822 format available.

Message #5 received at submit@bugs.debian.org (full text, mbox):

From: pmaydell@chiark.greenend.org.uk
To: submit@bugs.debian.org
Subject: ncurses: doesn't retry on EINTR when setting tty to noecho in initscr()
Date: Wed, 16 Nov 2005 20:44:48 +0000
Package: libncurses5
Version: 5.4-4

[source inspection suggests upstream's 5.5 still has this bug.]

This is obviously an upstream bug, but I report it to the Debian BTS
in the first instance, for you to forward upstream or fix locally,
as you choose.

The ncurses library, as part of the setup it does in initscr(), calls
tcsetattr() (or moral equivalent) to set the TTY into non-echoing mode.
(To be exact, initscr() calls newterm() calls _nc_initscr() calls
_nc_set_tty_mode() calls GET_TTY().) Unfortunately nothing is handling
the possibility that a signal interrupts tcsetattr and causes it to
return EINTR (the correct response is to retry the call). Moreover,
newterm() ignores the return value from _nc_initscr() so the application
has no chance to find out that initialisation didn't work.

I wouldn't be surprised to find that other parts of ncurses also
failed to handle EINTR correctly; but I haven't checked.

I'm going to append a test program which demonstrates the problem.
The idea of the test program is that because we've started curses
and disabled echoing no characters should be printed in response
to typing. But if we arrange for lots of signals to be received
while we're running initscr() then sometimes the echoing isn't disabled
because the tcsetattr() returned EINTR. You might have to try
running the program multiple times to get the bug to trigger.

(I ran into this whilst developing a genuine application, where it
manifested as a very annoyingly intermittent phenomenon.)

-- Peter Maydell

===begin cursesbug.c===
/* Demonstrate curses bug. Compile with:
 *  gcc -g -Wall -o cursesbug cursesbug.c -lcurses
 *
 * Run with: reset ; ./cursesbug [no]
 * (the reset is to make sure you have a clean terminal before starting)
 * If the optional argument is specified then we don't generate all the
 * SIGALRMs.
 * When the prompt says, try typing. Nothing should be echoed but if
 * signals are flying around then there's a chance that keys will be
 * echoed. It's a race condition so you might have to try running the
 * program multiple times to trigger it.
 */

#include <curses.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <errno.h>

sig_atomic_t quitnow = 0;

void handler(int signum)
{
   if (signum == SIGTERM)
      quitnow = 1;
}

void register_handler(int sig)
{
   struct sigaction sa;
   sigset_t ss;
   int i;
   
   sa.sa_flags = 0;
   sa.sa_handler = handler;
   sigfillset(&sa.sa_mask);
   do 
   {
      i = sigaction(sig, &sa, NULL);
   } while (i == -1 && errno == EINTR);
   if (i == -1) {
      perror("sigaction failed");
      exit(1);
   }

   sigemptyset(&ss);
   sigaddset(&ss, sig);
   do 
   {
      i = sigprocmask(SIG_UNBLOCK, &ss, NULL);
   } while (i == -1 && errno == EINTR);
   if (i == -1) {
      perror("sigprocmask failed");
      exit(1);
   }
}

void start_signal_storm(void)
{
   struct itimerval p;
   int i;
   register_handler(SIGALRM);

   p.it_value.tv_sec = p.it_interval.tv_sec = 0;
   p.it_value.tv_usec = p.it_interval.tv_usec = 1;
   
   do 
   {
      i = setitimer(ITIMER_REAL, &p, NULL);
   } while (i == -1 && errno == EINTR);

   if (i == -1) {
      perror("setitimer failed");
      exit(1);
   }
}

void blockalarms(void)
{
   sigset_t set;
   int i;
   sigemptyset(&set);
   sigaddset(&set, SIGALRM);
   do 
   {
      i = sigprocmask(SIG_BLOCK, &set, NULL);
   } while (i == -1 && errno == EINTR);
   if (i == -1) {
      perror("sigprocmask failed");
      exit(1);
   }
}

int main(int argc, char **argv) 
{
   register_handler(SIGTERM);
   if (argc == 1) {
      fprintf(stderr, "Starting signal storm...\n");
      start_signal_storm();
   } else {
      fprintf(stderr, "Running without signal storm...\n");
   }
   
   if (!initscr()) {
      fprintf(stderr, "initscr failed\n");
      return 1;
   }
   if (cbreak() == ERR) {
      fprintf(stderr, "cbreak failed\n");
      return 1;
   }
   if (noecho() == ERR) {
      fprintf(stderr, "noecho failed\n");
      return 1;
   }
   if (clear() == ERR) {
      fprintf(stderr, "noecho failed\n");
      return 1;
   }
   if (addstr("Start typing now: any echoing is a bug...\n") == ERR) 
   {
      fprintf(stderr, "addstr failed\n");
      return 1;
   }
   if (refresh() == ERR) {
      fprintf(stderr, "noecho failed\n");
      return 1;
   }
   while (!quitnow) {
      /* this will get woken up by the SIGALRMs, of course */
      sleep(1);
   }
   /* get here on SIGTERM */
   blockalarms();
   if (endwin() == ERR) {
      fprintf(stderr, "endwin failed\n");
      return 1;
   }
   fprintf(stderr, "Done.\n");
   return 0;
}
===endit===



Reply sent to Daniel Jacobowitz <dan@debian.org>:
You have taken responsibility. Full text and rfc822 format available.

Notification sent to pmaydell@chiark.greenend.org.uk:
Bug acknowledged by developer. Full text and rfc822 format available.

Message #10 received at 339518-close@bugs.debian.org (full text, mbox):

From: Daniel Jacobowitz <dan@debian.org>
To: 339518-close@bugs.debian.org
Subject: Bug#339518: fixed in ncurses 5.5-2
Date: Tue, 02 May 2006 10:15:05 -0700
Source: ncurses
Source-Version: 5.5-2

We believe that the bug you reported is fixed in the latest version of
ncurses, which is due to be installed in the Debian FTP archive:

lib32ncurses5-dev_5.5-2_amd64.deb
  to pool/main/n/ncurses/lib32ncurses5-dev_5.5-2_amd64.deb
lib32ncurses5_5.5-2_amd64.deb
  to pool/main/n/ncurses/lib32ncurses5_5.5-2_amd64.deb
libncurses5-dbg_5.5-2_amd64.deb
  to pool/main/n/ncurses/libncurses5-dbg_5.5-2_amd64.deb
libncurses5-dev_5.5-2_amd64.deb
  to pool/main/n/ncurses/libncurses5-dev_5.5-2_amd64.deb
libncurses5_5.5-2_amd64.deb
  to pool/main/n/ncurses/libncurses5_5.5-2_amd64.deb
libncursesw5-dbg_5.5-2_amd64.deb
  to pool/main/n/ncurses/libncursesw5-dbg_5.5-2_amd64.deb
libncursesw5-dev_5.5-2_amd64.deb
  to pool/main/n/ncurses/libncursesw5-dev_5.5-2_amd64.deb
libncursesw5_5.5-2_amd64.deb
  to pool/main/n/ncurses/libncursesw5_5.5-2_amd64.deb
ncurses-base_5.5-2_all.deb
  to pool/main/n/ncurses/ncurses-base_5.5-2_all.deb
ncurses-bin_5.5-2_amd64.deb
  to pool/main/n/ncurses/ncurses-bin_5.5-2_amd64.deb
ncurses-term_5.5-2_all.deb
  to pool/main/n/ncurses/ncurses-term_5.5-2_all.deb
ncurses_5.5-2.diff.gz
  to pool/main/n/ncurses/ncurses_5.5-2.diff.gz
ncurses_5.5-2.dsc
  to pool/main/n/ncurses/ncurses_5.5-2.dsc



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 339518@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Daniel Jacobowitz <dan@debian.org> (supplier of updated ncurses package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.7
Date: Sun, 30 Apr 2006 16:35:05 -0400
Source: ncurses
Binary: ncurses-base lib64ncurses5 libncursesw5-dev libncursesw5-dbg ncurses-bin libncurses5 libncursesw5 libncurses5-dev ncurses-term lib32ncurses5-dev lib32ncurses5 libncurses5-dbg lib64ncurses5-dev
Architecture: source amd64 all
Version: 5.5-2
Distribution: unstable
Urgency: low
Maintainer: Daniel Jacobowitz <ncurses-maint@debian.org>
Changed-By: Daniel Jacobowitz <dan@debian.org>
Description: 
 lib32ncurses5 - Shared libraries for terminal handling (32-bit)
 lib32ncurses5-dev - Developer's libraries for ncurses (32-bit)
 libncurses5 - Shared libraries for terminal handling
 libncurses5-dbg - Debugging/profiling libraries for ncurses
 libncurses5-dev - Developer's libraries and docs for ncurses
 libncursesw5 - Shared libraries for terminal handling (wide character support)
 libncursesw5-dbg - Debugging/profiling libraries for ncurses
 libncursesw5-dev - Developer's libraries for ncursesw
 ncurses-base - Descriptions of common terminal types
 ncurses-bin - Terminal-related programs and man pages
 ncurses-term - Additional terminal type definitions
Closes: 316663 334099 335655 338234 339518 341661 344022 344442 354281 355129 364339
Changes: 
 ncurses (5.5-2) unstable; urgency=low
 .
   * Update to upstream patch level 20060422.
     - Correct missing and bogus copyright notices (Closes: #364339).
     - Correct a typo in the infocmp(1) man page (Closes: 354281).
     - Correct wins_nwstr for single-column non-8bit codes (Closes: #341661).
     - Remove a redundant test in lib_color.c (Closes: #335655).
     - Ignore EINTR in tcgetattr/tcsetattr calls (Closes: #339518).
     - Correct smacs in cygwin terminfo (Closes: #338234).
     - Two additional fixes for wide character display (Closes: #316663)
       (again).
   * Acknowledge NMU (Closes: #355129).
   * Update control file for the removal of Section: base.
   * Use DEB_HOST_ARCH to determine whether to build biarch packages,
     based on patch from Aurelien Jarno (Closes: #334099).
   * Make lib64ncurses5-dev depend on lib64c-dev (Closes: #344022).
   * Add 32-bit library support on amd64, based loosely on Ubuntu
     patch (Closes: #344442).
   * Package debugging versions of libncurses++.a.
   * Update to debhelper compatibility level 5.
   * Update policy version to 3.7.0.0.
   * Use shorter symlinks within terminfo directories when possible
     (e.g. xx -> xy instead of xx -> ../x/xy).
Files: 
 67d1c3aeade59080eef852163369aad1 1016 libs standard ncurses_5.5-2.dsc
 e364f6c9b4069858811380d9413aa4c1 267511 libs standard ncurses_5.5-2.diff.gz
 5f8ac6f2c5152312ecb99d16b2b2694f 326914 libs required libncurses5_5.5-2_amd64.deb
 44f7971b876d8cc3bd938d30ef4086e1 1397902 libdevel optional libncurses5-dev_5.5-2_amd64.deb
 fa793b111679e39e6aac5652d0a7b58a 1625338 libdevel extra libncurses5-dbg_5.5-2_amd64.deb
 013032d9e1a01eadaf3e4154c05fc959 346736 libs important libncursesw5_5.5-2_amd64.deb
 ff2c0635f32d9a6d8f87c6e312a839eb 468774 libdevel optional libncursesw5-dev_5.5-2_amd64.deb
 bbd416d325ec51d229c18597bdb84401 1820344 libdevel extra libncursesw5-dbg_5.5-2_amd64.deb
 04636992af89ec30cd06ac18dada041f 299652 libs optional lib32ncurses5_5.5-2_amd64.deb
 8b8ca4b089a10bd5407625b94bc6e2e0 357666 libdevel optional lib32ncurses5-dev_5.5-2_amd64.deb
 7697188007849a705bc1efca8af7de32 230776 utils required ncurses-bin_5.5-2_amd64.deb
 fe09b1b13bb5a5e0e914e3a6490c31cd 12848 utils required ncurses-base_5.5-2_all.deb
 db626d5770c5b02d1558ee43a34759d7 277468 admin standard ncurses-term_5.5-2_all.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)

iD8DBQFEVTPbbgOPXuCjg3cRAngGAKCfr5oyaW7U50fclhLvwsyye4WivgCdFjBo
YedoELXd6ahM8lkmXxb10YU=
=CTxs
-----END PGP SIGNATURE-----




Bug archived. Request was from Debbugs Internal Request <owner@bugs.debian.org> to internal_control@bugs.debian.org. (Sun, 24 Jun 2007 18:43:32 GMT) Full text and rfc822 format available.

Send a report that this bug log contains spam.


Debian bug tracking system administrator <owner@bugs.debian.org>. Last modified: Fri Apr 18 16:35:22 2014; Machine Name: buxtehude.debian.org

Debian Bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.