https://invisible-island.net/ncurses/
Copyright © 2021,2023 by Thomas E. Dickey
Here is the latest version of this file.
In [comp.unix.bsd] NetBSD, FreeBSD, and OpenBSD FAQ (Part 6 of 10), Dave Burgess (or some anonymous contributor) stated in 1997
5.0 Introduction 5.1 A replacement curses program/library. It is generally accepted that the NetBSD curses can be easily replaced by the ncurses package. It is more complete and offers much better support for shared libraries and other advanced features. The current (early 1995 version) is 1.8.5 and is available from ftp://ftp.netcom.com:/pub/zm/zmbenhal/ncurses/ OpenBSD comes with a different curses package, called XSI curses and uses the termlib library for user code. The original curses code is still available in the <ocurses.h> include file and the -locurses library. The code in the termlib library is smart enough to recognize and handle both termcap and termlib database parsing. (Ed.Note) The X/Open curses standard is becoming the de facto standard (or perhaps imposed standard) for curses under Unix systems. XSI implements this X/Open curses completely, and is being used by lots of folks. FreeBSD and NetBSD will either develop their own compatible version or will use XSI like OpenBSD does.
That FAQ is more than a little misleading:
OpenBSD bundles a copy of ncurses,
which in turn is based on the documentation for SVr4 and
X/Open Curses.
FreeBSD added a port for ncurses
commit 4197b0921566e82824cc27d5b1d5041654655e2c Author: Andrey A. Chernov <ache@FreeBSD.org> Date: Sun Sep 11 22:29:01 1994 +0000 libncurses added
and began using it in September 1994:
commit 255a44b709307c2c1aa1f59590af6efa7d0a258a Author: Andrey A. Chernov <ache@FreeBSD.org> Date: Fri Sep 30 05:41:22 1994 +0000 Remove emulation of upper/lower lines from all entries, this work done by ncurses
and in October 1994, moved it to the base system:
Moved from ports with several enhancements
OpenBSD began using both the ncurses library and the tic/infocmp utilities in June 1996:
commit ca751a4c440c24b9feedffffe0dd93cc1e00ab0c Author: tholo <tholo@openbsd.org> Date: Sun Jun 2 06:04:50 1996 +0000 Install ncurses as -lcurses and <curses.h> Install BSD curses library as -locurses and <ocurses.h>
Before that, OpenBSD used the curses imported from NetBSD (see header file).
Unlike OpenBSD, FreeBSD developers frequently update their copy of ncurses.
Because ncurses is part of the base system, OpenBSD developers chose to not provide a port which could be updated frequently:
Here are some notes which would be helpful in updating the FAQ.
OpenBSD curses (and the utilities) as of mid-2021 is ncurses 5.7 (2008), with some fixes from later versions of ncurses, as well as customization by OpenBSD developers. Not all of ncurses 5.7 is in the OpenBSD source tree. These subdirectories of ncurses are missing:
Ada95, c++, doc, test
Additionally, the makefiles are not generated by autoconf, and some of the source-files which would be generated during the build are stored directly in the OpenBSD source-tree. I wrote a simple script (200 lines of Perl) to transform the source-files to simplify comparison with the original files:
Disregarding the makefiles and the shared-library version, OpenBSD's ncurses has 440 files.
ncurses 5.7 has 1029 files; some directories are omitted and the top-level README, etc, also are omitted.
OpenBSD copies directly 427 files, and adds 10 generated files (produced by ncurses scripts).
Of those 437 files, 417 are modified.
However two thirds are only modified mechanically, adding CVS identfier and reflecting the renaming of manual pages (e.g., changing “3X” to “3”).
That leaves 140 files to consider, using a simple script to filter out the mechanical changes.
That total includes 67 manual pages, most of which differ only by changes which could be handled by a more complex script. Factoring that out leaves only the changes to the main ncurses manual page. OpenBSD deletes discussion of the tracing feature as well as the alternate library configurations. OpenBSD provides only the default wide-character library.
Of the 73 source-code files which differ from ncurses 5.7, some reflect changes copied from later versions of ncurses. The largest is an update of the terminal database to 2017/04/01. I accounted for that in my script; other changes were much smaller and not worth the time to factor out.
Here is a diffstat showing the amount of change for the 140 files:
form/frm_driver.c | 5 -
form/fty_int.c | 2
form/fty_num.c | 2
include/curses.h | 28 +++--
include/nc_tparm.h | 1
include/ncurses_cfg.h | 203 ++++++++++++++++++++----------------------
include/term.h | 17 ++-
include/term_entry.h | 6 +
include/termcap.h | 17 ++-
man/captoinfo.1m | 23 ++--
man/curs_add_wch.3x | 2
man/curs_addch.3x | 4
man/curs_extend.3x | 2
man/curs_getch.3x | 8 -
man/curs_opaque.3x | 6 -
man/curs_printw.3x | 6 -
man/curs_scanw.3x | 6 -
man/curs_scr_dump.3x | 2
man/curs_termcap.3x | 10 +-
man/curs_terminfo.3x | 8 -
man/form.3x | 2
man/form_cursor.3x | 4
man/form_data.3x | 4
man/form_field.3x | 6 -
man/form_field_attributes.3x | 7 +
man/form_field_buffer.3x | 6 -
man/form_field_info.3x | 4
man/form_field_just.3x | 4
man/form_field_new.3x | 6 -
man/form_field_opts.3x | 9 +
man/form_field_userptr.3x | 5 -
man/form_field_validation.3x | 7 -
man/form_fieldtype.3x | 6 -
man/form_hook.3x | 8 +
man/form_new.3x | 4
man/form_new_page.3x | 4
man/form_opts.3x | 8 +
man/form_page.3x | 6 -
man/form_post.3x | 5 -
man/form_requestname.3x | 6 -
man/form_userptr.3x | 5 -
man/form_win.3x | 6 -
man/infocmp.1m | 43 ++++----
man/infotocap.1m | 23 ++--
man/keybound.3x | 4
man/legacy_coding.3x | 2
man/menu.3x | 2
man/menu_attributes.3x | 8 +
man/menu_cursor.3x | 4
man/menu_driver.3x | 2
man/menu_format.3x | 4
man/menu_hook.3x | 8 +
man/menu_items.3x | 5 -
man/menu_mark.3x | 4
man/menu_new.3x | 4
man/menu_opts.3x | 8 +
man/menu_pattern.3x | 5 -
man/menu_post.3x | 5 -
man/menu_requestname.3x | 5 -
man/menu_spacing.3x | 5 -
man/menu_userptr.3x | 5 -
man/menu_win.3x | 7 +
man/mitem_current.3x | 8 +
man/mitem_name.3x | 7 -
man/mitem_new.3x | 6 -
man/mitem_opts.3x | 9 +
man/mitem_userptr.3x | 7 -
man/mitem_value.3x | 6 -
man/mitem_visible.3x | 6 -
man/ncurses.3x | 149 ++++++------------------------
man/panel.3x | 11 +-
man/resizeterm.3x | 2
man/term.5 | 16 +--
man/term.7 | 16 +--
man/terminfo.5 | 32 +++---
man/tic.1m | 21 ++--
menu/m_item_new.c | 2
misc/tabset/stdcrt | 2
misc/tabset/vt100 | 1
misc/tabset/vt300 | 1
misc/terminfo.src | 74 +++++++++++++--
ncurses/base/MKkeyname.awk | 11 +-
ncurses/base/MKlib_gen.sh | 1
ncurses/base/MKunctrl.awk | 1
ncurses/base/keybound.c | 3
ncurses/base/lib_mouse.c | 4
ncurses/base/lib_newwin.c | 2
ncurses/base/lib_redrawln.c | 8 -
ncurses/base/lib_set_term.c | 1
ncurses/base/resizeterm.c | 4
ncurses/base/safe_sprintf.c | 6 +
ncurses/base/vsscanf.c | 5 -
ncurses/curses.priv.h | 25 ++++-
ncurses/tinfo/MKfallback.sh | 27 -----
ncurses/tinfo/access.c | 12 +-
ncurses/tinfo/alloc_entry.c | 18 ++-
ncurses/tinfo/captoinfo.c | 18 ++-
ncurses/tinfo/comp_error.c | 2
ncurses/tinfo/comp_expand.c | 10 +-
ncurses/tinfo/comp_hash.c | 2
ncurses/tinfo/comp_parse.c | 20 ++--
ncurses/tinfo/comp_scan.c | 2
ncurses/tinfo/doalloc.c | 4
ncurses/tinfo/home_terminfo.c | 6 -
ncurses/tinfo/lib_baudrate.c | 4
ncurses/tinfo/lib_cur_term.c | 2
ncurses/tinfo/lib_print.c | 8 -
ncurses/tinfo/lib_setup.c | 5 -
ncurses/tinfo/lib_termcap.c | 9 +
ncurses/tinfo/lib_tgoto.c | 10 +-
ncurses/tinfo/lib_tparm.c | 4
ncurses/tinfo/lib_tputs.c | 4
ncurses/tinfo/make_keys.c | 2
ncurses/tinfo/parse_entry.c | 12 +-
ncurses/tinfo/read_entry.c | 20 ++--
ncurses/tinfo/read_termcap.c | 25 +----
ncurses/tinfo/strings.c | 4
ncurses/tinfo/trim_sgr0.c | 2
ncurses/tinfo/write_entry.c | 21 ++--
ncurses/trace/lib_trace.c | 4
ncurses/trace/lib_traceatr.c | 16 +--
ncurses/trace/lib_tracebits.c | 39 ++++----
ncurses/trace/lib_tracechr.c | 9 +
ncurses/trace/lib_tracemse.c | 10 +-
ncurses/trace/trace_buf.c | 11 +-
ncurses/trace/trace_tries.c | 5 -
ncurses/trace/varargs.c | 10 +-
ncurses/trace/visbuf.c | 14 +-
ncurses/tty/MKexpanded.sh | 3
ncurses/tty/hardscroll.c | 10 +-
ncurses/tty/hashmap.c | 8 -
ncurses/tty/lib_mvcur.c | 10 +-
ncurses/tty/lib_tstp.c | 18 +++
ncurses/tty/tty_update.c | 6 +
panel/panel.c | 8 -
progs/dump_entry.c | 47 ++++-----
progs/infocmp.c | 107 ++++++++++++----------
progs/progs.priv.h | 2
progs/tic.c | 52 ++++++----
progs/tset.c | 87 ++++++------------
140 files changed, 950 insertions(+), 859 deletions(-)
For a better perspective, as of mid-2021, OpenBSD curses differs from the original ncurses sources by about 1.7% (compared to the total 115140 lines).
Beginning in 1999, Todd Miller developed a function which could read a terminfo description from a hashed database (see source). There were pros/cons:
access to the hashed database is potentially faster, but
storing the description in text format as done by Miller requires a larger ncurses library, and is slower than reading a formatted binary file.
I kept the idea (hashed database) in mind, and in 2006 re-implemented this without the latter limitation:
+ add configure --with-hashed-db option (tested only with FreeBSD 6.0, e.g., the db 1.8.5 interface).
I use this feature on all of my BSD ports. It has been in use on FreeBSD since 2013.
An OpenBSD change in 2015 dropped Miller's hashed-database reader. The commit message indicates that the developers did not understand that both hashed database and directory-tree are documented, supported features of ncurses:
Instead of using our own custom BDB terminfo databases, use the ncurses files in /usr/share/terminfo/*. This removes a large difference from upstream ncurses and other systems.
As of mid-2021, OpenBSD uses only the directory-tree terminal database.
While ncurses has provided signal handlers for other purposes,
the one for SIGWINCH
has gotten the most
attention.
Although OpenBSD provided a more-or-less complete set of manual pages, including resizeterm (see CVS source), it took several years to actually provide a SIGWINCH handler in OpenBSD curses so that KEY_RESIZE could be used.
Initially, no reason was given. The developer disabled it by
editing the generated ncurses_cfg.h
, but did not
mention this fact in any commit (see CVS
history). These symbols were removed:
--enable-sigwinch
configure option.The configure option's default value changed over time:
--with-develop
option.The CVS differences show that Miller noticed this “new” feature (which had been in development over the previous two years), and disabled it in the ncurses-4.2-990301 update:
=================================================================== RCS file: /cvs/src/lib/libcurses/ncurses_cfg.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- src/lib/libcurses/ncurses_cfg.h 1999/01/31 20:25:38 1.10 +++ src/lib/libcurses/ncurses_cfg.h 1999/03/02 06:23:27 1.11 @@ -1,4 +1,4 @@ -/* $OpenBSD: ncurses_cfg.h,v 1.10 1999/01/31 20:25:38 millert Exp $ */ +/* $OpenBSD: ncurses_cfg.h,v 1.11 1999/03/02 06:23:27 millert Exp $ */ /* include/ncurses_cfg.h. Generated automatically by configure. */ /**************************************************************************** @@ -115,6 +115,7 @@ #define USE_DATABASE 1 #define USE_GETCAP 1 #define USE_HASHMAP 1 +/* #define USE_SIGWINCH 1 */ /* The C compiler may not treat these properly but C++ has to */ #ifdef __cplusplus
I did not notice it myself, but after several years X ran well enough on OpenBSD that others noticed. There were a few mailing list threads in 2007-2008 dealing with the topic:
I posted to those threads, e.g., my reply to Ed Schouten:
List: openbsd-tech Subject: Re: [ncurses] USE_SIGWINCH disabled From: Thomas Dickey <dickey () radix ! net> Date: 2007-04-07 14:22:23 Message-ID: 20070407142223.GA8783 () saltmine ! radix ! net On Sat, Apr 07, 2007 at 01:34:32PM +0000, Ed Schouten wrote: > I took a look at the following file in OpenBSD's repository: > > http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libcurses/ncurses_cfg.h > > The reason why terminal resizing was broken in the first reason is > because USE_SIGWINCH is disabled (almost at the bottom). This option The commit comment doesn't mention the change - only ncurses-4.2-990301 ... > that already have their own handler, because those will overrule the > handler supplied by ncurses. In fact, ncurses 5.6 has it enabled by > default. It's been enabled by default for eight years. > Are there any plans to enable USE_SIGWINCH on OpenBSD, or even better, > bump ncurses to version 5.6? Thanks :) Looks like OpenBSD has ncurses 5.2 - 7 years old.
Miller responded indirectly (here):
List: openbsd-bugs Subject: Re: OpenBSD's ncurses doesn't have USE_SIGWINCH From: "Todd C. Miller" <Todd.Miller () courtesan ! com> Date: 2007-04-17 17:39:13 Message-ID: 200704171739.l3HHdDLq007909 () tex ! courtesan ! com [Download RAW message or body] In message <20070416220123.GH98082@hoeg.nl> so spake Ed Schouten (ed): > As you can see, USE_SIGWINCH is commented, which disables the handler. > It's quite irritating that you still have to write your own wrappers > while almost all other operating systems that include ncurses ship with > a working SIGWINCH handler. It was disabled in OpenBSD because we could not convince ourselves that it was safe (there is actually very little that is safe to do in a signal handler). In this case, it doesn't look like insertion and deletion of entries to _nc_screen_chain are guaranteed atomic so a signal at the right (wrong) time could potentially corrupt the chain. If all the signal handler did was set a flag (as opposed to traversing a list that may be under construction) it would be safe. - todd
as did De Raadt, though neither went beyond comments (i.e., neither has ever contributed any code to improving this area). De Raadt's comment about sig_atomic_t was useful:
Please note that _nc_screen_chain is a pointer, and the C standard specifically says that nothing but a variable of a sig_atomic_t is safe to atomically modify. People also end up having to use volatile to convince the compiler to not defer source-code requested modifications. Todd suggests that a solution to this problem will be to make the signal handler modify one global variable (which will be volatile sig_atommic_t, or volatile int), and then use the mainline loop to apply this to all the windows. Then the signal handler does not need to walk a linked list which is potentially corrupt for small windows of time.
though he credited it to Miller (who later echoed the same comment).
Given the hint about sig_atomic_t
, I improved the
SIGWINCH
handler for ncurses later that month
(2007-04-21):
+ move most static variables into structures _nc_globals and _nc_prescreen, to simplify storage. + add/use configure script macro CF_SIG_ATOMIC_T, use the corresponding type for data manipulated by signal handlers (prompted by comments in mailing.openbsd.bugs newsgroup).
However, after I released ncurses 5.7 the following year, I found no corresponding improvement in OpenBSD.
Another three years passed before someone revived the topic on an OpenBSD mailing list:
ncurses 5.7 update and define USE_SIGWINCH (2011-04-22)
Nicholas Marriott responded to that, and when I noticed it, pointed out that OpenBSD was the only group which disabled the feature. In his reply he indicated that he had been discussing it with others, and had concluded that it would be better to enable it:
Date: Sat, 23 Apr 2011 17:43:35 +0100 From: Nicholas Marriott <nicholas.marriott@gmail.com> To: Thomas Dickey <dickey@his.com> Subject: Re: ncurses 5.7 update and define USE_SIGWINCH Hi We've been discussing it a bit since as far as we can now see the SIGWINCH handler in ncurses is now safe (it didn't seem to be in the old version we were using). Might be changed yet, personally I think it is better to use the ncurses handler than have a bunch of patches of potentially varying quality to add signal handlers to ports. But we'll see. On Sat, Apr 23, 2011 at 09:33:12AM -0400, Thomas Dickey wrote: > > right - OpenBSD is the only group that I recall which disables the flag.
That said, he committed an update to enable the
SIGWINCH
handler
later that day:
Revision 1.26, Sat Apr 23 22:08:15 2011 UTC by nicm Branch: MAIN CVS Tags: OPENBSD_5_0_BASE, OPENBSD_5_0 Changes since 1.25: +3 -3 lines Diff to previous 1.25 (unified) Enable the SIGWINCH handler in ncurses. Prompted by mail from Mikolaj Kucharski on tech@ and discussion with deraadt@ and millert@. A library installing signal handlers without being asked is seriously wrong but it appears quite a few applications now depend on the ncurses SIGWINCH and it looks to be safe. Safer than the other signal handlers it installs (apparently without request... boke). ok millert
That “without being asked” bears comment:
The signal handlers are established at initialization time, if no handlers are found for the corresponding signals (SIGINT, SIGTERM, SIGTSTP and SIGWINCH):
The source-file (lib_tstp.c
) which implements
the signal handlers dates back to June 1995. If the OpenBSD
developers had concerns about this, they had more than ten
years to prepare their comments.
In ncurses 5.0 (October 1999), I modified the SIGINT/SIGTERM behavior to set a flag in the library which tells it to not use buffered output:
+ modify SIGINT/SIGQUIT handler to set a flag used in _nc_outch() to tell it to use write() rather than putc(), since the latter is not safe in a signal handler according to POSIX. + add/use internal macros _nc_flush() and NC_OUTPUT to hide details of output-file pointer in ncurses library.
in 2011 (shortly after enabling the SIGWINCH handler),
Nicholas Marriott asked me to include a comment written by De
Raadt for lib_tstp.c
:
Date: Wed, 25 May 2011 18:45:41 +0100 From: Nicholas Marriott <nicholas.marriott@gmail.com> To: Thomas Dickey <dickey@radix.net> Subject: ncurses lib_tstp.c comment improvement ... Just a quick one. A couple of people auditing signal handlers in OpenBSD rewrote the comment in lib_tstp.c to have some more specific notes. Don't know if you're interested in taking this too.
One part was useful, mentioning that it used
exit
in one place rather than
_exit
, another part was not (based on a false
premise), and part was harmless (I allowed that part, though
not actually useful).
I made the fix for exit
versus
_exit
and added another fix for a problem which
I noticed (June
2011):
+ improve cleanup() function in lib_tstp.c, using _exit() rather than exit() and checking for SIGTERM rather than SIGQUIT (prompted by comments forwarded by Nicholas Marriott).
In practice, the SIGINT/SIGTERM handlers work well with the 1999 workaround.
SIGTSTP proved to be more difficult.
A bug report in 2012 showed that because the workaround did not (i.e., could not easily) affect the buffered versus non-buffered output, a SIGTSTP could result in memory corruption and a crash.
I solved this problem by changing ncurses to write output using its own buffers (and thereby ensuring that ncurses would do no malloc or free calls as it cleaned up from a signal).
The initial change was small, but led on to other changes which would have justified a new release. However, working toward ncurses 6.0 took precedence, and output buffering was ultimately less important than symbol versioning.
In July 2015, I added an overview of Signal Handlers in the initscr manual page.
OpenBSD curses lacks all of the signal-handling improvements made since 2008.
The main problem to solve in upgrading OpenBSD curses is finding someone to do the work. Marriott mentioned this:
Date: Tue, 12 Feb 2019 04:47:09 -0500 From: Thomas Dickey <dickey@his.com> To: Nicholas Marriott <nicholas.marriott@gmail.com> Cc: Thomas Dickey <dickey@his.com> Subject: Re: hardware tabs and xterm OTpt ... > I haven't updated the database for a while because I need to look at > what changed with ncurses 6 that won't be compatible (OpenBSD is still > using ncurses 5.7 and upgrading is a real pain I haven't had time for). offhand - ncurses still supports the ABI 5 configuration, so upgrading with ABI 5 would get various improvements. 6.1 makes a small number of changes to color- and pair-limits which you could patch for compatibility with applications that get confused by the increased limits (ultimately that patch should go away).
and
Date: Tue, 12 Feb 2019 20:16:17 -0500 From: Thomas Dickey <dickey@his.com> To: Nicholas Marriott <nicholas.marriott@gmail.com> Cc: Thomas Dickey <dickey@his.com> Subject: Re: hardware tabs and xterm OTpt ... > Its not so much the ABI, it's really an OpenBSD problem - the way > ncurses was first imported (before the OpenBSD fork from NetBSD) means > it is spread in several different places around the tree and is very > time consuming to upgrade. But I'll get to it eventually I hope. I see (my to-do list never gets shorter, either).
Agreeing that it is in several places in the source-tree, here is a map:
OpenBSD src ├── bin │ └── (35 entries) ├── distrib │ └── (148 entries) ├── etc │ └── (24 entries) ├── games │ └── (58 entries) ├── gnu │ └── (3941 entries) ├── include │ └── (4 entries) ├── lib │ ├── (skip 239) │ ├── libcurses │ │ ├── base │ │ ├── tinfo │ │ ├── trace │ │ ├── tty │ │ └── widechar │ ├── (skip 15) │ ├── libform │ ├── (skip 26) │ ├── libmenu │ ├── (skip 1) │ ├── libpanel │ └── (skip 19) ├── libexec │ └── (42 entries) ├── regress │ └── (1066 entries) ├── sbin │ └── (85 entries) ├── share │ ├── (skip 45) │ ├── tabset │ ├── termtypes │ └── (skip 4) ├── sys │ └── (533 entries) ├── usr.bin │ ├── (skip 101) │ ├── infocmp │ ├── (skip 128) │ ├── tic │ ├── (skip 4) │ ├── tput │ ├── (skip 2) │ ├── tset │ └── (skip 51) └── usr.sbin └── (224 entries) 6824 directories
upgrading would be simplified by scripting the patching process.
Although OpenBSD developers are slow to upgrade the bundled ncurses, this (like FreeBSD and NetBSD) is a platform that I use for testing portability.
This story starts in October 2000 (before OpenBSD's changes in March 2003):
+ modify parse_format() in lib_tparm.c to ignore precision if it is longer than 10000 (report by Jouko Pynnonen). + rewrote limit checks in lib_mvcur.c using new functions _nc_safe_strcat(), etc. Made other related changes to check lengths used for strcat/strcpy (report by Jouko Pynnonen <jouko@solutions.fi>).
The initial report was on the ncurses mailing list (October 2, 2000), with a followup on Bugtraq (October 9, 2000).
That was shortly before I released ncurses 5.2 (which Miller
incorporated into OpenBSD on the following day). From my private
email, I see some discussion by others suggesting using
strlcpy
as a followup to Pynnonen's report, but none
from an OpenBSD developer. Still, that episode may have been a
factor when Miller modified the OpenBSD curses in March/April
2013 to replace strcpy
, strcat
and
sprintf
by strlcpy
,
strlcat
and snprintf
.
For a while, I made no change regarding that, because I did not frequently install OpenBSD because the BSDs required a primary partition for installing, and it was not unusual for a failed install to require reinstalling everything on a multiboot machine. As for system upgrades, even in 2021 those often fail.
But starting in 2010, I began developing with virtual machines (i.e., allowing frequent installs of machines holding a single operating system). During the first year or so, those included OpenBSD 4.6 (2009), MirBSD 8 and OpenBSD 4.9 (2011).
Initially it was sufficient to update the port. Later, in
2011, I began collecting build-logs systematically. I noticed
that MirBSD and OpenBSD would warn when linking programs using
strcpy
, strcat
and
sprintf
. I have addressed this more generally
here,
but because ncurses provides libraries, it was more of a nuisance
than with lynx, vile or xterm.
The point of the warning is to promote the use of analogous
functions strlcpy
, strlcat
and
snprintf
. By themselves, those functions cannot
ensure that a program is more robust. They are not magic
bullets which can replace the need for analysis. But those
linker warnings tend to promote a cargo cult style of
development, and as such are counter productive.
Keeping in mind portability, although snprintf
was standardized in
1997 (i.e., Issue 5 according to
The Open Group), it was not universally available until a few
years had passed. The OpenBSD manual page states that
snprintf
and vsnprintf
first appeared
in 4.4BSD. The CSRG SCCS credits the implementation to Chris
Torek, with a 1993 copyright added by Keith Bostic. SunOS 4,
Solaris 2.5 and other platforms on which I developed during the
1990s lacked this function.
Miller and De Raadt's
1999 Usenix paper outlines the use of strlcpy
and strlcat
. It mentions ncurses vs strncpy,
referring to an improvement suggested by
Miller.
Unlike snprintf
, the strlcpy
and
strlcat
functions have not yet been standardized.
They are not listed in The Open Group's system
interfaces.
One of the answers in Why are strlcpy and strlcat considered insecure? mentions that applications are expected to check the return value, to see if the data was truncated. Miller's conversion of ncurses added no checks of that sort. Aside from eliminating the linker warnings (added a few months later), there is no improvement.
Lacking a better (standard, portable) solution, ncurses checks lengths for string allocation, copying, and concatenation.
However, I would like to eliminate the warnings as well (since they are distracting and interfere with looking for genuine problems). In February 2012, I made this change:
+ add --enable-string-hacks option to control whether strlcat and strlcpy may be used. The same issue applies to OpenBSD's warnings about snprintf, noting that this function is weakly standardized. + add configure checks for strlcat, strlcpy and snprintf, to help reduce bogus warnings with OpenBSD builds.
I implemented this by defining macros which would expand to
strlcat
, etc., or their more well-established
counterparts. The macros are defined in
nc_string.h
, and for the most part, conversion
was simple. In one case (my rewrite of the screen-dump and
restore feature in 2015) that required passing
the buffer sizes via function parameter. But usually the length
was readily available because I was already using it in limit
checks.
Here are some counts of the “.c
”
files in OpenBSD curses:
255 total files 41 files using string-hack 70 snprintf 33 strlcat 53 strlcpy 1 vsnprintf
Here are counts of my macros in current ncurses source (June 2021). This includes the test-directory and ncurses/trace, which are absent from OpenBSD:
367 total files 85 files using string-hack 175 _nc_SLIMIT 184 _nc_SPRINTF 62 _nc_STRCAT 98 _nc_STRCPY 2 _nc_STRNCAT 15 _nc_STRNCPY 1 vsnprintf
OpenBSD has a libtool look-alike. Its manual page says
libtool is supposed to be a drop-in replacement for the eponymous GNU project. The following differences in behaviour with GNU Libtool are intentional:
and goes on to list a few differences which do not apply to ncurses. But it fails to build ncurses anyway. Install the port for GNU libtool, which works.
Until OpenBSD 5, locale support was nonexistent. Beginning with OpenBSD 5, there is partial support for locales.
Heads up! OpenBSD now supports multi-byte characters! (July 2010):
On July 27th, Stefan Sperling (stsp@) added support for the multi-byte characters in the OpenBSD libc. Thanks to the work of the people involved in its development, the OpenBSD C library now supports the Unicode character encoding scheme UTF-8.
referring to this:
Replace the single-byte placeholders for the multi-byte/wide-character conversion interfaces of libc (mbrtowc(3) and friends) with new implementations that internally call an API based on NetBSD's citrus. This allows us to support locales with multi-byte character encodings. Provide two implementations of the citrus-based API: one based on the old single-byte placeholders for use with our existing single-byte character locales (C, ISO8859-*, KOI8, CP1251, etc.), and one that provides support for UTF-8 encoded characters (code based on FreeBSD's implementation). Install the en_US.UTF-8 ctype locale support file, and allow the UTF-8 ctype locale to be enabled via setlocale(3) (export LC_CTYPE='en_US.UTF-8'). A lot of programs, especially from ports, will now start using UTF-8 if the UTF-8 locale is enabled. Use at your own risk, and please report any breakage. Note that ncurses-based programs cannot display UTF-8 right now, this is being worked on. To prevent install media growth, add vfprintf(3) and mbrtowc(3) to libstubs. The mbrtowc stub was copied unchanged from its old single-byte placeholder. vfprintf.c doesn't need to be copied, just put in .PATH (hint by fgsch@).
Shortly after, ncurses was updated (August 2010):
This builds all the libraries with the widechar code and also links them to "w" versions (libncursesw, libformw, etc). Some OSs only put the widechar stuff into libncursesw and not libncurses - I don't much like knobs in the form of library names but if opinion is that we should go that way then I can change it.
That “Some OSs” is misleading: most use the configuration as I designed and documented it in May 2000. OpenBSD deleted the relevant documentation in their copy. The commit-message
Remove obsolete tbl suffix from ncurses man pages, no objections from millert.
does not correspond to the actual change (which replaced the ncurses 4.1 manual page with the ncurses 5.7 manual page and deleted portions of it).
Others find this confusing, requiring special handling:
OpenBSD 6.9 ncursesw header detection with FIND_PACKAGE(Curses) in May 2021:
On OpenBSD 6.9 with CMake installed via pkg_add (pkg_info -Q reports that cmake-3.19.4p0v0 is installed), running FIND_PACKAGE(Curses) in CMake with wide character support required fails with the message: "Could NOT find Curses (missing: CURSES_INCLUDE_PATH)".
From what I see, the cause is that OpenBSD's packaging of ncurses uses ncurses.h for both the wide and standard character versions and does not have ncursesw/ncurses.h or ncursesw.h installed. There is only /usr/include/ncurses.h and /usr/include/curses.h.
configure: Fix curses probe for older ncurses, discussion on qemu-devel in November 2017:
On 11/27/2017 7:02 AM, Peter Maydell wrote: > On 26 November 2017 at 22:13, Brad Smith <brad@comstyle.com> wrote: >> Fix the curses probe with older ncurses (.e.g. 5.7, as used by OpenBSD). >> >> ncurses 5.7 requires _XOPEN_SOURCE_EXTENDED to be defined for WACS_* constants. > ncurses 5.7 was released in 2008 and is now 9 years old. Why > is OpenBSD still using such an ancient version? Someone has to put the time and effort into updating it.
Expose curses library name and version on Python level, in October 2017:
The name and the version of the curses library are needed for work around bugs in old versions or skip tests on platforms that provide broken curses library (like OpenBSD providing ncurses 5.7).
It took a while before updating xterm, as noted in
Author: schwarze <schwarze@openbsd.org> Date: Tue Mar 8 17:26:30 2016 +0000 Use UTF-8 mode by default because it is safer and more useful even for people always running with a C/POSIX locale(1). OK matthieu@ naddy@ martijn@
However, that is only a small part. Consider this:
[prev in list] [next in list] [prev in thread] [next in thread] List: openbsd-bugs Subject: Re: Locale not supported by C library. From: Daniele Bonini <my25mb () aol ! com> Date: 2020-05-05 3:45:40 Message-ID: 20200505054540.05e8872a () me ! windows ! com I want to thank again everyone for the time spent in reply to me. I already adopted a new OS for my purpose that is to write chinese characters by terminal into the file system. Daniele Bonini Project Owner and Author http://opengallery.media On Fri, 1 May 2020 19:29:37 +0200 Martijn van Duren <openbsd+bugs@list.imperialat.at> wrote: > On 5/1/20 7:13 PM, Daniele Bonini wrote: > > Hello, > > > > I need to work on unicode characters, expecially Chinese characters. > > > > So I set this in my .profile: > > > > export LC_CTYPE=zh_CN.GB18030 > > > > But launching Terminal in Xfce4 I get: > > > > (process:47941): xfce4-terminal-WARNING **: 18:51:15.832: Locale not > > supported by C library. > > > > (process:47941): Gtk-WARNING **: 18:51:15.836: Locale not supported > > by C library. > > > > I get the same kind of feedback trying to launch pkg_add. > > > > Please note that Xfce4 with Noto fonts on Thunar is running quite > > smoothly on all characters. > > > > If it is not a bug, any help could be much appreciated. > > > > > > Thnx > > > > Daniele Bonini > > Project Owner and Author > > http://opengallery.media > > > OpenBSD only supports UTF-8. This is intentional and unlikely to > change. Note that UTF-8 also supports all characters in GB18030[0]. > > martijn@ > > [0]https://www.unicode.org/faq/han_cjk.html
By the way, OpenBSD has no iconv port. The iconv program is part of the libiconv port.
Through OpenBSD 6.2, compiling and linking was fairly routine, allowing for spurious linker warnings to promote the use of strlcpy and snprintf. After OpenBSD 6.2, this change was made:
commit 86f55b3d2a934eb190815c5f83a3d683acf7337d
Author: naddy <naddy@openbsd.org>
Date: Fri Sep 14 13:44:18 2018 +0000
Pass -L/usr/lib to the linker in preparation for switching to lld, which
does not have a default search path. ok kettenis@ jsg@
diff --git a/gnu/gcc/gcc/config/i386/openbsd64.h b/gnu/gcc/gcc/config/i386/openbsd64.h
index 24444e505e0..ddef4c13ebf 100644
--- a/gnu/gcc/gcc/config/i386/openbsd64.h
+++ b/gnu/gcc/gcc/config/i386/openbsd64.h
@@ -121,7 +121,8 @@ Boston, MA 02111-1307, USA. */
%{!static:-Bdynamic} \
%{rdynamic:-export-dynamic} \
%{assert*} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so}"
+ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so} \
+ %{!nostdlib:-L/usr/lib}"
#define OBSD_HAS_CORRECT_SPECS
diff --git a/gnu/gcc/gcc/config/i386/openbsdelf.h b/gnu/gcc/gcc/config/i386/openbsdelf.h
index 5832f64cc76..0a475954be6 100644
--- a/gnu/gcc/gcc/config/i386/openbsdelf.h
+++ b/gnu/gcc/gcc/config/i386/openbsdelf.h
@@ -126,6 +126,7 @@ Boston, MA 02110-1301, USA. */
%{!static:-Bdynamic} \
%{rdynamic:-export-dynamic} \
%{assert*} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so}"
+ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so} \
+ %{!nostdlib:-L/usr/lib}"
#define OBSD_HAS_CORRECT_SPECS
The change is faulty, adding the option in the wrong place in the command-line. A user reported that he was unable to compile an up-to-date ncurses with OpenBSD:
Compiling ncurses-6.1 on OpenBSD (12 July 2019)
I reported the problem here:
Compiling ncurses-6.1 on OpenBSD (10 August 2019)
and got no useful response.
That was for OpenBSD 6.3 (released in May 2019). Time passes.
While preparing for ncurses 6.3 in May 2021, I repaired my OpenBSD 6.9 machine using this change:
The appropriate place to make the change would be to the
LIB_SPEC
macro in the
gcc
source-code.
I had noticed the problem first in the 64-bit machine, because
the clang program is (still, as of mid-2021) unreliable for that
architecture. It works more reliably on a 32-bit machine, so the
packagers discarded the /usr/bin/gcc
in favor of
clang.
However the same linker problem exists in the gcc port for the i386 platform, but that uses built-in specs (see source), and on first inspection appears to be less readily repaired. However, gcc provides an option which makes it possible to do this without rebuilding the program:
$ sudo su - # cd /usr/local/bin # egcc -dumpspecs >gcc.specs # vi gcc # cp gcc.specs gcc.specs.orig # vi gcc.specs # chmod 755 gcc # exit
As before, the necessary change moved the
-L/usr/lib
from the field that specifies the
linker path to the field which list
linker options:
--- gcc.specs.orig Sat Jun 12 16:17:19 2021
+++ gcc.specs Sat Jun 12 16:18:21 2021
@@ -50,10 +50,10 @@
%{!shared:crtend%O%s} %{shared:crtendS%O%s}
*link:
-%{!static|static-pie:--eh-frame-hdr} %{!shared:%{!nostdlib:%{!r:%{!e*:-e __start}}}} %{shared:-shared} %{R*} %{static:-Bstatic} %{!static:-Bdynamic} %{rdynamic:-export-dynamic} %{assert*} %{!static:-dynamic-linker /usr/libexec/ld.so} %{!nostdlib:-L/usr/lib}
+%{!static|static-pie:--eh-frame-hdr} %{!shared:%{!nostdlib:%{!r:%{!e*:-e __start}}}} %{shared:-shared} %{R*} %{static:-Bstatic} %{!static:-Bdynamic} %{rdynamic:-export-dynamic} %{assert*} %{!static:-dynamic-linker /usr/libexec/ld.so}
*lib:
-%{pthread:-lpthread%{!shared:%{p|pg:_p}}} %{!shared:-lc%{p:_p}%{!p:%{pg:_p}}}
+ %{!nostdlib:-L/usr/lib} %{pthread:-lpthread%{!shared:%{p|pg:_p}}} %{!shared:-lc%{p:_p}%{!p:%{pg:_p}}}
*link_gomp:
and the gcc
script uses that fix:
#!/bin/sh
exec egcc -specs=/usr/local/bin/gcc.specs "$@"
After repairing the specs-file, the OpenBSD port of gcc still
fails to build ncurses. I chose to set
LD_LIBRARY_PATH
during the build to work around this
problem. That was also needed in one of my OpenBSD 6.7 machines
to allow gmake
to run (the problem with
gmake
appears to be fixed in OpenBSD 6.9).
Finally (for June 2021), I encountered one of the known bugs in lld:
GCC generating incorrect relocation R_386_GOTOFF in .debug-info for x86 (32)
[ELF] Allow R_386_GOTOFF from .debug_info (closed February 4, 2021)
To work around this, I disabled the no-leaks option during build-time for the 32-bit machines.
The lld program for which workarounds are necessary is provided by the LLVM project. Its manual page says:
ld.lld is a drop-in replacement for the GNU BFD and gold linkers. It accepts most of the same command line arguments and linker scripts as GNU linkers.
The LLVM project's documentation says more
LLD is a linker from the LLVM project that is a drop-in replacement for system linkers and runs much faster than them. It also provides features that are useful for toolchain developers.
Like the OpenBSD libtool, the LLVM lld is not a “drop-in replacement” (its developers should consider amending their manual page to include “supposed to be” as done by the OpenBSD developer).
According to these:
the OpenBSD developers chose to use lld to improve performance (rather than, for example, because of licensing disputes). The errata listed in the latter overlooks gcc.
Not all of the changes are necessary. Some of them just happen.
Some of the changes made in OpenBSD are due to developer's errors, e.g., adding/changing whitespace to these files:
After removing Miller's customized terminfo interface, the prototypes for it still remain in the term_entry.h header file:
--- ncurses-5.7/include/term_entry.h 2008-08-16 12:16:03.000000000 -0400
+++ openbsd/include/term_entry.h 2021-06-17 16:06:12.414529281 -0400
@@ -161,6 +161,12 @@
/* trace_xnames.c */
extern NCURSES_EXPORT(void) _nc_trace_xnames (TERMTYPE *);
+#ifdef __OpenBSD__
+/* read_bsd_terminfo.c: terminfo.db reading */
+extern int _nc_read_bsd_terminfo_entry(const char * const, char * const, TERMTYPE *const);
+extern int _nc_read_bsd_terminfo_file(const char * const, TERMTYPE *const);
+#endif /* __OpenBSD__ */
+
#ifdef __cplusplus
}
#endif
Those mechanical changes (via a one-off script)
interfere with the process of importing new versions of ncurses,
because they add a line with CVS keywords for OpenBSD development
but fail to make existing RCS keywords inert. When I have to deal
with sources in this manner, I change (using a script of course)
the $
dollar-signs to
@
signs. In reviewing, my script
uses an option to the diff
program to make it ignore
lines which contain RCS/CVS keywords. That option does not work
with OpenBSD:
makepatch -diff 'diff -u -I\\\$\\\(Revision\\\|Date\\\|Header\\\|Id\\\):.*\\\$' $1 $2 >$tmp
In the diffstat above, the difference of ncurses_cfg.h versus ncurses 5.7 is greater than one might suppose. While that is an internal file, used when building ncurses and its associated libraries, it is a generated file. When something is amiss with generated code, one might expect a fix to the generating script.
The short explanation is that OpenBSD developers edited the generated file and during upgrade to ncurses 5.2 and ncurses 5.7 manually added lines to more or less correspond with the upgraded system. You can see this in the CVS history for ncurses_cfg.h — some is uninteresting and can be scripted as I did during review:
#!/bin/sh
# $Id: openbsd-ncu57,v 1.4 2021/06/23 01:09:57 tom Exp $
# Prep ncurses 5.7 for comparison with the OpenBSD version which is transformed
# by openbsd2ncu
rm -rf /tmp/ncurses-5.7
copy /usr/build/ncurses/ncurses-5.7 /tmp/
cd /tmp/ncurses-5.7
unarchive || exit 1
copy -v /usr/build/ncurses/terminfo/RCS misc/
co -fv6_0_20170401 misc/terminfo.src || exit 1
rm -f misc/RCS
rm -rf ./Ada95
cfg-shared \
--with-terminfo-dirs=/usr/share/terminfo:/usr/local/share/terminfo \
--disable-hard-tabs \
--enable-getcap \
--enable-bsdpad \
--enable-termcap \
--enable-widec \
|| exit 1
make sources || exit 1
# OpenBSD developers edit the generated file and do not regen it when doing
# upgrades. This script reflects those edits.
sed -i.bak \
-E \
-e '/TYPEOF_CHTYPE/s,int,long,' \
-e '/USE_TERMCAP/d' \
-e '/HAVE_LIB(FORM|MENU|PANEL)/s,^(.*)$,/* \1 */,' \
-e 's/TERMPATH.*/PURE_TERMINFO 0/' \
-e '/SYSTEM_NAME/s,[0-9.]+,,' \
include/ncurses_cfg.h
diff -u include/ncurses_cfg.h.bak include/ncurses_cfg.h
rm -f include/ncurses_cfg.h.bak
rm -rf ./doc ./c++ ./test
rm -f */Makefile
rm -f */llib-*
rm -f */*.in
rm -f */Caps.*
rm -f */modules */headers */programs
rm -f */*.def */*.ref
rm -f */*.head */*.tail */*.hin
rm -f */*.cmd */*.sed
rm -f include/*.sh include/*.awk
rm -f man/*.sh
rm -f */clear* */tput.* */tset.1
find . -name 'README*' -delete
rm -f * 2>/dev/null
rm-dirs
ls -l
Even with those deletions, the order differs. I filtered that
manually for this comparison using
“sort -u
” (to eliminate
duplicates). After factoring that out, here is what is left:
--- ncurses-5.7/include/ncurses_cfg.h Sun Jun 20 07:04:34 2021
+++ openbsd/include/ncurses_cfg.h Sun Jun 20 07:02:34 2021
@@ -31,7 +31,7 @@
* Author: Thomas E. Dickey <dickey@clark.net> 1997 *
****************************************************************************/
/*
- * $Id: ncurses_cfg.hin,v 1.7 2005/01/02 01:26:58 tom Exp $
+ * $Id: ncurses_cfg.h,v 1.27 2011/09/21 06:26:51 nicm Exp $
*
* This is a template-file used to generate the "ncurses_cfg.h" file.
*
@@ -50,15 +50,16 @@
#define CC_HAS_PROTOS 1
#define CPP_HAS_STATIC_CAST 1
#define ETIP_NEEDS_MATH_H 1
-#define GCC_NORETURN __attribute__((noreturn))
+#define GCC_NORETURN __attribute__((__noreturn__))
#define GCC_PRINTF 1
#define GCC_SCANF 1
-#define GCC_UNUSED __attribute__((unused))
+#define GCC_UNUSED __attribute__((__unused__))
#define HAVE_BIG_CORE 1
#define HAVE_BSD_CGETENT 1
#define HAVE_BTOWC 1
#define HAVE_CURSES_VERSION 1
#define HAVE_DIRENT_H 1
+#define HAVE_ERRNO 1
#define HAVE_FCNTL_H 1
#define HAVE_FORM_H 1
#define HAVE_FSEEKO 1
The change for the parameter of __attribute__
appears unnecessary, because clang's
documentation says that it accepts the gcc
syntax, while gcc's documentation does not use
this alternate spelling:
Please see GCC documentation about format attribute to find details about attribute syntax.
But the change was made well before there was a clang program to consider (December 2000):
Reading the gcc source code provides an
answer in
gcc/ONEWS
:
Numerous enhancements were made to the __attribute__ facility including more attributes and more places that support it. We now support the "packed", "nocommon", "noreturn", "volatile", "const", "unused", "transparent_union", "constructor", "destructor", "mode", "section", "align", "format", "weak", and "alias" attributes. Each of these names may also be specified with added underscores, e.g., "__packed__". __attribute__ may now be applied to parameter definitions, function definitions, and structure, enum, and union definitions.
Given that clue, it is possible to find this in 6.39 Attribute Syntax:
You may optionally specify attribute names with ‘__’ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name
__noreturn__
instead ofnoreturn
.
The change history makes it apparent that there is no distinction between the documented and alternate spelling, i.e., changes between the forms are due to preferences by some developers rather than because there is a difference in behavior.
As part of the buffer-overflow fixes in 2000, I made this change:
+ add configure option --disable-root-environ, which tells ncurses to disregard $TERMINFO and similar environment variables if the current user is root, or running setuid/setgid (based on discussion with several people).
OpenBSD does not use that feature. Instead, it accepts those environment variables if the user is root but not running setuid/setgid, by
A more appropriate change would have been to the C function
_nc_env_access
.
That already made the check for setuid/setgid, before Miller's changes.#ifndef USE_ROOT_ENVIRON
/*
* Returns true if we allow application to use environment variables that are
* used for searching lists of directories, etc.
*/
int
_nc_env_access(void)
{
#if HAVE_ISSETUGID
if (issetugid())
return FALSE;
#elif HAVE_GETEUID && HAVE_GETEGID
if (getuid() != geteuid()
|| getgid() != getegid())
return FALSE;
#endif
return getuid() != 0; /* ...finally, disallow root */
}
#endif
The manual page for issetugid
bears comment:
.\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved
Lacking better information, it appears to have been implemented in 1996, documented initially by copy/paste from the getuid manual page. It has not been standardized; however, it is available on more than one platform (OpenBSD, FreeBSD, NetBSD, Solaris, and other BSDs).
That 1993 copyright date also appears in the Solaris manpage, where it is less plausible. Solaris 9 (2002), which is the first version of Solaris with this function, does not provide that detail.
I added ncurses_dll.h
in December 2000, to simplify
porting to Windows-based environments (such as Cygwin, DJGPP or
MinGW).
Although <curses.h>
includes other files,
in this case the OpenBSD developer disagreed, using copy/paste to
eliminate the file. For example:
--- ncurses-5.7/include/curses.h 2021-06-23 06:21:11.000000000 -0400
+++ openbsd/include/curses.h 2021-06-23 06:17:48.000000000 -0400
@@ -55,17 +55,25 @@
#undef NCURSES_VERSION
#define NCURSES_VERSION "5.7"
+#if !defined(NCURSES_IMPEXP)
+# define NCURSES_IMPEXP /* nothing */
+#endif
+#if !defined(NCURSES_API)
+# define NCURSES_API /* nothing */
+#endif
+#if !defined(NCURSES_EXPORT)
+# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API
+#endif
+#if !defined(NCURSES_EXPORT_VAR)
+# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type
+#endif
+
/*
* Identify the mouse encoding version.
*/
#define NCURSES_MOUSE_VERSION 1
/*
- * Definitions to facilitate DLL's.
- */
-#include <ncurses_dll.h>
-
-/*
* User-definable tweak to disable the include of <stdbool.h>.
*/
#ifndef NCURSES_ENABLE_STDBOOL_H
As a result, the content of <ncurses_dll.h>
is inline in 4 places:
No rationale was given by the developer. The check-in comment in each case was
Update to ncurses-5.2-20010114
According to a comment in the OpenBSD changes for
terminfo.src
,
# # OpenBSD local changes: # - add rxvt-unicode and rxvt-unicode-256color # - xterm-r5, xterm-r6, xterm-xf86-v32, xterm+kbs change kbs=^H to kbs=\177 # - screen change kbs=^H to kbs=\177
most of the change adds the terminal description for rxvt-unicode (see FAQ: Where is rxvt-unicode?).
While making updates to the terminal database, I use a script which compare all of the items (both canonical names and aliases) between the terminfo.src text file and the compiled/installed terminal database. That script reports
and using tic -I1x terminfo.src
, there are
That is, updating the terminal database is usually beneficial,
but we have to keep things in perspective. OpenBSD happened to
avoid the problems with st 0.7
because no one
upgraded the terminal database, but without upgrading the ncurses
library and utilities, OpenBSD cannot use a current terminal
database (i.e., ncurses 6.2 or later). The ncurses 6.2 release
notes mention this:
Both of these issues dated from the original implementation of user-defined capabilities. Fixing them does not change the terminal database, but a older tic without the fixes will not be able to handle terminfo sources which rely upon those fixes. Starting in June 2019, the download link for the terminfo source file was capped at that date. The development sources have an up-to-date copy of the file, for people with a legitimate need for it.
The 6.2 release is long past (more than a year at this writing), so the capped download link is moot.
Changes to support rxvt-unicode and st are not new:
but since both are still under development, someone will want an up-to-date terminal description.
Besides ports, OpenBSD has its own (self-inflicted)
problems with terminal descriptions. OpenBSD's console for
AMD/Intel hardware can display ANSI colors (and presumably other
hardware cannot), but OpenBSD sets
TERM
to “vt220” (which
tells applications that it has no colors). Some people notice,
and some propose improvements:
(At least they did not call it “xterm”).
The OpenBSD tput and its manual page are not derived from ncurses. The OpenBSD tput is derived from the 4.4BSD version began by Keith Bostic, as outlined in the ncurses tput manual.
There are differences, mainly that the OpenBSD variant is less capable:
It gets confused by string parameters that are entirely digits.
It tries to process terminfo names first, then termcap names, but doesn't know about cancels. Allowing for termcap names is not a special feature; ncurses' tput has also handled termcap names for a long time (1999/01/23), or about six months longer than OpenBSD.
There is another issue with the program, which some might regard as an improvement:
In reviewing the differences between OpenBSD's ncurses-related utilities, I noticed the examples in the manual page:
EXAMPLES tput cl cm 5 10 clear the screen and goto line 5 column 10 tput cm 6 11 DC 6 goto line 6 column 11 and delete 6 characters
Those examples rely upon the tput program being able to determine the number of parameters for each capability. The AT&T tput cannot do this.
I took a look at the OpenBSD source-code, and noticed some familiar code (part of ncurses). The commit-comment did not mention that Miller copied source-code from ncurses:
Revision 1.8 / (download) - annotate - [select for diffs], Tue Jun 29 19:39:40 1999 UTC (22 years, 3 months ago) by millert Branch: MAIN Changes since 1.7: +251 -127 lines Diff to previous 1.7 (unified) Heavily modified to support both terminfo and termcap attributes. Now links with -lcurses (ncurses), not -locurses. TODO: set tabs/margins for init/reset pseudo-attributes.
For reference,
here is a link to the version of
lib_tparm.c
which Miller used. In later
versions, those cases would be split up, since that is what
the indent program does.
Also, the function has been improved in various ways (see
September 2021).
The ncurses source-code was used to solve a problem: transforming tput from a termcap-program to a terminfo-program.
The corresponding termcap-code and examples in the manual page came from NetBSD, in January 1994:
Revision 1.3 / (download) - annotate - [select for diffs], Mon Jan 24 23:54:57 1994 UTC (27 years, 8 months ago) by cgd Branch: MAIN Changes since 1.2: +119 -10 lines Diff to previous 1.2 (colored) DTRT with termcap string arguments. from Christos-Zoulas@deshaw.com. needs man page update.
The CSRG SCCS has the source-code change, but not the manual-page update:
^As 00099/00018/00101 ^Ad D 8.2 94/03/19 11:27:54 bostic 11 10 ^Ac tput patch to support 'tput cm 10 20' ^Ac From: Christos-Zoulas@deshaw.com (Christos Zoulas)
tparm
able to cope with variable-length parameter
lists. That started with my changes in 1995:
(most of the changes between ncurses 1.8.9 and 1.9 were my work, though unattributed as noted in the ncurses licensing discussion). In this instance, I recognize my phrasing in the source-code comment which differs from Eric Raymond's style:* rewrote varargs parsing in lib_tparm.c (to avoid referencing memory that may be out of bounds on the stack) -- Purify found this.
/* * Find the highest parameter-number referred to in the format string. * Use this value to limit the number of arguments copied from the * variable-length argument list. */
Having that function embedded in the tput program is counter-productive. On the other hand, there might be a user of the feature. Taking that into account, I implemented this while preparing for ncurses 6.3 in September 2021.
Taking all of the above in account, this utility should simply be replaced (see ncurses 6.1 release notes for additional reasons why the OpenBSD utility is obsolete).
OpenBSD tset is more complicated. Both it and ncurses began with the same tset.c from 4.4BSD, however most of the followup development has been in ncurses. The OpenBSD variant has been based on ncurses since November 1998, with some local changes.
While the program is derived from ncurses, the tset manual page is not.
This utility should simply be replaced (see ncurses 6.1 release notes).
OpenBSD 6.9 lacks these utilities:
tabs, a POSIX utility, part of ncurses since 2008, shortly after the ncurses 5.7 release.
toe, an ncurses utility since ncurses 1.9.7 (November 1995).
For whatever reason, the OpenBSD developers have not kept up with maintenance. Upgrading ncurses (with ABI 5) is straightforward, because no binary incompatibilities were introduced during the past thirteen years (November 2008 to October 2021). There is no need to rebuild the whole system, only the out-of-date libraries and their associated utilities.
I created scripts to demonstrate this. Some are for test-builds (and not of general interest), but these are useful:
ncu2openbsd copies from an ncurses
tarball or source-tree into the OpenBSD /usr/src
tree. I have tested this with each release of ncurses
starting with 5.7, as well as the development (prerelease of
6.3).
install-ncu2openbsd executes the ncu2openbsd script, compiles the relevant source-directories and installs the result. I have tested this with the 32-bit (i386) and 64-bit (amd64) OpenBSD 6.9 releases.
The first script is lengthy (1286 lines), and you can read it here. The other script is shorter, and most developers will find it easy to understand how the longer script is used:
#!/bin/sh
# $Id: install-ncu2openbsd,v 1.1 2021/09/27 23:05:12 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2021 by Thomas E. Dickey
#
# All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# https://invisible-island.net/ncurses/ncurses-openbsd.html
#
# use ncu2openbsd to prepare/build ncurses to upgrade it on OpenBSD.
# This relies upon the fixes noted in the "Broken linker" section.
failed() {
echo "? $*" >&2
exit 1
}
need_file() {
[ -f "$1" ] || failed "no such file: $1"
}
need_dir() {
[ -d "$1" ] || failed "no such directory: $1"
}
push_dir() {
save_dir=$PWD
my_dir=$1
cd $my_dir
}
pop_dir() {
cd $save_dir
}
make_install() {
if [ $DOIT = "eval" ]
then
$DOIT sudo make $OPTN install "$@"
else
$DOIT make $OPTN install "$@"
fi
}
install_lib() {
push_dir /usr/src/lib/$1
need_dir $my_dir
need_file $my_dir/$1.a
make_install includes
ls -ld $my_dir/$1*.*
pop_dir
}
install_bin() {
push_dir /usr/src/usr.bin/$1
need_dir $my_dir
need_file $my_dir/$1
make_install
ls -ld $my_dir/$1
pop_dir
}
install_db() {
push_dir /usr/src/share/termtypes
need_dir $my_dir/terminfo
need_file $my_dir/termcap
make_install
ls -ld $my_dir/*
pop_dir
}
DOIT=echo
OPTN=
OPTV=-v
args=`getopt nvx $*`
if [ $? -ne 0 ]
then
echo 'Usage: ...'
exit 2
fi
set -- $args
while [ $# -ne 0 ]
do
case "$1" in
-n)
OPTN="$1"; shift;;
-v)
OPTV="$1"; shift;;
-x)
DOIT=eval; shift;;
--)
shift; break;;
esac
done
# run this from an ncurses source-tree
need_file dist.mk
need_file NEWS
if [ ! -f Makefile ]
then
ncu2openbsd -r $OPTV || failed "cannot build here"
ncu2openbsd -x $OPTV || failed "cannot build here"
fi
install_lib libcurses
install_lib libform
install_lib libmenu
install_lib libpanel
install_bin tic
install_bin infocmp
install_bin tabs
install_bin toe
install_bin tput
install_bin tset
install_db
For non-developers, here are logs from running the script: