11573Srgrimes/* 21573Srgrimes * Copyright (c) 1988, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 4. Neither the name of the University nor the names of its contributors 141573Srgrimes * may be used to endorse or promote products derived from this software 151573Srgrimes * without specific prior written permission. 161573Srgrimes * 171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271573Srgrimes * SUCH DAMAGE. 281573Srgrimes */ 291573Srgrimes 301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 311573Srgrimesstatic char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94"; 321573Srgrimes#endif /* LIBC_SCCS and not lint */ 3390045Sobrien#include <sys/cdefs.h> 3490045Sobrien__FBSDID("$FreeBSD$"); 351573Srgrimes 3671579Sdeischen#include "namespace.h" 371573Srgrimes#include <sys/types.h> 38143305Sphk#include <sys/ioctl.h> 39143305Sphk#include <sys/filio.h> 401573Srgrimes#include <fcntl.h> 411573Srgrimes#include <dirent.h> 4213545Sjulian#include <stdlib.h> 4310954Speter#include <termios.h> 4413545Sjulian#include <unistd.h> 451573Srgrimes#include <string.h> 461573Srgrimes#include <paths.h> 47146186Sdelphij#include <errno.h> 48146453Sume#include "reentrant.h" 4971579Sdeischen#include "un-namespace.h" 5013545Sjulian 5171579Sdeischen#include "libc_private.h" 5271579Sdeischen 53143305Sphkstatic char ttyname_buf[sizeof(_PATH_DEV) + MAXNAMLEN]; 5471579Sdeischen 55146453Sumestatic once_t ttyname_init_once = ONCE_INITIALIZER; 56146453Sumestatic thread_key_t ttyname_key; 57146453Sumestatic int ttyname_keycreated = 0; 5871579Sdeischen 59146186Sdelphijint 6071579Sdeischenttyname_r(int fd, char *buf, size_t len) 6113545Sjulian{ 62146455Sume size_t used; 6313545Sjulian 64143305Sphk *buf = '\0'; 6513545Sjulian 6613545Sjulian /* Must be a terminal. */ 6713545Sjulian if (!isatty(fd)) 68146186Sdelphij return (ENOTTY); 6913545Sjulian /* Must have enough room */ 7013545Sjulian if (len <= sizeof(_PATH_DEV)) 71146186Sdelphij return (ERANGE); 7213545Sjulian 73116651Sphk strcpy(buf, _PATH_DEV); 74146455Sume used = strlen(buf); 75188497Sed if (fdevname_r(fd, buf + used, len - used) == NULL) 76188497Sed return (ENOTTY); 77146186Sdelphij return (0); 7813545Sjulian} 7913545Sjulian 80146453Sumestatic void 81146453Sumettyname_keycreate(void) 82146453Sume{ 83146453Sume ttyname_keycreated = (thr_keycreate(&ttyname_key, free) == 0); 84146453Sume} 85146453Sume 86143305Sphkchar * 87143305Sphkttyname(int fd) 8813545Sjulian{ 8971579Sdeischen char *buf; 9013545Sjulian 91146453Sume if (thr_main() != 0) 92146453Sume buf = ttyname_buf; 93146453Sume else { 94146453Sume if (thr_once(&ttyname_init_once, ttyname_keycreate) != 0 || 95146453Sume !ttyname_keycreated) 96146186Sdelphij return (NULL); 97146453Sume if ((buf = thr_getspecific(ttyname_key)) == NULL) { 98146453Sume if ((buf = malloc(sizeof ttyname_buf)) == NULL) 9971579Sdeischen return (NULL); 100146453Sume if (thr_setspecific(ttyname_key, buf) != 0) { 10113545Sjulian free(buf); 10213545Sjulian return (NULL); 10313545Sjulian } 10413545Sjulian } 10513545Sjulian } 106146453Sume 107146453Sume if (ttyname_r(fd, buf, sizeof ttyname_buf) != 0) 108146451Sume return (NULL); 109146186Sdelphij return (buf); 11013545Sjulian} 111