From owner-freebsd-current@FreeBSD.ORG Tue Dec 16 00:08:07 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C671616A4CE for ; Tue, 16 Dec 2003 00:08:07 -0800 (PST) Received: from rwcrmhc11.comcast.net (rwcrmhc11.comcast.net [204.127.198.35]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5D12343D41 for ; Tue, 16 Dec 2003 00:08:06 -0800 (PST) (envelope-from d@diefree.com) Received: from diefree.com ([24.6.31.57]) by comcast.net (rwcrmhc11) with ESMTP id <20031216080805013006p643e>; Tue, 16 Dec 2003 08:08:05 +0000 Message-ID: <3FDEBDC4.5090409@diefree.com> Date: Tue, 16 Dec 2003 00:09:40 -0800 From: Dan Hulme User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6b) Gecko/20031206 Thunderbird/0.4 X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-current@freebsd.org Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Subject: Problem with make buildworld with existing terminfo database X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Dec 2003 08:08:08 -0000 The compilation of [/usr/src/usr.sbin/sysinstall] depends on a small program called "rtermcap". The program is used to generate a file called "makedevs.c" from several termcap entries (ansi, xterm, cons25, etc.). rtermcap, in turn, relies on a c call (ncurses) to "tgetent," which checks for a termcap entry, and fills a buffer with the terminal information. On closer inspection, however, "tgetent" is also capable of using terminfo, and in fact prefers terminfo over termcap (if the terminal exists in terminfo, it will never check termcap--perhaps this behavior can be changed in ncurses, but I'm not sure it should be). Unfortunately, it acts a little differently when using terminfo: [man curs_termcap] The tgetent routine loads the entry for name. It returns 1 on success, 0 if there is no such entry, and -1 if the terminfo database could not be found. The emulation ignores the buffer pointer bp. So, in the event that a terminfo database is present, tgetent will use it, and will not fill the buffer. However, the Makefile in [/usr/src/usr.sbin/sysinstall] relies on the buffer being filled, so it can use this data to create the arrays in makedevs.c. There is no detection of this issue currently, and the compilation of sysinstall fails with the following message(s), due to the arrays being empty: makedevs.c:4: error: syntax error before ',' token makedevs.c:7: error: syntax error before ',' token makedevs.c:10: error: syntax error before ',' token makedevs.c:13: error: syntax error before ',' token makedevs.c:16: error: syntax error before ',' token makedevs.c:19: error: syntax error before ',' token makedevs.c:22: error: syntax error before ',' token makedevs.c:25: error: syntax error before ',' token makedevs.c:28: error: syntax error before ',' token makedevs.c:31: error: syntax error before ',' token I happen to have a terminfo database installed in [/usr/share/misc/terminfo]. It really is just a symlink to [/usr/compat/linux/usr/share/terminfo]. Therefore, my build failed, and didn't give me any helpful information when it did so. After tracking down the culprit scripts, I still didn't know what was wrong, because I didn't understand how ncurses deals with terminfo/termcap. Now that I understand it, I think that something should be changed to deal with this possibility. Currently, the workaround is to remove/move the terminfo database during the build. Possible solutions to the problem might include prebuilding makedevs.c (the termcap file hasn't changed in quite a long time), or manually pulling the data using cgetent. I have written a short program to replace rtermcap.c which has identical output, but is terminfo safe (in other words it loads from termcap even if terminfo exists): #include int main(int argc, char**argv) { char * files[]={ "/etc/termcap" }; char * tbuf; char * buf; char * c; char d; int i; if (argc < 2) return 1; i=cgetent(&tbuf, files, argv[1]); for (c = tbuf; *c != 0; c++) { if(*c != '\t' && (*c != 58 || d != 58)) { printf("%c", *c); d = *c; } } cgetclose(); return 0; } I suggest that this code replace rtermcap.c, or some other solution be found, so that having a terminfo database installed doesn't break the build. This code strips tabs and avoids duplicate colons (:), to have the same output as tgetent (which does not appear to strip spaces). I did "make makedevs.c" on this code as well as the original, and the output is identical. If there is a terminfo database installed at [/usr/share/misc/terminfo] (or in root's profile), this code gives identical output, but the original code creates an uncompileable makedevs.c. -Dan Please CC any responses to d@diefree.com, as I am not subscribed.