Date: Wed, 29 Oct 1997 03:24:19 -0800 (PST) From: asami@cs.berkeley.edu (Satoshi Asami) To: peter@spinner.netplex.com.au Cc: freebsd-current@freefall.FreeBSD.org Subject: Re: bad system call - world build Message-ID: <199710291124.DAA14565@silvia.HIP.Berkeley.EDU> In-Reply-To: <1126.878119837@critter.freebsd.dk> (message from Poul-Henning Kamp on Wed, 29 Oct 1997 11:10:37 %2B0100)
next in thread | previous in thread | raw e-mail | index | archive | help
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 <stdlib.h> #include <string.h> #include <unistd.h> +#include <signal.h> #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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710291124.DAA14565>