@@ -42,10 +42,14 @@ void cbm_daemon_runtime_force_peer_image_unverified_for_testing(bool force) {
4242#include <sys/proc_info.h>
4343#include <sys/stat.h>
4444#include <unistd.h>
45- #elif defined(__linux__ )
45+ #elif defined(__linux__ ) || defined( __FreeBSD__ )
4646#include <fcntl.h>
4747#include <sys/stat.h>
4848#include <unistd.h>
49+ #if defined(__FreeBSD__ )
50+ #include <sys/types.h>
51+ #include <sys/sysctl.h>
52+ #endif
4953#endif
5054
5155enum {
@@ -147,7 +151,7 @@ typedef struct {
147151 HANDLE file ;
148152 BY_HANDLE_FILE_INFORMATION information ;
149153 LARGE_INTEGER size ;
150- #elif defined(__APPLE__ ) || defined(__linux__ )
154+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
151155 int fd ;
152156 struct stat status ;
153157#endif
@@ -502,7 +506,7 @@ static bool runtime_activation_response_decode(
502506static uint64_t runtime_current_process_id (void ) {
503507#ifdef _WIN32
504508 return (uint64_t )GetCurrentProcessId ();
505- #elif defined(__APPLE__ ) || defined(__linux__ )
509+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
506510 return (uint64_t )getpid ();
507511#else
508512 return 0 ;
@@ -516,7 +520,7 @@ static void runtime_process_image_reference_init(runtime_process_image_reference
516520 memset (reference , 0 , sizeof (* reference ));
517521#ifdef _WIN32
518522 reference -> file = INVALID_HANDLE_VALUE ;
519- #elif defined(__APPLE__ ) || defined(__linux__ )
523+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
520524 reference -> fd = -1 ;
521525#endif
522526}
@@ -530,7 +534,7 @@ static bool runtime_process_image_reference_release(runtime_process_image_refere
530534 if (reference -> file != INVALID_HANDLE_VALUE && !CloseHandle (reference -> file )) {
531535 ok = false;
532536 }
533- #elif defined(__APPLE__ ) || defined(__linux__ )
537+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
534538 if (reference -> fd >= 0 && close (reference -> fd ) != 0 ) {
535539 ok = false;
536540 }
@@ -670,9 +674,9 @@ static bool runtime_mac_process_maps_file_executable(int process_id, const struc
670674 return false;
671675}
672676
673- #elif defined(__linux__ )
677+ #elif defined(__linux__ ) || defined( __FreeBSD__ )
674678
675- static bool runtime_linux_stat_same_image (const struct stat * first , const struct stat * second ) {
679+ static bool runtime_posix_stat_same_image (const struct stat * first , const struct stat * second ) {
676680 return first && second && S_ISREG (first -> st_mode ) && S_ISREG (second -> st_mode ) &&
677681 first -> st_dev == second -> st_dev && first -> st_ino == second -> st_ino &&
678682 first -> st_size == second -> st_size && first -> st_mtim .tv_sec == second -> st_mtim .tv_sec &&
@@ -788,11 +792,11 @@ static bool runtime_process_image_reference_acquire(
788792 (!fingerprint ||
789793 cbm_daemon_build_fingerprint_native_file ((uintptr_t )image_fd , fingerprint )) &&
790794 fstat (image_fd , & image_after ) == 0 &&
791- runtime_linux_stat_same_image (& image_before , & image_after );
795+ runtime_posix_stat_same_image (& image_before , & image_after );
792796 int verify_fd = ok ? openat (process_fd , "exe" , O_RDONLY | O_CLOEXEC ) : -1 ;
793797 struct stat verify_status ;
794798 ok = ok && verify_fd >= 0 && fstat (verify_fd , & verify_status ) == 0 &&
795- runtime_linux_stat_same_image (& image_after , & verify_status );
799+ runtime_posix_stat_same_image (& image_after , & verify_status );
796800 if (verify_fd >= 0 && close (verify_fd ) != 0 ) {
797801 ok = false;
798802 }
@@ -806,6 +810,33 @@ static bool runtime_process_image_reference_acquire(
806810 } else if (image_fd >= 0 ) {
807811 (void )close (image_fd );
808812 }
813+ #elif defined(__FreeBSD__ )
814+ if (process_id > INT_MAX ) {
815+ return false;
816+ }
817+ int pid = (int )process_id ;
818+ int mib [4 ] = {CTL_KERN , KERN_PROC , KERN_PROC_PATHNAME , pid };
819+ char path [PATH_MAX ];
820+ size_t path_length = sizeof (path );
821+ bool ok = sysctl (mib , 4 , path , & path_length , NULL , 0 ) == 0 && path_length > 0 ;
822+ if (ok ) {
823+ path [path_length < sizeof (path ) ? path_length : sizeof (path ) - 1 ] = '\0' ;
824+ }
825+ int image_fd = ok ? open (path , O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK ) : -1 ;
826+ struct stat image_before ;
827+ struct stat image_after ;
828+ ok = image_fd >= 0 && fstat (image_fd , & image_before ) == 0 && S_ISREG (image_before .st_mode ) &&
829+ (!fingerprint ||
830+ cbm_daemon_build_fingerprint_native_file ((uintptr_t )image_fd , fingerprint )) &&
831+ fstat (image_fd , & image_after ) == 0 &&
832+ runtime_posix_stat_same_image (& image_before , & image_after );
833+ if (ok ) {
834+ reference -> held = true;
835+ reference -> fd = image_fd ;
836+ reference -> status = image_after ;
837+ } else if (image_fd >= 0 ) {
838+ (void )close (image_fd );
839+ }
809840#else
810841 (void )process_id ;
811842 bool ok = false;
@@ -846,14 +877,14 @@ static bool runtime_process_image_reference_matches_process(
846877 runtime_mac_stat_same (& active -> status , & peer .status );
847878 bool released = runtime_process_image_reference_release (& peer );
848879 return same && released ;
849- #elif defined(__linux__ )
880+ #elif defined(__linux__ ) || defined( __FreeBSD__ )
850881 runtime_process_image_reference_t peer ;
851882 runtime_process_image_reference_init (& peer );
852883 bool same = runtime_process_image_reference_acquire (process_id , & peer , NULL );
853884 struct stat active_now ;
854885 same = same && fstat (active -> fd , & active_now ) == 0 &&
855- runtime_linux_stat_same_image (& active -> status , & active_now ) &&
856- runtime_linux_stat_same_image (& active -> status , & peer .status );
886+ runtime_posix_stat_same_image (& active -> status , & active_now ) &&
887+ runtime_posix_stat_same_image (& active -> status , & peer .status );
857888 bool released = runtime_process_image_reference_release (& peer );
858889 return same && released ;
859890#else
0 commit comments