Fixing xterm-256color with NetBSD

Update: the patch made it into NetBSD 6.1, so if you can upgrade, this fixes the problem.

I am mostly writing this article because I could not really find anything about this problem, despite the fact that it should occur somewhat commonly nowadays.

If you have ever logged into a NetBSD machine using xterm-256color as value for your TERM-variable (this is the default for Mac OS X's, for example), you may have noticed that any program which tries to use colors in the terminal produces garbage among its normal output, essentially rendering every colored terminal application useless.

Things to try this with are vim, emacs, screen and tmux. Depending on your configuration, starting them up is often enough to see that something is wrong, but for extra fun try M-x list-colors-display in emacs.

emacs displaying a world devoid of any colors, corrupted and bland :(


A workaround is fairly easy: set your TERM variable to xterm instead of xterm-256color. You can, for example, do this ad hoc by typing export TERM=xterm, or instruct your terminal emulator to set TERM accordingly on startup, or employ some shell startup script logic. However this is not only kludgy, but of course also disables the use of 256 color capabilities, which at least for emacs would be quite a nice thing to have.


The actual reason is not any incompatibility, nor any problem in NetBSD's terminfo entries, but in fact a bug in NetBSD's libterminfo. The full bug report is here, but the short version is that conditionals in terminfo are not correctly handled on NetBSD. While those are pretty rare, which is probably why this bug has gone unnoticed for so long, they are used in the color escape codes for xterm-like emulators with support for 256 colors, making the problem immediately visible in those.

I included a patch in the aforementioned bug report, so hopefully this will be fixed in one of the next releases. If you don't want to wait until then, you may apply the patch yourself.

And if you are really lazy, you may also download the patched sources to just libterminfo and compile and install them like this:

$ cp /usr/bin/tic .
$ make
$ sudo make install

The first step is needed because the build system somehow wants tic (the terminfo compiler) in the same directory when building like this.

(Keep in mind that I took the libterminfo-sources from NetBSD 6.0-rc2, which may or may not be a good version for you. I also don't know if or how much of the NetBSD sources in /usr/src you actually need to have for the compilation to work.)

Once it is installed, color codes with xterm-256color should work right away!

a happier emacs in a shiny 256 color world.


Anonymous said...

Thank you for posting this. I hope it gets fixed in an upcoming patch/release.

Building the patched sources is not trivial. I have started with a fresh 6.0.1 system, and unpacked src.tgz and sharesrc.tgz into /usr/src, but te build still fails.:

# compile libterminfo/termcap.o
gcc -O2 -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wno-sign-compare -Wno-traditional -Wa,--fatal-warnings -Wreturn-type -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wextra -Wno-unused-parameter -Wno-sign-compare -Wsign-compare -Wformat=2 -Werror -I/usr/local/terminfo/libterminfo -I/usr/local/terminfo/libterminfo -c termcap.c -o termcap.o
cc1: warnings being treated as errors
termcap.c: In function 'tgetflag':
termcap.c:87:2: error: implicit declaration of function '_t_flaghash'
termcap.c: In function 'tgetnum':
termcap.c:112:2: error: implicit declaration of function '_t_numhash'
termcap.c: In function 'tgetstr':
termcap.c:145:2: error: implicit declaration of function '_t_strhash'
*** Error code 1

make: stopped in /usr/local/terminfo/libterminfo

I think I'll live with it for now.


julien said...

dgl: I opened a PR and sent the patch, and there's a good chance it will make it in soon:

I don't know about you issue with compiling, but I will look into it when I'm home.