diff options
author | peter <peter@FreeBSD.org> | 1997-11-29 11:30:57 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1997-11-29 11:30:57 +0000 |
commit | 0f5c6ba2fe6220b669a693bd6f6a1ba5fe7a0b00 (patch) | |
tree | 22656faf17c533fde4f5f26c43adc0a31761df83 /lib/libtermcap/termcap.c | |
parent | 208bdc6cb329e1cc94f7a79b9fe9a10c06ed7b23 (diff) | |
download | FreeBSD-src-0f5c6ba2fe6220b669a693bd6f6a1ba5fe7a0b00.zip FreeBSD-src-0f5c6ba2fe6220b669a693bd6f6a1ba5fe7a0b00.tar.gz |
Work around the problems caused by calling issetugid() in libtermcap in
a similar way to libc. Sigh. This is not pretty but seems to work.
Somthing like this was needed in preference to bogusly bumping the major
library number here.
The syscall(SYS_issetugid) idea is originally Bruce's.
Diffstat (limited to 'lib/libtermcap/termcap.c')
-rw-r--r-- | lib/libtermcap/termcap.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/lib/libtermcap/termcap.c b/lib/libtermcap/termcap.c index 4b98c1b..0f76a86 100644 --- a/lib/libtermcap/termcap.c +++ b/lib/libtermcap/termcap.c @@ -45,6 +45,9 @@ static char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93"; #include <string.h> #include <unistd.h> #include <termios.h> +#include <signal.h> +#include <errno.h> +#include <sys/syscall.h> #include "termcap.h" #include "pathnames.h" @@ -64,6 +67,8 @@ static char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93"; static char *tbuf; /* termcap buffer */ +static int use_issetugid = 1; /* 0 = not present, 1 = try it, 2 = exists */ + /* * Get an entry for terminal name in buffer bp from the termcap file. */ @@ -115,8 +120,42 @@ tgetent(char *bp, const char *name) strncpy(pathbuf, cp, PBUFSIZ); /* still can be tokenized */ pathbuf[PBUFSIZ - 1] = '\0'; - if (issetugid()) - strcpy(pathbuf, _PATH_DEF_SEC); +#ifdef SYS_issetugid + /* + * This stuff is to try and detect the presence of the issetugid() + * syscall without breaking dynamic linking during compiles.. Sigh. + */ +othersyscall: + if (use_issetugid) { + struct sigaction sa, osa; + int sigsys_installed = 0; + int unsafe; + + if (use_issetugid == 1) { + bzero(&sa, sizeof(sa)); + sa.sa_handler = SIG_IGN; + if (sigaction(SIGSYS, &sa, &osa) >= 0) + sigsys_installed = 1; + } + errno = 0; + unsafe = syscall(SYS_issetugid); + if (sigsys_installed == 1) { + int oerrno = errno; + sigaction(SIGSYS, &osa, NULL); + errno = oerrno; + } + if (errno == ENOSYS || errno == EINVAL) { + use_issetugid = 0; + goto othersyscall; + } else if (sigsys_installed == 1) + sigsys_installed = 2; + if (unsafe) + strcpy(pathbuf, _PATH_DEF_SEC); + } else +#endif /* SYS_issetugid */ + /* issetugid() not in kernel or undefined - try second best */ + if (getuid() != geteid() || getgid() != getegid()) + strcpy(pathbuf, _PATH_DEF_SEC); *fname++ = pathbuf; /* tokenize path into vector of names */ while (*++p) |