1104476Ssam/* 2104476Ssam * Copyright (c) 1988, 1993 3104476Ssam * The Regents of the University of California. All rights reserved. 4139825Simp * 5104476Ssam * Redistribution and use in source and binary forms, with or without 6104476Ssam * modification, are permitted provided that the following conditions 7104476Ssam * are met: 8104476Ssam * 1. Redistributions of source code must retain the above copyright 9104476Ssam * notice, this list of conditions and the following disclaimer. 10104476Ssam * 2. Redistributions in binary form must reproduce the above copyright 11104476Ssam * notice, this list of conditions and the following disclaimer in the 12275732Sjmg * documentation and/or other materials provided with the distribution. 13275732Sjmg * 4. Neither the name of the University nor the names of its contributors 14104476Ssam * may be used to endorse or promote products derived from this software 15275732Sjmg * without specific prior written permission. 16275732Sjmg * 17275732Sjmg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18275732Sjmg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19104476Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20104476Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21104476Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22104476Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23104476Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24104476Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25104476Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26104476Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27104476Ssam * SUCH DAMAGE. 28104476Ssam */ 29104476Ssam 30104476Ssam#if defined(LIBC_SCCS) && !defined(lint) 31292963Sallanjudestatic char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94"; 32292963Sallanjude#endif /* LIBC_SCCS and not lint */ 33104476Ssam#include <sys/cdefs.h> 34292963Sallanjude__FBSDID("$FreeBSD: stable/10/lib/libc/gen/ttyname.c 317392 2017-04-24 22:44:59Z brooks $"); 35292963Sallanjude 36292963Sallanjude#include "namespace.h" 37292963Sallanjude#include <sys/types.h> 38292963Sallanjude#include <sys/ioctl.h> 39292963Sallanjude#include <sys/filio.h> 40292963Sallanjude#include <fcntl.h> 41292963Sallanjude#include <dirent.h> 42292963Sallanjude#include <stdlib.h> 43292963Sallanjude#include <termios.h> 44104476Ssam#include <unistd.h> 45292963Sallanjude#include <string.h> 46292963Sallanjude#include <paths.h> 47292963Sallanjude#include <errno.h> 48292963Sallanjude#include "reentrant.h" 49292963Sallanjude#include "un-namespace.h" 50104476Ssam 51104476Ssam#include "libc_private.h" 52104476Ssam 53104476Ssamstatic char ttyname_buf[sizeof(_PATH_DEV) + MAXNAMLEN]; 54104476Ssam 55275732Sjmgstatic once_t ttyname_init_once = ONCE_INITIALIZER; 56104476Ssamstatic thread_key_t ttyname_key; 57104476Ssamstatic int ttyname_keycreated = 0; 58104476Ssam 59104476Ssamint 60104476Ssamttyname_r(int fd, char *buf, size_t len) 61213068Spjd{ 62104476Ssam size_t used; 63104476Ssam 64104476Ssam /* Don't write off the end of a zero-length buffer. */ 65104476Ssam if (len < 1) 66104476Ssam return (ERANGE); 67104476Ssam 68104476Ssam *buf = '\0'; 69104476Ssam 70104476Ssam /* Must be a terminal. */ 71104476Ssam if (!isatty(fd)) 72275732Sjmg return (errno); 73275732Sjmg /* Must have enough room */ 74275732Sjmg if (len <= sizeof(_PATH_DEV)) 75213068Spjd return (ERANGE); 76104476Ssam 77169425Sgnn strcpy(buf, _PATH_DEV); 78104476Ssam used = strlen(buf); 79292963Sallanjude if (fdevname_r(fd, buf + used, len - used) == NULL) 80292963Sallanjude return (errno == EINVAL ? ERANGE : errno); 81292963Sallanjude return (0); 82292963Sallanjude} 83292963Sallanjude 84292963Sallanjudestatic void 85104476Ssamttyname_keycreate(void) 86292963Sallanjude{ 87292963Sallanjude ttyname_keycreated = (thr_keycreate(&ttyname_key, free) == 0); 88292963Sallanjude} 89292963Sallanjude 90292963Sallanjudechar * 91104476Ssamttyname(int fd) 92292963Sallanjude{ 93 char *buf; 94 95 if (thr_main() != 0) 96 buf = ttyname_buf; 97 else { 98 if (thr_once(&ttyname_init_once, ttyname_keycreate) != 0 || 99 !ttyname_keycreated) 100 return (NULL); 101 if ((buf = thr_getspecific(ttyname_key)) == NULL) { 102 if ((buf = malloc(sizeof ttyname_buf)) == NULL) 103 return (NULL); 104 if (thr_setspecific(ttyname_key, buf) != 0) { 105 free(buf); 106 return (NULL); 107 } 108 } 109 } 110 111 if (ttyname_r(fd, buf, sizeof ttyname_buf) != 0) 112 return (NULL); 113 return (buf); 114} 115