-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
--- $Id: NEWS,v 1.1942 2012/08/11 21:30:05 tom Exp $
+-- $Id: NEWS,v 1.1943 2012/08/25 20:02:00 tom Exp $
-------------------------------------------------------------------------------
This is a log of changes that ncurses has gone through since Zeyd started
Changes through 1.9.9e did not credit all contributions;
it is not possible to add this information.
+20120825
+ + change output buffering scheme, using buffer maintained by ncurses
+ rather than stdio, to avoid problems with SIGTSTP handling (report
+ by Brian Bloniarz).
+
20120811
+ update autoconf patch to 2.52.20120811, adding --datarootdir
(prompted by discussion with Erwin Waterlander).
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
-# $Id: dist.mk,v 1.886 2012/08/11 15:55:23 tom Exp $
+# $Id: dist.mk,v 1.887 2012/08/25 16:47:15 tom Exp $
# Makefile for creating ncurses distributions.
#
# This only needs to be used directly as a makefile by developers, but
# These define the major/minor/patch versions of ncurses.
NCURSES_MAJOR = 5
NCURSES_MINOR = 9
-NCURSES_PATCH = 20120811
+NCURSES_PATCH = 20120825
# We don't append the patch to the version, since this only applies to releases
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
/****************************************************************************
- * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
extern int malloc_errfd; /* FIXME */
#endif
-MODULE_ID("$Id: lib_freeall.c,v 1.60 2011/10/22 16:34:50 tom Exp $")
+MODULE_ID("$Id: lib_freeall.c,v 1.61 2012/08/25 19:52:47 tom Exp $")
/*
* Free all ncurses data. This is used for testing only (there's no practical
NCURSES_EXPORT(void)
NCURSES_SP_NAME(_nc_free_and_exit) (NCURSES_SP_DCLx int code)
{
- char *last_setbuf = (SP_PARM != 0) ? SP_PARM->_setbuf : 0;
+ char *last_buffer = (SP_PARM != 0) ? SP_PARM->out_buffer : 0;
+ NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
NCURSES_SP_NAME(_nc_freeall) (NCURSES_SP_ARG);
#ifdef TRACE
trace(0); /* close trace file, freeing its setbuf */
free(_nc_varargs("?", fake));
}
#endif
- fclose(stdout);
- FreeIfNeeded(last_setbuf);
+ FreeIfNeeded(last_buffer);
exit(code);
}
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_set_term.c,v 1.141 2012/07/07 20:37:40 tom Exp $")
+MODULE_ID("$Id: lib_set_term.c,v 1.143 2012/08/25 20:10:40 tom Exp $")
#ifdef USE_TERM_DRIVER
#define MaxColors InfoOf(sp).maxcolors
FreeIfNeeded(sp->_acs_map);
FreeIfNeeded(sp->_screen_acs_map);
- /*
- * If the associated output stream has been closed, we can discard the
- * set-buffer. Limit the error check to EBADF, since fflush may fail
- * for other reasons than trying to operate upon a closed stream.
- */
- if (sp->_ofp != 0
- && sp->_setbuf != 0
- && fflush(sp->_ofp) != 0
- && errno == EBADF) {
- free(sp->_setbuf);
- }
-
+ NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx sp->_term);
free(sp);
sp->_lines = (NCURSES_SIZE_T) slines;
sp->_lines_avail = (NCURSES_SIZE_T) slines;
sp->_columns = (NCURSES_SIZE_T) scolumns;
+
+ fflush(output);
+ sp->_ofd = output ? fileno(output) : -1;
sp->_ofp = output;
+ sp->out_limit = (size_t) (slines * scolumns);
+ if ((sp->out_buffer = malloc(sp->out_limit)) == 0)
+ sp->out_limit = 0;
+ sp->out_inuse = 0;
+
SP_PRE_INIT(sp);
SetNoPadding(sp);
****************************************************************************/
/*
- * $Id: curses.priv.h,v 1.502 2012/07/14 21:14:30 tom Exp $
+ * $Id: curses.priv.h,v 1.505 2012/08/25 20:49:15 tom Exp $
*
* curses.priv.h
*
* Global data which is not specific to a screen.
*/
typedef struct {
+ SIG_ATOMIC_T have_sigtstp;
SIG_ATOMIC_T have_sigwinch;
SIG_ATOMIC_T cleanup_nested;
*/
struct screen {
- int _ifd; /* input file ptr for screen */
+ int _ifd; /* input file descriptor for screen */
+ int _ofd; /* output file descriptor for screen */
FILE *_ofp; /* output file ptr for screen */
- char *_setbuf; /* buffered I/O for output */
+ char *out_buffer; /* output buffer */
+ size_t out_limit; /* output buffer size */
+ size_t out_inuse; /* output buffer current use */
bool _filtered; /* filter() was called */
- bool _buffered; /* setvbuf uses _setbuf data */
bool _prescreen; /* is in prescreen phase */
bool _use_env; /* LINES & COLS from environment? */
int _checkfd; /* filedesc for typeahead check */
int *_oldnum_list;
int _oldnum_size;
- bool _cleanup; /* cleanup after int/quit signal */
NCURSES_SP_OUTC _outch; /* output handler if not putc */
int _legacy_coding; /* see use_legacy_coding() */
#define PUTC_DATA char PUTC_buf[MB_LEN_MAX]; int PUTC_i, PUTC_n; \
mbstate_t PUT_st; wchar_t PUTC_ch
#define PUTC_INIT init_mb (PUT_st)
-#define PUTC(ch,b) do { if(!isWidecExt(ch)) { \
+#define PUTC(ch) do { if(!isWidecExt(ch)) { \
if (Charable(ch)) { \
- fputc(CharOf(ch), b); \
+ NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_ARGx CharOf(ch)); \
COUNT_OUTCHARS(1); \
} else { \
PUTC_INIT; \
(ch).chars[PUTC_i], &PUT_st); \
if (PUTC_n <= 0) { \
if (PUTC_ch && is8bits(PUTC_ch) && PUTC_i == 0) \
- putc(PUTC_ch,b); \
+ NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_ARGx CharOf(ch)); \
break; \
+ } else { \
+ int PUTC_j; \
+ for (PUTC_j = 0; PUTC_j < PUTC_n; ++PUTC_j) { \
+ NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_ARGx PUTC_buf[PUTC_j]); \
+ } \
} \
- IGNORE_RC(fwrite(PUTC_buf, (size_t) PUTC_n, (size_t) 1, b)); \
} \
COUNT_OUTCHARS(PUTC_i); \
} } } while (0)
#define CHDEREF(wch) wch
#define ARG_CH_T NCURSES_CH_T
#define CARG_CH_T NCURSES_CH_T
-#define PUTC_DATA int data = 0
-#define PUTC(ch,b) do { data = CharOf(ch); putc(data,b); } while (0)
+#define PUTC_DATA /* nothing */
+#define PUTC(ch) NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_ARGx ch)
#define BLANK (' '|A_NORMAL)
#define ZEROS ('\0'|A_NORMAL)
FreeAndNull(my_blob);
if (my_list != 0)
FreeAndNull(my_list);
- for (which = 0; which < dbdLAST; ++which) {
+ for (which = 0; (int) which < dbdLAST; ++which) {
my_vars[which].name = 0;
FreeIfNeeded(my_vars[which].value);
my_vars[which].value = 0;
#include <curses.priv.h>
-MODULE_ID("$Id: lib_data.c,v 1.64 2012/07/14 21:01:49 tom Exp $")
+MODULE_ID("$Id: lib_data.c,v 1.65 2012/08/25 18:38:43 tom Exp $")
/*
* OS/2's native linker complains if we don't initialize public data when
#define TGETENT_0s { TGETENT_0, TGETENT_0, TGETENT_0, TGETENT_0 }
NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
+ 0, /* have_sigtstp */
0, /* have_sigwinch */
0, /* cleanup_nested */
#include <termcap.h> /* ospeed */
#include <tic.h>
-MODULE_ID("$Id: lib_tputs.c,v 1.84 2012/02/22 22:40:24 tom Exp $")
+MODULE_ID("$Id: lib_tputs.c,v 1.86 2012/08/25 21:22:08 tom Exp $")
NCURSES_EXPORT_VAR(char) PC = 0; /* used by termcap library */
NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0; /* used by termcap library */
NCURSES_EXPORT(void)
NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_DCL0)
{
- (void) fflush(NC_OUTPUT(SP_PARM));
+ if (SP_PARM->_ofd >= 0) {
+ if (SP_PARM->out_inuse) {
+ size_t amount = SP->out_inuse;
+ /*
+ * Help a little, if the write is interrupted, by first resetting
+ * our amount.
+ */
+ SP->out_inuse = 0;
+ (void) write(SP_PARM->_ofd, SP_PARM->out_buffer, amount);
+ }
+ }
}
#if NCURSES_SP_FUNCS
COUNT_OUTCHARS(1);
if (HasTInfoTerminal(SP_PARM)
- && SP_PARM != 0
- && SP_PARM->_cleanup) {
- char tmp = (char) ch;
- /*
- * POSIX says write() is safe in a signal handler, but the
- * buffered I/O is not.
- */
- if (write(fileno(NC_OUTPUT(SP_PARM)), &tmp, (size_t) 1) == -1)
- rc = ERR;
+ && SP_PARM != 0) {
+ if (SP_PARM->out_buffer != 0) {
+ if (SP_PARM->out_inuse + 1 >= SP_PARM->out_limit)
+ NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
+ SP_PARM->out_buffer[SP_PARM->out_inuse++] = (char) ch;
+ } else {
+ char tmp = (char) ch;
+ /*
+ * POSIX says write() is safe in a signal handler, but the
+ * buffered I/O is not.
+ */
+ if (write(fileno(NC_OUTPUT(SP_PARM)), &tmp, (size_t) 1) == -1)
+ rc = ERR;
+ }
} else {
- if (putc(ch, NC_OUTPUT(SP_PARM)) == EOF)
+ char tmp = (char) ch;
+ if (write(fileno(stdout), &tmp, (size_t) 1) == -1)
rc = ERR;
}
return rc;
/****************************************************************************
- * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include <curses.priv.h>
-MODULE_ID("$Id: setbuf.c,v 1.17 2011/10/22 16:34:50 tom Exp $")
+MODULE_ID("$Id: setbuf.c,v 1.19 2012/08/25 20:48:05 tom Exp $")
/*
- * If the output file descriptor is connected to a tty (the typical case) it
- * will probably be line-buffered. Keith Bostic pointed out that we don't want
- * this; it hoses people running over networks by forcing out a bunch of small
- * packets instead of one big one, so screen updates on ptys look jerky.
- * Restore block buffering to prevent this minor lossage.
- *
- * The buffer size is a compromise. Ideally we'd like a buffer that can hold
- * the maximum possible update size (the whole screen plus cup commands to
- * change lines as it's painted). On a 66-line xterm this can become
- * excessive. So we min it with the amount of data we think we can get through
- * two Ethernet packets (maximum packet size - 100 for TCP/IP overhead).
- *
- * Why two ethernet packets? It used to be one, on the theory that said
- * packets define the maximum size of atomic update. But that's less than the
- * 2000 chars on a 25 x 80 screen, and we don't want local updates to flicker
- * either. Two packet lengths will handle up to a 35 x 80 screen.
- *
- * The magic '6' is the estimated length of the end-of-line cup sequence to go
- * to the next line. It's generous. We used to mess with the buffering in
- * init_mvcur() after cost computation, but that lost the sequences emitted by
- * init_acs() in setupscreen().
- *
- * "The setvbuf function may be used only after the stream pointed to by stream
- * has been associated with an open file and before any other operation is
- * performed on the stream." (ISO 7.9.5.6.)
- *
- * Grrrr...
- *
- * On a lighter note, many implementations do in fact allow an application to
- * reset the buffering after it has been written to. We try to do this because
- * otherwise we leave stdout in buffered mode after endwin() is called. (This
- * also happens with SVr4 curses).
- *
- * There are pros/cons:
- *
- * con:
- * There is no guarantee that we can reestablish buffering once we've
- * dropped it.
- *
- * We _may_ lose data if the implementation does not coordinate this with
- * fflush.
- *
- * pro:
- * An implementation is more likely to refuse to change the buffering than
- * to do it in one of the ways mentioned above.
- *
- * The alternative is to have the application try to change buffering
- * itself, which is certainly no improvement.
- *
- * Just in case it does not work well on a particular system, the calls to
- * change buffering are all via the macro NC_BUFFERED. Some implementations
- * do indeed get confused by changing setbuf on/off, and will overrun the
- * buffer. So we disable this by default (there may yet be a workaround).
+ * Obsolete entrypoint retained for binary compatbility.
*/
NCURSES_EXPORT(void)
NCURSES_SP_NAME(_nc_set_buffer) (NCURSES_SP_DCLx FILE *ofp, int buffered)
{
- int Cols;
- int Lines;
-
- if (0 == SP_PARM)
- return;
-
- Cols = *(ptrCols(SP_PARM));
- Lines = *(ptrLines(SP_PARM));
-
- /* optional optimization hack -- do before any output to ofp */
-#if HAVE_SETVBUF || HAVE_SETBUFFER
- if (SP_PARM->_buffered != buffered) {
- unsigned buf_len;
- char *buf_ptr;
-
- if (getenv("NCURSES_NO_SETBUF") != 0)
- return;
-
- fflush(ofp);
-#ifdef __DJGPP__
- setmode(ofp, O_BINARY);
-#endif
- if (buffered != 0) {
- buf_len = (unsigned) min(Lines * (Cols + 6), 2800);
- if ((buf_ptr = SP_PARM->_setbuf) == 0) {
- if ((buf_ptr = typeMalloc(char, buf_len)) == NULL)
- return;
- SP_PARM->_setbuf = buf_ptr;
- /* Don't try to free this! */
- }
-#if !USE_SETBUF_0
- else
- return;
-#endif
- } else {
-#if !USE_SETBUF_0
- return;
-#else
- buf_len = 0;
- buf_ptr = 0;
-#endif
- }
-
-#if HAVE_SETVBUF
-#ifdef SETVBUF_REVERSED /* pre-svr3? */
- (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IOLBF);
-#else
- (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IOLBF, (size_t) buf_len);
-#endif
-#elif HAVE_SETBUFFER
- (void) setbuffer(ofp, buf_ptr, (int) buf_len);
+#if NCURSES_SP_FUNCS
+ (void) SP_PARM;
#endif
-
- SP_PARM->_buffered = buffered;
- }
-#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */
+ (void) ofp;
+ (void) buffered;
}
#if NCURSES_SP_FUNCS
/****************************************************************************
- * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include <SigAction.h>
-MODULE_ID("$Id: lib_tstp.c,v 1.45 2011/10/22 15:37:42 tom Exp $")
+MODULE_ID("$Id: lib_tstp.c,v 1.46 2012/08/25 19:52:47 tom Exp $")
#if defined(SIGTSTP) && (HAVE_SIGACTION || HAVE_SIGVEC)
#define USE_SIGTSTP 1
#if USE_SIGTSTP
static void
-tstp(int dummy GCC_UNUSED)
+handle_SIGTSTP(int dummy GCC_UNUSED)
{
SCREEN *sp = CURRENT_SCREEN;
sigset_t mask, omask;
int sigttou_blocked;
#endif
- T(("tstp() called"));
+ _nc_globals.have_sigtstp = 1;
+ T(("handle_SIGTSTP() called"));
/*
* The user may have changed the prog_mode tty bits, so save them.
#endif /* USE_SIGTSTP */
static void
-cleanup(int sig)
+handle_SIGINT(int sig)
{
SCREEN *sp = CURRENT_SCREEN;
for (each_screen(scan)) {
if (scan->_ofp != 0
&& isatty(fileno(scan->_ofp))) {
- scan->_cleanup = TRUE;
scan->_outch = NCURSES_SP_NAME(_nc_outch);
}
set_term(scan);
#if USE_SIGWINCH
static void
-sigwinch(int sig GCC_UNUSED)
+handle_SIGWINCH(int sig GCC_UNUSED)
{
_nc_globals.have_sigwinch = 1;
# if USE_PTHREADS_EINTR
#ifdef SA_RESTART
new_sigaction.sa_flags |= SA_RESTART;
#endif /* SA_RESTART */
- new_sigaction.sa_handler = tstp;
+ new_sigaction.sa_handler = handle_SIGTSTP;
(void) sigaction(SIGTSTP, &new_sigaction, NULL);
} else {
ignore_tstp = TRUE;
if (!_nc_globals.init_signals) {
if (enable) {
- CatchIfDefault(SIGINT, cleanup);
- CatchIfDefault(SIGTERM, cleanup);
+ CatchIfDefault(SIGINT, handle_SIGINT);
+ CatchIfDefault(SIGTERM, handle_SIGINT);
#if USE_SIGWINCH
- CatchIfDefault(SIGWINCH, sigwinch);
+ CatchIfDefault(SIGWINCH, handle_SIGWINCH);
#endif
_nc_globals.init_signals = TRUE;
}
#include <ctype.h>
-MODULE_ID("$Id: tty_update.c,v 1.268 2012/05/12 21:02:00 tom Exp $")
+MODULE_ID("$Id: tty_update.c,v 1.271 2012/08/25 21:04:03 tom Exp $")
/*
* This define controls the line-breakout optimization. Every once in a
{
int chlen = 1;
NCURSES_CH_T my_ch;
+#if USE_WIDEC_SUPPORT
PUTC_DATA;
+#endif
NCURSES_CH_T tilde;
NCURSES_CH_T attr = CHDEREF(ch);
}
UpdateAttrs(SP_PARM, attr);
+ PUTC(CHDEREF(ch));
#if !USE_WIDEC_SUPPORT
- /* FIXME - we do this special case for signal handling, should see how to
- * make it work for wide characters.
- */
- if (SP_PARM->_outch != 0) {
- SP_PARM->_outch(NCURSES_SP_ARGx UChar(ch));
- } else
+ COUNT_OUTCHARS(1);
#endif
- {
- PUTC(CHDEREF(ch), SP_PARM->_ofp); /* macro's fastest... */
- COUNT_OUTCHARS(1);
- }
SP_PARM->_curscol += chlen;
if (char_padding) {
TPUTS_TRACE("char_padding");
-ncurses6 (5.9-20120811) unstable; urgency=low
+ncurses6 (5.9-20120825) unstable; urgency=low
* latest weekly patch
- -- Thomas E. Dickey <dickey@invisible-island.net> Sat, 11 Aug 2012 17:52:54 -0400
+ -- Thomas E. Dickey <dickey@invisible-island.net> Sat, 25 Aug 2012 16:49:58 -0400
ncurses6 (5.9-20120608) unstable; urgency=low
Summary: shared libraries for terminal handling
Name: ncurses6
Release: 5.9
-Version: 20120811
+Version: 20120825
License: X11
Group: Development/Libraries
Source: ncurses-%{release}-%{version}.tgz