[uClibc] (mconf SEGV) cols/COLS and rows/LINES inconsistency

ikaruga at cyberspace.org ikaruga at cyberspace.org
Mon Sep 15 15:16:32 UTC 2003


  (using uClibc source from uClibc-20030910.tar.bz2 and libncurses-5.3)

  The mconf.c uses global variables COLS and ROWS  from  libncurses, and  values
obtained by TIOCGWINSZ ioctl independently. They can get unsynchronized, example
  libncurses is configured to not detect number of  terminal  rows  and  columns
via ioctl (disable-ext-funcs). mconf is started on a 160x64 characters terminal;
init_wsize at mconf.c detects 160x64 characters terminal by a TIOCGWINSZ ioctl  and
saves result as (cols, rows). initscr at lib_initscr.c (libncurses)  loads  "linux"
terminfo sees it has (0, 0) default, then checks LINES  and  COLUMNS  env  vars,
doesn't find them and finally defaults to 80x24  characters  keeping  result  as
(COLS, LINES) global vars.
  Each of dialog_checklist at checklist.c, dialog_inputbox at inputbox.c,
dialog_menu at menubox.c, dialog_msgbox at msgbox.c, dialog_textbox at textbox.c,
dialog_yesno at yesno.c has the code:

  x = (COLS - width) / 2;       /* x = (80 - 155) / 2 = -37 */
  y = (LINES - height) / 2;     /* y = (24 - 60) / 2 = -18 */

  dialog = newwin (height, width, y, x);
  keypad (dialog, TRUE);

  newwin at lib_newwin.c returns NULL if any of its argument is less than 0,  mconf
accepts it without check and causes SEGV.
  Please have a look at the patch that changes mconf.c to  use  COLS  and  LINES
variables only. It also removes SIGWINCH handler in favour of  libncurses'  one,
because it caused the same trouble.

Thank You, and keep up with Your great work.
-------------- next part --------------
103d102
< static int rows, cols;
121,157d119
< static void init_wsize(void)
< {
< 	struct winsize ws;
< 	char *env;
< 
< 	if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
< 		rows = 24;
< 		cols = 80;
< 	} else {
< 		rows = ws.ws_row;
< 		cols = ws.ws_col;
< 		if (!rows) {
< 			env = getenv("LINES");
< 			if (env)
< 				rows = atoi(env);
< 			if (!rows)
< 				rows = 24;
< 		}
< 		if (!cols) {
< 			env = getenv("COLUMNS");
< 			if (env)
< 				cols = atoi(env);
< 			if (!cols)
< 				cols = 80;
< 		}
< 	}
< 
< 	if (rows < 19 || cols < 80) {
< 		fprintf(stderr, "Your display is too small to run Menuconfig!\n");
< 		fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
< 		exit(1);
< 	}
< 
< 	rows -= 4;
< 	cols -= 5;
< }
< 
391c353
< 				menu_instructions, rows, cols, rows - 10,
---
> 				menu_instructions, LINES - 4, COLS - 5, LINES - 10,
486c448
< 	show_textbox(title, text, rows, cols);
---
> 	show_textbox(title, text, LINES - 4, COLS - 5);
635,658d596
< static void winch_handler(int sig)
< {
< 	struct winsize ws;
< 
< 	if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
< 		rows = 24;
< 		cols = 80;
< 	} else {
< 		rows = ws.ws_row;
< 		cols = ws.ws_col;
< 	}
< 
< 	if (rows < 19 || cols < 80) {
< 		end_dialog();
< 		fprintf(stderr, "Your display is too small to run Menuconfig!\n");
< 		fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
< 		exit(1);
< 	}
< 
< 	rows -= 4;
< 	cols -= 5;
< 
< }
< 
681d618
< 	init_wsize();
683d619
< 	signal(SIGWINCH, winch_handler); 


More information about the uClibc mailing list