From b32dd708df63d90f9d755b6c0de2588200e432ca Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Tue, 2 Jun 2009 16:53:24 +0200 Subject: add stub for shm_open() and shm_unlink Untested and needs testsuite exercise added Signed-off-by: Bernhard Reutner-Fischer --- librt/shm.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 librt/shm.c (limited to 'librt') diff --git a/librt/shm.c b/librt/shm.c new file mode 100644 index 000000000..637e94559 --- /dev/null +++ b/librt/shm.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2009 Bernhard Reutner-Fischer + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef O_CLOEXEC +#include +#endif + +#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; + } +#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) { + int fdflags = fcntl(fd, F_GETFD, 0); + 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; + + /* Stripped multiple '/' from start; may have set errno properly */ + if (shm_name == NULL) + return -1; + ret = unlink(shm_name); + free(shm_name); + return ret; +} -- cgit v1.2.3 From 0e605ccee71b9072671b7dfe93a4b82400277e60 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Tue, 2 Jun 2009 17:58:58 +0200 Subject: include errno.h unconditionally Signed-off-by: Bernhard Reutner-Fischer --- librt/shm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'librt') diff --git a/librt/shm.c b/librt/shm.c index 637e94559..3f33d68af 100644 --- a/librt/shm.c +++ b/librt/shm.c @@ -10,10 +10,7 @@ #include #include #include - -#ifndef O_CLOEXEC #include -#endif #ifndef _PATH_SHM #define _PATH_SHM "/dev/shm/" @@ -87,12 +84,14 @@ int shm_open(const char *name, int oflag, mode_t mode) int shm_unlink(const char *name) { char *shm_name = get_shm_name(name); - int ret; + 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; } -- cgit v1.2.3 From eac5e6eee91332c3c98f4c5a3ee2d55ec1723d81 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Fri, 3 Jul 2009 00:20:19 +0200 Subject: add testcases for shm_{open,unlink} Reported-by: Mikael Lund Jepsen Signed-off-by: Bernhard Reutner-Fischer --- librt/shm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'librt') diff --git a/librt/shm.c b/librt/shm.c index 3f33d68af..c7c0ee461 100644 --- a/librt/shm.c +++ b/librt/shm.c @@ -45,6 +45,10 @@ static char* get_shm_name(const char*name) if (i < 0) { free(path); return NULL; + } else if (i >= NAME_MAX) { + free(path); + __set_errno(ENAMETOOLONG); + return NULL; } #endif return path; -- cgit v1.2.3