145e80934SMatthew Dillon /* 245e80934SMatthew Dillon * Copyright (c) 2009 The DragonFly Project. All rights reserved. 345e80934SMatthew Dillon * 445e80934SMatthew Dillon * This code is derived from software contributed to The DragonFly Project 545e80934SMatthew Dillon * by Alex Hornung <ahornung@gmail.com> 645e80934SMatthew Dillon * 745e80934SMatthew Dillon * Redistribution and use in source and binary forms, with or without 845e80934SMatthew Dillon * modification, are permitted provided that the following conditions 945e80934SMatthew Dillon * are met: 1045e80934SMatthew Dillon * 1145e80934SMatthew Dillon * 1. Redistributions of source code must retain the above copyright 1245e80934SMatthew Dillon * notice, this list of conditions and the following disclaimer. 1345e80934SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 1445e80934SMatthew Dillon * notice, this list of conditions and the following disclaimer in 1545e80934SMatthew Dillon * the documentation and/or other materials provided with the 1645e80934SMatthew Dillon * distribution. 1745e80934SMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 1845e80934SMatthew Dillon * contributors may be used to endorse or promote products derived 1945e80934SMatthew Dillon * from this software without specific, prior written permission. 2045e80934SMatthew Dillon * 2145e80934SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2245e80934SMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2345e80934SMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2445e80934SMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2545e80934SMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2645e80934SMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 2745e80934SMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2845e80934SMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2945e80934SMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 3045e80934SMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 3145e80934SMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3245e80934SMatthew Dillon * SUCH DAMAGE. 3345e80934SMatthew Dillon */ 3445e80934SMatthew Dillon #include "namespace.h" 3545e80934SMatthew Dillon #include <sys/types.h> 3645e80934SMatthew Dillon #include <fcntl.h> 3745e80934SMatthew Dillon #include <dirent.h> 3845e80934SMatthew Dillon #include <stdlib.h> 3945e80934SMatthew Dillon #include <termios.h> 4045e80934SMatthew Dillon #include <unistd.h> 4145e80934SMatthew Dillon #include <string.h> 4245e80934SMatthew Dillon #include <paths.h> 4345e80934SMatthew Dillon #include <errno.h> 4445e80934SMatthew Dillon #include <machine/stdint.h> 4545e80934SMatthew Dillon #include <sys/stat.h> 4645e80934SMatthew Dillon #include <sys/ioctl.h> 4745e80934SMatthew Dillon #include "reentrant.h" 4845e80934SMatthew Dillon #include "un-namespace.h" 4945e80934SMatthew Dillon 5045e80934SMatthew Dillon #include "libc_private.h" 5145e80934SMatthew Dillon 5245e80934SMatthew Dillon static char fdevname_buf[sizeof(_PATH_DEV) + NAME_MAX]; 5345e80934SMatthew Dillon 5445e80934SMatthew Dillon static once_t fdevname_init_once = ONCE_INITIALIZER; 5545e80934SMatthew Dillon static thread_key_t fdevname_key; 5645e80934SMatthew Dillon static int fdevname_keycreated = 0; 5745e80934SMatthew Dillon 5845e80934SMatthew Dillon int 5945e80934SMatthew Dillon fdevname_r(int fd, char *buf, size_t len) 6045e80934SMatthew Dillon { 6145e80934SMatthew Dillon struct stat sb; 6245e80934SMatthew Dillon struct fiodname_args fa; 6345e80934SMatthew Dillon 6445e80934SMatthew Dillon *buf = '\0'; 6545e80934SMatthew Dillon 66*65653ce5SAlex Hornung /* Must be a valid file descriptor */ 67*65653ce5SAlex Hornung if (_fstat(fd, &sb)) 68*65653ce5SAlex Hornung return (EBADF); 6945e80934SMatthew Dillon 70*65653ce5SAlex Hornung /* Must be a character device */ 71*65653ce5SAlex Hornung if (!S_ISCHR(sb.st_mode)) 72*65653ce5SAlex Hornung return (EINVAL); 7345e80934SMatthew Dillon 74*65653ce5SAlex Hornung fa.len = len; 75*65653ce5SAlex Hornung fa.name = buf; 7645e80934SMatthew Dillon if (_ioctl(fd, FIODNAME, &fa) == -1) { 7745e80934SMatthew Dillon return ERANGE; 7845e80934SMatthew Dillon } 7945e80934SMatthew Dillon return (0); 8045e80934SMatthew Dillon } 8145e80934SMatthew Dillon 8245e80934SMatthew Dillon static void 8345e80934SMatthew Dillon fdevname_keycreate(void) 8445e80934SMatthew Dillon { 8545e80934SMatthew Dillon fdevname_keycreated = (thr_keycreate(&fdevname_key, free) == 0); 8645e80934SMatthew Dillon } 8745e80934SMatthew Dillon 8845e80934SMatthew Dillon char * 8945e80934SMatthew Dillon fdevname(int fd) 9045e80934SMatthew Dillon { 9145e80934SMatthew Dillon char *buf; 92*65653ce5SAlex Hornung int error; 9345e80934SMatthew Dillon 9445e80934SMatthew Dillon if (thr_main() != 0) 9545e80934SMatthew Dillon buf = fdevname_buf; 9645e80934SMatthew Dillon else { 9745e80934SMatthew Dillon if (thr_once(&fdevname_init_once, fdevname_keycreate) != 0 || 9845e80934SMatthew Dillon !fdevname_keycreated) 9945e80934SMatthew Dillon return (NULL); 10045e80934SMatthew Dillon if ((buf = thr_getspecific(fdevname_key)) == NULL) { 10145e80934SMatthew Dillon if ((buf = malloc(sizeof fdevname_buf)) == NULL) 10245e80934SMatthew Dillon return (NULL); 10345e80934SMatthew Dillon if (thr_setspecific(fdevname_key, buf) != 0) { 10445e80934SMatthew Dillon free(buf); 10545e80934SMatthew Dillon return (NULL); 10645e80934SMatthew Dillon } 10745e80934SMatthew Dillon } 10845e80934SMatthew Dillon } 10945e80934SMatthew Dillon 110*65653ce5SAlex Hornung if (((error = fdevname_r(fd, buf, sizeof fdevname_buf))) != 0) { 111*65653ce5SAlex Hornung errno = error; 11245e80934SMatthew Dillon return (NULL); 113*65653ce5SAlex Hornung } 11445e80934SMatthew Dillon return (buf); 11545e80934SMatthew Dillon } 116