| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | /* 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, old_errno;	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	old_errno = errno;	free(shm_name);	errno = old_errno;	return fd;}int shm_unlink(const char *name){	char *shm_name = get_shm_name(name);	int ret, old_errno;	/* Stripped multiple '/' from start; may have set errno properly */	if (shm_name == NULL)		return -1;	ret = unlink(shm_name);	old_errno = errno;	free(shm_name);	errno = old_errno;	return ret;}
 |