12

OS X 10.6.3 broke ncurses

As I was working on my Seitunes project, I noticed something strange: the arrows didn’t quite work any more. Instead of their proper action (up & down to change volume, right & left to change song), they all quit the program and printed -respectively- “OA”, “OB”, “OC” and “OD” on the stdout.

I tried to go back to a working state by progressively deleting new features I was implementing, until I had exactly the same code as the (known working!) 0.5 version, but it was still quitting. gdb told me it wasn’t a crash (“Program exited normally”).

After some testing, I noticed Seitunes worked on my laptop, but not on my MacBook Pro. The only difference between them being that my laptop was still in OS X 10.6.2, while my mbp has upgraded to 10.6.3.

After a bit of digging into curses functions, I started to suspect keypad(WINDOW *, BOOL) to not work properly after the update. keypad() is supposed to dictate whether getch() should interpret an arrow as one non-ASCII value (with the boolean argument set to TRUE) or a set of ASCII values beginning by the escape char, a.k.a. 27 (FALSE). I explicitly call keypad(stdscr, TRUE) in Seitunes, but the FALSE state would perfectly explain the quit-then-print-two-chars behaviour I had was having: I use the escape character to quit Seitunes.

I wrote two very simple pieces of code -one for keypad true, one for keypad false- that plainly outputs the value returned by getch(). They look like:

#include <curses.h>

int main( int argc, char** argv )
{
	int key;
	initscr();
	cbreak();
	noecho();
	nonl();
	intrflush(stdscr, FALSE);
	keypad(stdscr, TRUE);
	printw("getch() should produce only one value when hitting an arrow.\n");
	while ( (key = getch() ) != 'q' ) {
		printw("You entered key %d\n", key);	
	}
	endwin();
	return 0;
}

Code and makefile available here (testCurses.zip) if you want to give it a try.

Under both OS X 10.6.2 and Linux Mint 6 “Felicia” (based on Ubuntu 8.10), these programs behave as they’re supposed to: when keypad is TRUE, an arrow is shown as a single value; when FALSE, an arrow becomes a set of values.

Under OS X 10.6.3, these two programs behave the same way. Both output several values for an arrow.

I filed a bug report to Apple (vintage interface by the way!).

While this bug is present, we’ll have to manually parse the ASCII values for the arrows, which are mapped as follows:

Up	27 79 65	('escape' 'O' 'A')
Down	27 79 66	('escape' 'O' 'B')
Right	27 79 67	('escape' 'O' 'C')
Left	27 79 68	('escape' 'O' 'D')

Edit: these values assume OS X 10.6.3 and keypad(stdscr, TRUE), a.k.a. when the bug is present.

If you want to use keypad(stdscr, FALSE) in 10.6.3, the arrows are mapped as:

Up	27 91 65	('escape' '[' 'A')
Down	27 91 66	('escape' '[' 'B')
Right	27 91 67	('escape' '[' 'C')
Left	27 91 68	('escape' '[' 'D')

Update, March 1st: Apple answered to my bugreport (ID #7812788). They told me it was a known issue (duplicate of bug #7812932) currently being investigated by engineering.

12 Responses

  • April 7, 2010 at 9:25 am

    A temporary fix is to copy
    /usr/lib/libncurses.5.4.dylib
    /usr/lib/libncurses.5.dylib
    From a 10.6.2 system to a 10.6.3 system.

    • April 7, 2010 at 9:48 am

      Also, running sudo update_dyld_shared_cache after replacing the libraries may be a good idea.

    • Florent
      April 9, 2010 at 7:18 pm

      Hi!

      Thanks for the comment: this solution does work.

      However, I’m not sure what the side effects could be. If Apple brought some more changes to the code base, replacing ncurses libraries with older ones might trigger some other errors, couldn’t it?

    • Severin
      May 3, 2010 at 10:59 am

      Does anyone have the 10.6.2 version of the library and could send it to me?

  • April 20, 2010 at 9:19 am

    Thanks for this – I’m the author of bpython (a fancy Python shell that uses curses) and we’ve had a bunch of people complaining on the mailing list about the problem, so glad to know it’s not my fault ! I’ll use this post as a reference in the bug report.

    Thanks again.

  • April 28, 2010 at 2:09 am

    […] This post was mentioned on Twitter by Vinícius Baggio. Vinícius Baggio said: Descobri 2 coisas: parece que o ncurses do 10.6.3 tá zuado (http://bit.ly/cnmn3T) e que eu posso usar hjkl pra mover o cursor. #win […]

  • May 3, 2010 at 11:51 pm

    […] response to my blog post about the issue affecting arrows under OS X 10.6.3, Jonathan Groll pointed out that copying the ncurses libraries from an old 10.6.2 install would fix […]

  • Gapato
    August 18, 2010 at 12:48 pm

    Do you know if this has been fixed in 10.6.4 ?

    • Florent
      August 26, 2010 at 7:03 am

      I’m not really sure. It seems to work in my computer under 10.6.4, but it might be because of the fiddling around I did to make it work in 10.6.3.

      I didn’t receive any new answer from Apple since my bug report has been closed as duplicate of bug #7812932. Apparently you can contact devbugs@apple.com with this bug number to ask them if it’s been resolved or not.

  • July 5, 2011 at 4:14 pm

    […] answer on SO links to a blog entry that describes some other investigations into the problem. One reported workaround is to copy the […]

Leave a Reply

2014 — Upon my shoulder

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.