xref: /dflybsd-src/lib/libc/gen/fdevname.c (revision 32cb82727ec681e604bb5631909bd642cd14fe5a)
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