| | 17 | |
|---|
| | 18 | |
|---|
| | 19 | static const char* kSharedMemoryDir = "/boot/var/shared_memory/"; |
|---|
| | 20 | |
|---|
| | 21 | |
|---|
| | 22 | static bool |
|---|
| | 23 | append_string(char*& path, size_t& bytesLeft, const char* toAppend, size_t size) |
|---|
| | 24 | { |
|---|
| | 25 | if (bytesLeft <= size) |
|---|
| | 26 | return false; |
|---|
| | 27 | |
|---|
| | 28 | memcpy(path, toAppend, size); |
|---|
| | 29 | path += size; |
|---|
| | 30 | path[0] = '\0'; |
|---|
| | 31 | bytesLeft -= size; |
|---|
| | 32 | |
|---|
| | 33 | return true; |
|---|
| | 34 | } |
|---|
| | 35 | |
|---|
| | 36 | |
|---|
| | 37 | static bool |
|---|
| | 38 | append_string(char*& path, size_t& bytesLeft, const char* toAppend) |
|---|
| | 39 | { |
|---|
| | 40 | return append_string(path, bytesLeft, toAppend, strlen(toAppend)); |
|---|
| | 41 | } |
|---|
| | 42 | |
|---|
| | 43 | |
|---|
| | 44 | static status_t |
|---|
| | 45 | shm_name_to_path(const char* name, char* path, size_t pathSize) |
|---|
| | 46 | { |
|---|
| | 47 | if (name == NULL) |
|---|
| | 48 | return B_BAD_VALUE; |
|---|
| | 49 | |
|---|
| | 50 | // skip leading slashes |
|---|
| | 51 | while (*name == '/') |
|---|
| | 52 | name++; |
|---|
| | 53 | |
|---|
| | 54 | if (*name == '\0') |
|---|
| | 55 | return B_BAD_VALUE; |
|---|
| | 56 | |
|---|
| | 57 | // create the path; replace occurrences of '/' by "%s" and '%' by "%%" |
|---|
| | 58 | if (!append_string(path, pathSize, kSharedMemoryDir)) |
|---|
| | 59 | return ENAMETOOLONG; |
|---|
| | 60 | |
|---|
| | 61 | while (const char* found = strpbrk(name, "%/")) { |
|---|
| | 62 | // append section that doesn't need escaping |
|---|
| | 63 | if (found != name) { |
|---|
| | 64 | if (!append_string(path, pathSize, name, found - name)) |
|---|
| | 65 | return ENAMETOOLONG; |
|---|
| | 66 | } |
|---|
| | 67 | |
|---|
| | 68 | // append escaped char |
|---|
| | 69 | const char* append = (*found == '%' ? "%%" : "%s"); |
|---|
| | 70 | if (!append_string(path, pathSize, append, 2)) |
|---|
| | 71 | return ENAMETOOLONG; |
|---|
| | 72 | name = found + 1; |
|---|
| | 73 | } |
|---|
| | 74 | |
|---|
| | 75 | // append remaining string |
|---|
| | 76 | if (!append_string(path, pathSize, name)) |
|---|
| | 77 | return ENAMETOOLONG; |
|---|
| | 78 | |
|---|
| | 79 | return B_OK; |
|---|
| | 80 | } |
|---|
| | 81 | |
|---|
| | 82 | |
|---|
| | 83 | // #pragma mark - |
|---|
| | 143 | |
|---|
| | 144 | |
|---|
| | 145 | int |
|---|
| | 146 | shm_open(const char* name, int openMode, mode_t permissions) |
|---|
| | 147 | { |
|---|
| | 148 | char path[PATH_MAX]; |
|---|
| | 149 | status_t error = shm_name_to_path(name, path, sizeof(path)); |
|---|
| | 150 | if (error != B_OK) |
|---|
| | 151 | RETURN_AND_SET_ERRNO(error); |
|---|
| | 152 | |
|---|
| | 153 | return open(path, openMode, permissions); |
|---|
| | 154 | } |
|---|
| | 155 | |
|---|
| | 156 | |
|---|
| | 157 | int |
|---|
| | 158 | shm_unlink(const char* name) |
|---|
| | 159 | { |
|---|
| | 160 | char path[PATH_MAX]; |
|---|
| | 161 | status_t error = shm_name_to_path(name, path, sizeof(path)); |
|---|
| | 162 | if (error != B_OK) |
|---|
| | 163 | RETURN_AND_SET_ERRNO(error); |
|---|
| | 164 | |
|---|
| | 165 | return unlink(path); |
|---|
| | 166 | } |
|---|