diff options
author | 1998-11-20 11:18:22 +0000 | |
---|---|---|
committer | 1998-11-20 11:18:22 +0000 | |
commit | 92efb7350713770eeac379dc990eaecbee107aa1 (patch) | |
tree | 9e7a54e9f5f807b6269323fc5be9480298ad6de5 /lib/libc/gen/ttyname.c | |
parent | Move atomic_lock code from asm to C with inline asm; (diff) | |
download | wireguard-openbsd-92efb7350713770eeac379dc990eaecbee107aa1.tar.xz wireguard-openbsd-92efb7350713770eeac379dc990eaecbee107aa1.zip |
Add thread-safety to libc, so that libc_r will build (on i386 at least).
All POSIX libc api now there (to P1003.1c/D10)
(more md stuff is needed for other libc/arch/*)
(setlogin is no longer a special syscall)
Add -pthread option to gcc (that makes it use -lc_r and -D_POSIX_THREADS).
Doc some re-entrant routines
Add libc_r to intro(3)
dig() uses some libc srcs and an extra -I was needed there.
Add more md stuff to libc_r.
Update includes for the pthreads api
Update libc_r TODO
Diffstat (limited to 'lib/libc/gen/ttyname.c')
-rw-r--r-- | lib/libc/gen/ttyname.c | 78 |
1 files changed, 64 insertions, 14 deletions
diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c index 192072a208f..a18b68fdd2c 100644 --- a/lib/libc/gen/ttyname.c +++ b/lib/libc/gen/ttyname.c @@ -32,7 +32,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: ttyname.c,v 1.5 1998/08/27 06:42:16 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: ttyname.c,v 1.6 1998/11/20 11:18:40 d Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -44,13 +44,49 @@ static char rcsid[] = "$OpenBSD: ttyname.c,v 1.5 1998/08/27 06:42:16 deraadt Exp #include <string.h> #include <unistd.h> #include <paths.h> +#include <limits.h> +#include <errno.h> +#include "thread_private.h" -static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; -static char *oldttyname __P((int, struct stat *)); +static char buf[TTY_NAME_MAX]; +static int oldttyname __P((int, struct stat *, char *, size_t)); +static int __ttyname_r_basic __P((int, char *, size_t)); + +int +ttyname_r(int fd, char *buf, size_t buflen) +{ + int ret; + + if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) { + ret = __ttyname_r_basic(fd, buf, buflen); + _FD_UNLOCK(fd, FD_READ); + } + return ret; +} char * -ttyname(fd) +ttyname(int fd) +{ + _THREAD_PRIVATE_KEY(ttyname) + char * bufp = (char*) _THREAD_PRIVATE(ttyname, buf, NULL); + int err; + + if (bufp == NULL) + return NULL; + err = ttyname_r(fd, bufp, sizeof buf); + if (err) { + errno = err; + return NULL; + } + else + return bufp; +} + +static int +__ttyname_r_basic(fd, buf, len) int fd; + char *buf; + size_t len; { struct stat sb; struct termios ttyb; @@ -63,10 +99,14 @@ ttyname(fd) /* Must be a terminal. */ if (tcgetattr(fd, &ttyb) < 0) - return (NULL); + return (errno); /* Must be a character device. */ - if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) - return (NULL); + if (fstat(fd, &sb)) + return (errno); + if (!S_ISCHR(sb.st_mode)) + return (ENOTTY); + if (len < sizeof(_PATH_DEV)) + return (ERANGE); memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV)); @@ -77,40 +117,50 @@ ttyname(fd) key.data = &bkey; key.size = sizeof(bkey); if (!(db->get)(db, &key, &data, 0)) { + if (data.size > len - (sizeof(_PATH_DEV) - 1)) { + (void)(db->close)(db); + return (ERANGE); + } memcpy(buf + sizeof(_PATH_DEV) - 1, data.data, data.size); (void)(db->close)(db); - return (buf); + return (0); } (void)(db->close)(db); } - return (oldttyname(fd, &sb)); + return (oldttyname(fd, &sb, buf, len)); } /* ARGSUSED */ -static char * -oldttyname(fd, sb) +static int +oldttyname(fd, sb, buf, len) int fd; struct stat *sb; + char *buf; + size_t len; { register struct dirent *dirp; register DIR *dp; struct stat dsb; if ((dp = opendir(_PATH_DEV)) == NULL) - return (NULL); + return (errno); while ((dirp = readdir(dp))) { if (dirp->d_fileno != sb->st_ino) continue; + if (dirp->d_namlen > len - sizeof(_PATH_DEV)) { + (void)closedir(dp); + return (ERANGE); + } memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, dirp->d_namlen + 1); if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev || sb->st_ino != dsb.st_ino) continue; (void)closedir(dp); - return (buf); + return (0); } (void)closedir(dp); - return (NULL); + return (ENOTTY); } |