| 237 | } |
| 238 | |
| 239 | static char *activation_unique_path(const char *directory, const char *tag) { |
| 240 | uint64_t sequence = |
| 241 | atomic_fetch_add_explicit(&activation_unique_sequence, 1U, memory_order_relaxed) + 1U; |
| 242 | #ifdef _WIN32 |
| 243 | unsigned long process_id = (unsigned long)GetCurrentProcessId(); |
| 244 | #else |
| 245 | unsigned long process_id = (unsigned long)getpid(); |
| 246 | #endif |
| 247 | size_t directory_length = strlen(directory); |
| 248 | size_t needed = directory_length + strlen(tag) + 80U; |
| 249 | char *path = malloc(needed); |
| 250 | if (!path) { |
| 251 | return NULL; |
| 252 | } |
| 253 | /* Windows joins use the backslash: extended-length (\\\\?\\) directories |
| 254 | * reach this composer and that namespace performs no forward-slash |
| 255 | * translation. POSIX keeps the slash. */ |
| 256 | #ifdef _WIN32 |
| 257 | const char *separator = "\\"; |
| 258 | #else |
| 259 | const char *separator = "/"; |
| 260 | #endif |
| 261 | int written = |
| 262 | snprintf(path, needed, "%s%s.cbm-%s-%lu-%" PRIu64, directory, |
| 263 | directory[directory_length - 1U] == '/' || directory[directory_length - 1U] == '\\' |
| 264 | ? "" |
| 265 | : separator, |
| 266 | tag, process_id, sequence); |
| 267 | if (written <= 0 || (size_t)written >= needed) { |
| 268 | free(path); |
| 269 | return NULL; |
| 270 | } |
| 271 | return path; |
| 272 | } |
| 273 | |
| 274 | static bool activation_identity_equal(const activation_file_identity_t *left, |
| 275 | const activation_file_identity_t *right) { |
no outgoing calls
no test coverage detected