| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | /* Copyright (C) 2009 Bernhard Reutner-Fischer <uclibc@uclibc.org> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */#include <features.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#ifndef _PATH_SHM#define _PATH_SHM "/dev/shm/"#endif#ifndef NAME_MAX#define NAME_MAX 255#endif/* Get name of dummy shm operation handle. * Returns a malloc'ed buffer containing the OS specific path * to the shm filename or NULL upon failure. */static __attribute_noinline__ char* get_shm_name(const char *name) __nonnull((1));static char* get_shm_name(const char *name){	char *path;	int i;	/* Skip leading slashes */	while (*name == '/')		++name;#ifdef __USE_GNU	i = asprintf(&path, _PATH_SHM "%s", name);	if (i < 0)		return NULL;#else	path = malloc(NAME_MAX);	if (path == NULL)		return NULL;	i = snprintf(path, NAME_MAX, _PATH_SHM "%s", name);	if (i < 0) {		free(path);		return NULL;	} else if (i >= NAME_MAX) {		free(path);		__set_errno(ENAMETOOLONG);		return NULL;	}#endif	return path;}int shm_open(const char *name, int oflag, mode_t mode){	int fd;	char *shm_name = get_shm_name(name);	/* Stripped multiple '/' from start; may have set errno properly */	if (shm_name == NULL)		return -1;	/* The FD_CLOEXEC file descriptor flag associated with the new	 * file descriptor is set.  */#ifdef O_CLOEXEC	 /* Just open it with CLOEXEC set, for brevity */	fd = open(shm_name, oflag | O_CLOEXEC, mode);#else	fd = open(shm_name, oflag, mode);	if (fd >= 0) {		fcntl(fd, F_SETFD, FD_CLOEXEC);		/* thus far, {G,S}ETFD only has this single flag,		 * and setting it never fails.		 *int fdflags = fcntl(fd, F_GETFD);		 *if (fdflags >= 0)		 *	fdflags = fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);		 *if (fdflags < 0) {		 *	close(fd);		 *	fd = -1;		 *}		 */	}#endif	free(shm_name); /* doesn't affect errno */	return fd;}int shm_unlink(const char *name){	char *shm_name = get_shm_name(name);	int ret;	/* Stripped multiple '/' from start; may have set errno properly */	if (shm_name == NULL)		return -1;	ret = unlink(shm_name);	free(shm_name); /* doesn't affect errno */	return ret;}
 |