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
This commit is contained in:
Ingo Weinhold 2008-05-08 13:42:33 +00:00
parent cf1c322756
commit f23d0a6242
3 changed files with 107 additions and 9 deletions

View File

@ -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`

View File

@ -5,6 +5,7 @@
#ifndef _SYS_MMAN_H
#define _SYS_MMAN_H
#include <sys/cdefs.h>
#include <sys/types.h>
@ -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

View File

@ -6,6 +6,8 @@
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <OS.h>
@ -14,6 +16,73 @@
#include <vm.h>
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);
}