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>
