this repo has no description
1#include <errno.h>
2#include <stddef.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <pthread.h>
6#include "dirhelper_priv.h"
7
8static const char* dir_suffix = NULL;
9static pthread_mutex_t dir_suffix_lock = PTHREAD_MUTEX_INITIALIZER;
10
11void _dirhelper_fork_child(void)
12{
13}
14
15void _libcoreservices_fork_child(void)
16{
17 /**
18 * my god, threading is *incredibly* tricky when mixed with `fork()`!
19 * and the POSIX spec is so unclear about the behavior of mutexes when `fork()`ing
20 * and the macOS docs are no help
21 *
22 * the *only* viable resources i found was this commit in jemalloc:
23 * https://github.com/jemalloc/jemalloc/commit/0a4f5a7eea5e42292cea95fd30a88201c8d4a1ca
24 *
25 * basically, it *seems* that it's fine to reinitialize mutexes in the child---on macOS at least
26 * but i really wish the POSIX spec or macOS docs mentioned this kind of stuff!
27 *
28 * undefined behavior is really the **worst** behavior
29 */
30 dir_suffix_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
31
32 /**
33 * i checked on a real macOS system and confirmed this behavior:
34 * `fork()` does NOT reset the directory suffix
35 */
36 //dir_suffix = NULL;
37}
38
39char* _dirhelper(int which, char* p, size_t limit)
40{
41 pthread_mutex_lock(&dir_suffix_lock);
42 switch (which)
43 {
44 case DIRHELPER_USER_LOCAL:
45 {
46 const char* home;
47
48 home = getenv("HOME");
49 if (home == NULL)
50 home = "";
51
52 snprintf(p, limit, "%s/%s%s", home, dir_suffix ? dir_suffix : "", dir_suffix ? "/" : "");
53 } break;
54 case DIRHELPER_USER_LOCAL_TEMP:
55 {
56 const char* tmp;
57
58 tmp = getenv("TMPDIR");
59 if (tmp == NULL)
60 tmp = "/tmp";
61
62 snprintf(p, limit, "%s/%s%s", tmp, dir_suffix ? dir_suffix : "", dir_suffix ? "/" : "");
63 } break;
64 case DIRHELPER_USER_LOCAL_CACHE:
65 {
66 const char* home;
67
68 home = getenv("HOME");
69 if (home != NULL)
70 snprintf(p, limit, "%s/.cache/%s%s", home, dir_suffix ? dir_suffix : "", dir_suffix ? "/" : "");
71 else
72 snprintf(p, limit, "/tmp/%s%s", dir_suffix ? dir_suffix : "", dir_suffix ? "/" : "");
73 } break;
74 default:
75 p = NULL;
76 }
77 pthread_mutex_unlock(&dir_suffix_lock);
78 return p;
79}
80
81int _set_user_dir_suffix(const char* suffix) {
82 pthread_mutex_lock(&dir_suffix_lock);
83 dir_suffix = suffix;
84 pthread_mutex_unlock(&dir_suffix_lock);
85 return 1; // weird, it's supposed to return non-zero on success (maybe it's actually a bool?)
86};
87