@@ -50,10 +50,14 @@ void cbm_daemon_runtime_force_peer_image_mismatch_for_testing(bool force) {
5050#include <sys/proc_info.h>
5151#include <sys/stat.h>
5252#include <unistd.h>
53- #elif defined(__linux__ )
53+ #elif defined(__linux__ ) || defined( __FreeBSD__ )
5454#include <fcntl.h>
5555#include <sys/stat.h>
5656#include <unistd.h>
57+ #if defined(__FreeBSD__ )
58+ #include <sys/types.h>
59+ #include <sys/sysctl.h>
60+ #endif
5761#endif
5862
5963enum {
@@ -155,7 +159,7 @@ typedef struct {
155159 HANDLE file ;
156160 BY_HANDLE_FILE_INFORMATION information ;
157161 LARGE_INTEGER size ;
158- #elif defined(__APPLE__ ) || defined(__linux__ )
162+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
159163 int fd ;
160164 struct stat status ;
161165#endif
@@ -510,7 +514,7 @@ static bool runtime_activation_response_decode(
510514static uint64_t runtime_current_process_id (void ) {
511515#ifdef _WIN32
512516 return (uint64_t )GetCurrentProcessId ();
513- #elif defined(__APPLE__ ) || defined(__linux__ )
517+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
514518 return (uint64_t )getpid ();
515519#else
516520 return 0 ;
@@ -524,7 +528,7 @@ static void runtime_process_image_reference_init(runtime_process_image_reference
524528 memset (reference , 0 , sizeof (* reference ));
525529#ifdef _WIN32
526530 reference -> file = INVALID_HANDLE_VALUE ;
527- #elif defined(__APPLE__ ) || defined(__linux__ )
531+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
528532 reference -> fd = -1 ;
529533#endif
530534}
@@ -538,7 +542,7 @@ static bool runtime_process_image_reference_release(runtime_process_image_refere
538542 if (reference -> file != INVALID_HANDLE_VALUE && !CloseHandle (reference -> file )) {
539543 ok = false;
540544 }
541- #elif defined(__APPLE__ ) || defined(__linux__ )
545+ #elif defined(__APPLE__ ) || defined(__linux__ ) || defined( __FreeBSD__ )
542546 if (reference -> fd >= 0 && close (reference -> fd ) != 0 ) {
543547 ok = false;
544548 }
@@ -678,9 +682,9 @@ static bool runtime_mac_process_maps_file_executable(int process_id, const struc
678682 return false;
679683}
680684
681- #elif defined(__linux__ )
685+ #elif defined(__linux__ ) || defined( __FreeBSD__ )
682686
683- static bool runtime_linux_stat_same_image (const struct stat * first , const struct stat * second ) {
687+ static bool runtime_posix_stat_same_image (const struct stat * first , const struct stat * second ) {
684688 return first && second && S_ISREG (first -> st_mode ) && S_ISREG (second -> st_mode ) &&
685689 first -> st_dev == second -> st_dev && first -> st_ino == second -> st_ino &&
686690 first -> st_size == second -> st_size && first -> st_mtim .tv_sec == second -> st_mtim .tv_sec &&
@@ -796,11 +800,11 @@ static bool runtime_process_image_reference_acquire(
796800 (!fingerprint ||
797801 cbm_daemon_build_fingerprint_native_file ((uintptr_t )image_fd , fingerprint )) &&
798802 fstat (image_fd , & image_after ) == 0 &&
799- runtime_linux_stat_same_image (& image_before , & image_after );
803+ runtime_posix_stat_same_image (& image_before , & image_after );
800804 int verify_fd = ok ? openat (process_fd , "exe" , O_RDONLY | O_CLOEXEC ) : -1 ;
801805 struct stat verify_status ;
802806 ok = ok && verify_fd >= 0 && fstat (verify_fd , & verify_status ) == 0 &&
803- runtime_linux_stat_same_image (& image_after , & verify_status );
807+ runtime_posix_stat_same_image (& image_after , & verify_status );
804808 if (verify_fd >= 0 && close (verify_fd ) != 0 ) {
805809 ok = false;
806810 }
@@ -814,6 +818,33 @@ static bool runtime_process_image_reference_acquire(
814818 } else if (image_fd >= 0 ) {
815819 (void )close (image_fd );
816820 }
821+ #elif defined(__FreeBSD__ )
822+ if (process_id > INT_MAX ) {
823+ return false;
824+ }
825+ int pid = (int )process_id ;
826+ int mib [4 ] = {CTL_KERN , KERN_PROC , KERN_PROC_PATHNAME , pid };
827+ char path [PATH_MAX ];
828+ size_t path_length = sizeof (path );
829+ bool ok = sysctl (mib , 4 , path , & path_length , NULL , 0 ) == 0 && path_length > 0 ;
830+ if (ok ) {
831+ path [path_length < sizeof (path ) ? path_length : sizeof (path ) - 1 ] = '\0' ;
832+ }
833+ int image_fd = ok ? open (path , O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK ) : -1 ;
834+ struct stat image_before ;
835+ struct stat image_after ;
836+ ok = image_fd >= 0 && fstat (image_fd , & image_before ) == 0 && S_ISREG (image_before .st_mode ) &&
837+ (!fingerprint ||
838+ cbm_daemon_build_fingerprint_native_file ((uintptr_t )image_fd , fingerprint )) &&
839+ fstat (image_fd , & image_after ) == 0 &&
840+ runtime_posix_stat_same_image (& image_before , & image_after );
841+ if (ok ) {
842+ reference -> held = true;
843+ reference -> fd = image_fd ;
844+ reference -> status = image_after ;
845+ } else if (image_fd >= 0 ) {
846+ (void )close (image_fd );
847+ }
817848#else
818849 (void )process_id ;
819850 bool ok = false;
@@ -854,14 +885,14 @@ static bool runtime_process_image_reference_matches_process(
854885 runtime_mac_stat_same (& active -> status , & peer .status );
855886 bool released = runtime_process_image_reference_release (& peer );
856887 return same && released ;
857- #elif defined(__linux__ )
888+ #elif defined(__linux__ ) || defined( __FreeBSD__ )
858889 runtime_process_image_reference_t peer ;
859890 runtime_process_image_reference_init (& peer );
860891 bool same = runtime_process_image_reference_acquire (process_id , & peer , NULL );
861892 struct stat active_now ;
862893 same = same && fstat (active -> fd , & active_now ) == 0 &&
863- runtime_linux_stat_same_image (& active -> status , & active_now ) &&
864- runtime_linux_stat_same_image (& active -> status , & peer .status );
894+ runtime_posix_stat_same_image (& active -> status , & active_now ) &&
895+ runtime_posix_stat_same_image (& active -> status , & peer .status );
865896 bool released = runtime_process_image_reference_release (& peer );
866897 return same && released ;
867898#else
0 commit comments