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>
44*32cb8272SSascha Wildner #include <limits.h>
4545e80934SMatthew Dillon #include <machine/stdint.h>
4645e80934SMatthew Dillon #include <sys/stat.h>
4745e80934SMatthew Dillon #include <sys/ioctl.h>
4845e80934SMatthew Dillon #include "reentrant.h"
4945e80934SMatthew Dillon #include "un-namespace.h"
5045e80934SMatthew Dillon
5145e80934SMatthew Dillon #include "libc_private.h"
5245e80934SMatthew Dillon
5345e80934SMatthew Dillon static char fdevname_buf[sizeof(_PATH_DEV) + NAME_MAX];
5445e80934SMatthew Dillon
5545e80934SMatthew Dillon static once_t fdevname_init_once = ONCE_INITIALIZER;
5645e80934SMatthew Dillon static thread_key_t fdevname_key;
5745e80934SMatthew Dillon static int fdevname_keycreated = 0;
5845e80934SMatthew Dillon
5945e80934SMatthew Dillon int
fdevname_r(int fd,char * buf,size_t len)6045e80934SMatthew Dillon fdevname_r(int fd, char *buf, size_t len)
6145e80934SMatthew Dillon {
6245e80934SMatthew Dillon struct stat sb;
6345e80934SMatthew Dillon struct fiodname_args fa;
6445e80934SMatthew Dillon
6545e80934SMatthew Dillon *buf = '\0';
6645e80934SMatthew Dillon
6765653ce5SAlex Hornung /* Must be a valid file descriptor */
6865653ce5SAlex Hornung if (_fstat(fd, &sb))
6965653ce5SAlex Hornung return (EBADF);
7045e80934SMatthew Dillon
7165653ce5SAlex Hornung /* Must be a character device */
7265653ce5SAlex Hornung if (!S_ISCHR(sb.st_mode))
7365653ce5SAlex Hornung return (EINVAL);
7445e80934SMatthew Dillon
7565653ce5SAlex Hornung fa.len = len;
7665653ce5SAlex Hornung fa.name = buf;
7745e80934SMatthew Dillon if (_ioctl(fd, FIODNAME, &fa) == -1) {
7845e80934SMatthew Dillon return ERANGE;
7945e80934SMatthew Dillon }
8045e80934SMatthew Dillon return (0);
8145e80934SMatthew Dillon }
8245e80934SMatthew Dillon
8345e80934SMatthew Dillon static void
fdevname_keycreate(void)8445e80934SMatthew Dillon fdevname_keycreate(void)
8545e80934SMatthew Dillon {
8645e80934SMatthew Dillon fdevname_keycreated = (thr_keycreate(&fdevname_key, free) == 0);
8745e80934SMatthew Dillon }
8845e80934SMatthew Dillon
8945e80934SMatthew Dillon char *
fdevname(int fd)9045e80934SMatthew Dillon fdevname(int fd)
9145e80934SMatthew Dillon {
9245e80934SMatthew Dillon char *buf;
9365653ce5SAlex Hornung int error;
9445e80934SMatthew Dillon
9545e80934SMatthew Dillon if (thr_main() != 0)
9645e80934SMatthew Dillon buf = fdevname_buf;
9745e80934SMatthew Dillon else {
9845e80934SMatthew Dillon if (thr_once(&fdevname_init_once, fdevname_keycreate) != 0 ||
9945e80934SMatthew Dillon !fdevname_keycreated)
10045e80934SMatthew Dillon return (NULL);
10145e80934SMatthew Dillon if ((buf = thr_getspecific(fdevname_key)) == NULL) {
10245e80934SMatthew Dillon if ((buf = malloc(sizeof fdevname_buf)) == NULL)
10345e80934SMatthew Dillon return (NULL);
10445e80934SMatthew Dillon if (thr_setspecific(fdevname_key, buf) != 0) {
10545e80934SMatthew Dillon free(buf);
10645e80934SMatthew Dillon return (NULL);
10745e80934SMatthew Dillon }
10845e80934SMatthew Dillon }
10945e80934SMatthew Dillon }
11045e80934SMatthew Dillon
11165653ce5SAlex Hornung if (((error = fdevname_r(fd, buf, sizeof fdevname_buf))) != 0) {
11265653ce5SAlex Hornung errno = error;
11345e80934SMatthew Dillon return (NULL);
11465653ce5SAlex Hornung }
11545e80934SMatthew Dillon return (buf);
11645e80934SMatthew Dillon }
117