@@ -136,6 +136,10 @@ static inline void _CFSetProgramNameFromPath(const char *path) {
136
136
#include <sys/exec.h>
137
137
#endif
138
138
139
+ #if TARGET_OS_BSD && defined(__FreeBSD__ )
140
+ #include <sys/sysctl.h>
141
+ #endif
142
+
139
143
const char * _CFProcessPath (void ) {
140
144
if (__CFProcessPath ) return __CFProcessPath ;
141
145
@@ -230,6 +234,29 @@ const char *_CFProcessPath(void) {
230
234
char * res = realpath (ps -> ps_argvstr [0 ], NULL );
231
235
argv0 = res ? res : strdup (ps -> ps_argvstr [0 ]);
232
236
}
237
+ #elif defined(__FreeBSD__ )
238
+ // see sysctl(3), pid == -1 means current process
239
+ int mib [4 ] = {CTL_KERN , KERN_PROC , KERN_PROC_PATHNAME , -1 };
240
+ int sysctl_ret = 0 ;
241
+ size_t len = PATH_MAX + 1 ;
242
+ argv0 = calloc (len , 1 );
243
+
244
+ sysctl_ret = sysctl (mib , 4 , argv0 , & len , NULL , 0 );
245
+
246
+ // in case for whatever reason the path is > PATH_MAX
247
+ if (sysctl_ret == -1 && errno == ENOMEM ) {
248
+ // get size needed
249
+ sysctl_ret = sysctl (mib , 4 , NULL , & len , NULL , 0 );
250
+ if (sysctl_ret != -1 ) {
251
+ argv0 = realloc (argv0 , len );
252
+ sysctl_ret = sysctl (mib , 4 , argv0 , & len , NULL , 0 );
253
+ }
254
+ }
255
+
256
+ if (sysctl_ret == -1 ) {
257
+ free (argv0 );
258
+ argv0 = NULL ;
259
+ }
233
260
#endif
234
261
235
262
if (!__CFProcessIsRestricted () && argv0 && argv0 [0 ] == '/' ) {
@@ -908,6 +935,9 @@ static void __CFTSDFinalize(void *arg) {
908
935
909
936
if (!arg || arg == CF_TSD_BAD_PTR ) {
910
937
// We've already been destroyed. The call above set the bad pointer again. Now we just return.
938
+ #if defined(__FreeBSD__ )
939
+ __CFTSDSetSpecific (NULL );
940
+ #endif
911
941
return ;
912
942
}
913
943
0 commit comments