1*45e80934SMatthew Dillon /* 2*45e80934SMatthew Dillon * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3*45e80934SMatthew Dillon * 4*45e80934SMatthew Dillon * This code is derived from software contributed to The DragonFly Project 5*45e80934SMatthew Dillon * by Alex Hornung <ahornung@gmail.com> 6*45e80934SMatthew Dillon * 7*45e80934SMatthew Dillon * Redistribution and use in source and binary forms, with or without 8*45e80934SMatthew Dillon * modification, are permitted provided that the following conditions 9*45e80934SMatthew Dillon * are met: 10*45e80934SMatthew Dillon * 11*45e80934SMatthew Dillon * 1. Redistributions of source code must retain the above copyright 12*45e80934SMatthew Dillon * notice, this list of conditions and the following disclaimer. 13*45e80934SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 14*45e80934SMatthew Dillon * notice, this list of conditions and the following disclaimer in 15*45e80934SMatthew Dillon * the documentation and/or other materials provided with the 16*45e80934SMatthew Dillon * distribution. 17*45e80934SMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 18*45e80934SMatthew Dillon * contributors may be used to endorse or promote products derived 19*45e80934SMatthew Dillon * from this software without specific, prior written permission. 20*45e80934SMatthew Dillon * 21*45e80934SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*45e80934SMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*45e80934SMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24*45e80934SMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25*45e80934SMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26*45e80934SMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*45e80934SMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28*45e80934SMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29*45e80934SMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30*45e80934SMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31*45e80934SMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*45e80934SMatthew Dillon * SUCH DAMAGE. 33*45e80934SMatthew Dillon */ 34*45e80934SMatthew Dillon #include "namespace.h" 35*45e80934SMatthew Dillon #include <sys/types.h> 36*45e80934SMatthew Dillon #include <fcntl.h> 37*45e80934SMatthew Dillon #include <dirent.h> 38*45e80934SMatthew Dillon #include <stdlib.h> 39*45e80934SMatthew Dillon #include <termios.h> 40*45e80934SMatthew Dillon #include <unistd.h> 41*45e80934SMatthew Dillon #include <string.h> 42*45e80934SMatthew Dillon #include <paths.h> 43*45e80934SMatthew Dillon #include <errno.h> 44*45e80934SMatthew Dillon #include <machine/stdint.h> 45*45e80934SMatthew Dillon #include <sys/stat.h> 46*45e80934SMatthew Dillon #include <sys/ioctl.h> 47*45e80934SMatthew Dillon #include "reentrant.h" 48*45e80934SMatthew Dillon #include "un-namespace.h" 49*45e80934SMatthew Dillon 50*45e80934SMatthew Dillon #include "libc_private.h" 51*45e80934SMatthew Dillon 52*45e80934SMatthew Dillon static char fdevname_buf[sizeof(_PATH_DEV) + NAME_MAX]; 53*45e80934SMatthew Dillon 54*45e80934SMatthew Dillon static once_t fdevname_init_once = ONCE_INITIALIZER; 55*45e80934SMatthew Dillon static thread_key_t fdevname_key; 56*45e80934SMatthew Dillon static int fdevname_keycreated = 0; 57*45e80934SMatthew Dillon 58*45e80934SMatthew Dillon int 59*45e80934SMatthew Dillon fdevname_r(int fd, char *buf, size_t len) 60*45e80934SMatthew Dillon { 61*45e80934SMatthew Dillon struct stat sb; 62*45e80934SMatthew Dillon struct fiodname_args fa; 63*45e80934SMatthew Dillon size_t used; 64*45e80934SMatthew Dillon 65*45e80934SMatthew Dillon *buf = '\0'; 66*45e80934SMatthew Dillon 67*45e80934SMatthew Dillon /* Must be a character device. */ 68*45e80934SMatthew Dillon if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) 69*45e80934SMatthew Dillon return (ENOTTY); 70*45e80934SMatthew Dillon 71*45e80934SMatthew Dillon /* Must have enough room */ 72*45e80934SMatthew Dillon if (len <= sizeof(_PATH_DEV)) 73*45e80934SMatthew Dillon return (ERANGE); 74*45e80934SMatthew Dillon 75*45e80934SMatthew Dillon strcpy(buf, _PATH_DEV); 76*45e80934SMatthew Dillon used = strlen(buf); 77*45e80934SMatthew Dillon fa.len = len - used; 78*45e80934SMatthew Dillon fa.name = buf + used; 79*45e80934SMatthew Dillon if (_ioctl(fd, FIODNAME, &fa) == -1) { 80*45e80934SMatthew Dillon return ERANGE; 81*45e80934SMatthew Dillon } 82*45e80934SMatthew Dillon return (0); 83*45e80934SMatthew Dillon } 84*45e80934SMatthew Dillon 85*45e80934SMatthew Dillon static void 86*45e80934SMatthew Dillon fdevname_keycreate(void) 87*45e80934SMatthew Dillon { 88*45e80934SMatthew Dillon fdevname_keycreated = (thr_keycreate(&fdevname_key, free) == 0); 89*45e80934SMatthew Dillon } 90*45e80934SMatthew Dillon 91*45e80934SMatthew Dillon char * 92*45e80934SMatthew Dillon fdevname(int fd) 93*45e80934SMatthew Dillon { 94*45e80934SMatthew Dillon char *buf; 95*45e80934SMatthew Dillon 96*45e80934SMatthew Dillon if (thr_main() != 0) 97*45e80934SMatthew Dillon buf = fdevname_buf; 98*45e80934SMatthew Dillon else { 99*45e80934SMatthew Dillon if (thr_once(&fdevname_init_once, fdevname_keycreate) != 0 || 100*45e80934SMatthew Dillon !fdevname_keycreated) 101*45e80934SMatthew Dillon return (NULL); 102*45e80934SMatthew Dillon if ((buf = thr_getspecific(fdevname_key)) == NULL) { 103*45e80934SMatthew Dillon if ((buf = malloc(sizeof fdevname_buf)) == NULL) 104*45e80934SMatthew Dillon return (NULL); 105*45e80934SMatthew Dillon if (thr_setspecific(fdevname_key, buf) != 0) { 106*45e80934SMatthew Dillon free(buf); 107*45e80934SMatthew Dillon return (NULL); 108*45e80934SMatthew Dillon } 109*45e80934SMatthew Dillon } 110*45e80934SMatthew Dillon } 111*45e80934SMatthew Dillon 112*45e80934SMatthew Dillon if (fdevname_r(fd, buf, sizeof fdevname_buf) != 0) 113*45e80934SMatthew Dillon return (NULL); 114*45e80934SMatthew Dillon return (buf); 115*45e80934SMatthew Dillon } 116