From f23d0a624287b6d275610e71d7c329323a565975 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 8 May 2008 13:42:33 +0000 Subject: [PATCH] Implement shm_open() and shm_unlink(). The shared memory objects are simply created as files in /boot/var/shared_memory/. The Bootscript clears the directory. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25374 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- data/system/boot/Bootscript | 6 ++ headers/posix/sys/mman.h | 17 +++-- src/system/libroot/posix/sys/mman.cpp | 93 +++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 9 deletions(-) diff --git a/data/system/boot/Bootscript b/data/system/boot/Bootscript index 24d88dc1f0..4486c6970d 100644 --- a/data/system/boot/Bootscript +++ b/data/system/boot/Bootscript @@ -57,6 +57,12 @@ exec >/dev/null 2>&1 SCRIPTS=beos/system/boot SERVERS=beos/system/servers +# clean the shared memory dir +shmDir=/boot/var/shared_memory +rm -rf $shmDir +mkdir $shmDir +chmod 777 $shmDir + # Set up the environment export SAFEMODE=`/bin/safemode` diff --git a/headers/posix/sys/mman.h b/headers/posix/sys/mman.h index c9bfcad0fa..40c98c74d4 100644 --- a/headers/posix/sys/mman.h +++ b/headers/posix/sys/mman.h @@ -5,6 +5,7 @@ #ifndef _SYS_MMAN_H #define _SYS_MMAN_H +#include #include @@ -24,19 +25,17 @@ // mmap() error return code #define MAP_FAILED ((void*)-1) -#ifdef __cplusplus -extern "C" { -#endif +__BEGIN_DECLS -extern void* mmap(void* address, size_t length, int protection, int flags, - int fd, off_t offset); -extern int munmap(void* address, size_t length); +void* mmap(void* address, size_t length, int protection, int flags, + int fd, off_t offset); +int munmap(void* address, size_t length); +int shm_open(const char* name, int openMode, mode_t permissions); +int shm_unlink(const char* name); -#ifdef __cplusplus -} -#endif +__END_DECLS #endif // _SYS_MMAN_H diff --git a/src/system/libroot/posix/sys/mman.cpp b/src/system/libroot/posix/sys/mman.cpp index 615030633b..fadfc7f0ed 100644 --- a/src/system/libroot/posix/sys/mman.cpp +++ b/src/system/libroot/posix/sys/mman.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include @@ -14,6 +16,73 @@ #include +static const char* kSharedMemoryDir = "/boot/var/shared_memory/"; + + +static bool +append_string(char*& path, size_t& bytesLeft, const char* toAppend, size_t size) +{ + if (bytesLeft <= size) + return false; + + memcpy(path, toAppend, size); + path += size; + path[0] = '\0'; + bytesLeft -= size; + + return true; +} + + +static bool +append_string(char*& path, size_t& bytesLeft, const char* toAppend) +{ + return append_string(path, bytesLeft, toAppend, strlen(toAppend)); +} + + +static status_t +shm_name_to_path(const char* name, char* path, size_t pathSize) +{ + if (name == NULL) + return B_BAD_VALUE; + + // skip leading slashes + while (*name == '/') + name++; + + if (*name == '\0') + return B_BAD_VALUE; + + // create the path; replace occurrences of '/' by "%s" and '%' by "%%" + if (!append_string(path, pathSize, kSharedMemoryDir)) + return ENAMETOOLONG; + + while (const char* found = strpbrk(name, "%/")) { + // append section that doesn't need escaping + if (found != name) { + if (!append_string(path, pathSize, name, found - name)) + return ENAMETOOLONG; + } + + // append escaped char + const char* append = (*found == '%' ? "%%" : "%s"); + if (!append_string(path, pathSize, append, 2)) + return ENAMETOOLONG; + name = found + 1; + } + + // append remaining string + if (!append_string(path, pathSize, name)) + return ENAMETOOLONG; + + return B_OK; +} + + +// #pragma mark - + + void* mmap(void* address, size_t length, int protection, int flags, int fd, off_t offset) @@ -71,3 +140,27 @@ munmap(void* address, size_t length) { RETURN_AND_SET_ERRNO(_kern_unmap_memory(address, length)); } + + +int +shm_open(const char* name, int openMode, mode_t permissions) +{ + char path[PATH_MAX]; + status_t error = shm_name_to_path(name, path, sizeof(path)); + if (error != B_OK) + RETURN_AND_SET_ERRNO(error); + + return open(path, openMode, permissions); +} + + +int +shm_unlink(const char* name) +{ + char path[PATH_MAX]; + status_t error = shm_name_to_path(name, path, sizeof(path)); + if (error != B_OK) + RETURN_AND_SET_ERRNO(error); + + return unlink(path); +}