From owner-freebsd-current Wed Oct 29 03:24:43 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id DAA10013 for current-outgoing; Wed, 29 Oct 1997 03:24:43 -0800 (PST) (envelope-from owner-freebsd-current) Received: from silvia.HIP.Berkeley.EDU (wck-ca6-01.ix.netcom.com [199.35.213.193]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id DAA10004 for ; Wed, 29 Oct 1997 03:24:38 -0800 (PST) (envelope-from asami@vader.cs.berkeley.edu) Received: (from asami@localhost) by silvia.HIP.Berkeley.EDU (8.8.7/8.6.9) id DAA14565; Wed, 29 Oct 1997 03:24:19 -0800 (PST) Date: Wed, 29 Oct 1997 03:24:19 -0800 (PST) Message-Id: <199710291124.DAA14565@silvia.HIP.Berkeley.EDU> To: peter@spinner.netplex.com.au CC: freebsd-current@freefall.FreeBSD.org In-reply-to: <1126.878119837@critter.freebsd.dk> (message from Poul-Henning Kamp on Wed, 29 Oct 1997 11:10:37 +0100) Subject: Re: bad system call - world build From: asami@cs.berkeley.edu (Satoshi Asami) Sender: owner-freebsd-current@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk Peter, I took a look at your patch (attached below for the readers' convenience): =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/getcwd.c,v retrieving revision 1.13 retrieving revision 1.14 diff -p -u -r1.13 -r1.14 --- src/lib/libc/gen/getcwd.c 1997/09/15 17:40:15 1.13 +++ /home/ncvs/src/lib/libc/gen/getcwd.c 1997/09/16 06:00:50 1.14 @@ -45,11 +45,14 @@ static char sccsid[] = "@(#)getcwd.c 8.5 #include #include #include +#include #define ISDOT(dp) \ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) +static int have__getcwd = 1; /* 0 = no, 1 = perhaps, 2 = yes */ + char * getcwd(pt, size) char *pt; @@ -89,17 +92,40 @@ getcwd(pt, size) return (NULL); ept = pt + ptsize; } - if (!__getcwd(pt, ept - pt)) { - if (*pt != '/') { - bpt = pt; - ept = pt + strlen(pt) - 1; - while (bpt < ept) { - c = *bpt; - *bpt++ = *ept; - *ept-- = c; + if (have__getcwd) { + struct sigaction sa, osa; + int sigsys_installed = 0; + int ret; + + if (have__getcwd == 1) { /* unsure? */ + bzero(&sa, sizeof(sa)); + sa.sa_handler = SIG_IGN; + if (sigaction(SIGSYS, &sa, &osa) >= 0) + sigsys_installed = 1; + } + ret = __getcwd(pt, ept - pt); + if (sigsys_installed == 1) { + int oerrno = errno; + sigaction(SIGSYS, &osa, NULL); + errno = oerrno; + } + /* XXX a bogus syscall seems to return EINVAL(!) */ + if (ret < 0 && (errno == ENOSYS || errno == EINVAL)) + have__getcwd = 0; + else if (have__getcwd == 1) + have__getcwd = 2; /* yep, remember we have it */ + if (ret == 0) { + if (*pt != '/') { + bpt = pt; + ept = pt + strlen(pt) - 1; + while (bpt < ept) { + c = *bpt; + *bpt++ = *ept; + *ept-- = c; + } } + return (pt); } - return (pt); } bpt = ept - 1; *bpt = '\0'; ======= It appears to be fine, I can't find anything wrong with it except the "else if (have__getcwd == 1)" is sort of redundant ("else" is good enough here). This is what I know about the "make world" problem: (1) It only breaks on some programs, most notably vi during termcap compilation. There should be some other programs before vi that use getcwd(), I wonder why they don't die. (2) It only breaks on older systems, like 2.1.5 or 2.2.2. I think it works on a recent 2.2-stable (I'm not sure, testing now). Do you have any idea what's going on? Especially (2), was there a matching commit that went into RELENG_2_2 at that time? Thanks Satoshi