2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
15 #include <errno_private.h>
16 #include <syscall_utils.h>
21 static const char* kSharedMemoryDir
= "/var/shared_memory/";
25 append_string(char*& path
, size_t& bytesLeft
, const char* toAppend
, size_t size
)
27 if (bytesLeft
<= size
)
30 memcpy(path
, toAppend
, size
);
40 append_string(char*& path
, size_t& bytesLeft
, const char* toAppend
)
42 return append_string(path
, bytesLeft
, toAppend
, strlen(toAppend
));
47 shm_name_to_path(const char* name
, char* path
, size_t pathSize
)
52 // skip leading slashes
59 // create the path; replace occurrences of '/' by "%s" and '%' by "%%"
60 if (!append_string(path
, pathSize
, kSharedMemoryDir
))
63 while (const char* found
= strpbrk(name
, "%/")) {
64 // append section that doesn't need escaping
66 if (!append_string(path
, pathSize
, name
, found
- name
))
70 // append escaped char
71 const char* append
= (*found
== '%' ? "%%" : "%s");
72 if (!append_string(path
, pathSize
, append
, 2))
77 // append remaining string
78 if (!append_string(path
, pathSize
, name
))
89 mmap(void* address
, size_t length
, int protection
, int flags
, int fd
,
92 // offset and length must be page-aligned
93 if (length
== 0 || offset
% B_PAGE_SIZE
!= 0) {
94 __set_errno(B_BAD_VALUE
);
98 // check anonymous mapping
99 if ((flags
& MAP_ANONYMOUS
) != 0) {
106 // either MAP_SHARED or MAP_PRIVATE must be specified
107 if (((flags
& MAP_SHARED
) != 0) == ((flags
& MAP_PRIVATE
) != 0)) {
108 __set_errno(B_BAD_VALUE
);
112 // translate mapping, address specification, and protection
113 int mapping
= (flags
& MAP_SHARED
) != 0
114 ? REGION_NO_PRIVATE_MAP
: REGION_PRIVATE_MAP
;
117 if ((flags
& MAP_FIXED
) != 0)
118 addressSpec
= B_EXACT_ADDRESS
;
119 else if (address
!= NULL
)
120 addressSpec
= B_BASE_ADDRESS
;
122 addressSpec
= B_RANDOMIZED_ANY_ADDRESS
;
124 uint32 areaProtection
= 0;
125 if ((protection
& PROT_READ
) != 0)
126 areaProtection
|= B_READ_AREA
;
127 if ((protection
& PROT_WRITE
) != 0)
128 areaProtection
|= B_WRITE_AREA
;
129 if ((protection
& PROT_EXEC
) != 0)
130 areaProtection
|= B_EXECUTE_AREA
;
132 // ask the kernel to map
133 area_id area
= _kern_map_file("mmap area", &address
, addressSpec
,
134 length
, areaProtection
, mapping
, true, fd
, offset
);
145 munmap(void* address
, size_t length
)
147 RETURN_AND_SET_ERRNO(_kern_unmap_memory(address
, length
));
152 mprotect(void* address
, size_t length
, int protection
)
154 RETURN_AND_SET_ERRNO(_kern_set_memory_protection(address
, length
,
160 msync(void* address
, size_t length
, int flags
)
162 RETURN_AND_SET_ERRNO_TEST_CANCEL(_kern_sync_memory(address
, length
, flags
));
167 posix_madvise(void* address
, size_t length
, int advice
)
169 RETURN_AND_SET_ERRNO(_kern_memory_advice(address
, length
, advice
));
174 shm_open(const char* name
, int openMode
, mode_t permissions
)
177 status_t error
= shm_name_to_path(name
, path
, sizeof(path
));
179 RETURN_AND_SET_ERRNO(error
);
181 return open(path
, openMode
| FD_CLOEXEC
, permissions
);
186 shm_unlink(const char* name
)
189 status_t error
= shm_name_to_path(name
, path
, sizeof(path
));
191 RETURN_AND_SET_ERRNO(error
);