@@ -79,9 +79,33 @@ pub fn available_memory_bytes() -> Option<u128> {
7979
8080/// Get the total number of bytes of physical memory on macOS.
8181///
82- /// Uses the `sysctl` command to query `hw.memsize`.
82+ /// Uses native `sysctl` syscall to query `hw.memsize`, with subprocess fallback .
8383#[ cfg( target_os = "macos" ) ]
8484fn total_physical_memory ( ) -> Result < u128 , SystemError > {
85+ use std:: mem;
86+ use std:: ptr;
87+
88+ // Try native sysctl syscall first (more reliable in restricted environments)
89+ let mut size: u64 = 0 ;
90+ let mut len = mem:: size_of :: < u64 > ( ) ;
91+ let mut mib = [ libc:: CTL_HW , libc:: HW_MEMSIZE ] ;
92+
93+ let result = unsafe {
94+ libc:: sysctl (
95+ mib. as_mut_ptr ( ) ,
96+ 2 ,
97+ & mut size as * mut _ as * mut libc:: c_void ,
98+ & mut len,
99+ ptr:: null_mut ( ) ,
100+ 0 ,
101+ )
102+ } ;
103+
104+ if result == 0 {
105+ return Ok ( size as u128 ) ;
106+ }
107+
108+ // Fallback to subprocess if native call fails
85109 let output = std:: process:: Command :: new ( "sysctl" )
86110 . arg ( "-n" )
87111 . arg ( "hw.memsize" )
@@ -94,9 +118,36 @@ fn total_physical_memory() -> Result<u128, SystemError> {
94118
95119/// Get the total number of bytes of physical memory on FreeBSD.
96120///
97- /// Uses the `sysctl` command to query `hw.physmem`.
121+ /// Uses native `sysctl` syscall to query `hw.physmem`, with subprocess fallback .
98122#[ cfg( target_os = "freebsd" ) ]
99123fn total_physical_memory ( ) -> Result < u128 , SystemError > {
124+ use std:: mem;
125+ use std:: ptr;
126+
127+ // HW_PHYSMEM constant (not always exported by libc)
128+ const HW_PHYSMEM : libc:: c_int = 5 ;
129+
130+ // Try native sysctl syscall first (more reliable in restricted environments)
131+ let mut size: u64 = 0 ;
132+ let mut len = mem:: size_of :: < u64 > ( ) ;
133+ let mut mib = [ libc:: CTL_HW , HW_PHYSMEM ] ;
134+
135+ let result = unsafe {
136+ libc:: sysctl (
137+ mib. as_mut_ptr ( ) ,
138+ 2 ,
139+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
140+ & mut len,
141+ ptr:: null_mut ( ) ,
142+ 0 ,
143+ )
144+ } ;
145+
146+ if result == 0 {
147+ return Ok ( size as u128 ) ;
148+ }
149+
150+ // Fallback to subprocess if native call fails
100151 let output = std:: process:: Command :: new ( "sysctl" )
101152 . arg ( "-n" )
102153 . arg ( "hw.physmem" )
@@ -109,9 +160,36 @@ fn total_physical_memory() -> Result<u128, SystemError> {
109160
110161/// Get the total number of bytes of physical memory on OpenBSD.
111162///
112- /// Uses the `sysctl` command to query `hw.physmem`.
163+ /// Uses native `sysctl` syscall to query `hw.physmem`, with subprocess fallback .
113164#[ cfg( target_os = "openbsd" ) ]
114165fn total_physical_memory ( ) -> Result < u128 , SystemError > {
166+ use std:: mem;
167+ use std:: ptr;
168+
169+ // HW_PHYSMEM constant (not always exported by libc)
170+ const HW_PHYSMEM : libc:: c_int = 19 ;
171+
172+ // Try native sysctl syscall first (more reliable in restricted environments)
173+ let mut size: u64 = 0 ;
174+ let mut len = mem:: size_of :: < u64 > ( ) ;
175+ let mut mib = [ libc:: CTL_HW , HW_PHYSMEM ] ;
176+
177+ let result = unsafe {
178+ libc:: sysctl (
179+ mib. as_mut_ptr ( ) ,
180+ 2 ,
181+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
182+ & mut len,
183+ ptr:: null_mut ( ) ,
184+ 0 ,
185+ )
186+ } ;
187+
188+ if result == 0 {
189+ return Ok ( size as u128 ) ;
190+ }
191+
192+ // Fallback to subprocess if native call fails
115193 let output = std:: process:: Command :: new ( "sysctl" )
116194 . arg ( "-n" )
117195 . arg ( "hw.physmem" )
@@ -124,9 +202,36 @@ fn total_physical_memory() -> Result<u128, SystemError> {
124202
125203/// Get the total number of bytes of physical memory on NetBSD.
126204///
127- /// Uses the `sysctl` command to query `hw.physmem64`.
205+ /// Uses native `sysctl` syscall to query `hw.physmem64`, with subprocess fallback .
128206#[ cfg( target_os = "netbsd" ) ]
129207fn total_physical_memory ( ) -> Result < u128 , SystemError > {
208+ use std:: mem;
209+ use std:: ptr;
210+
211+ // HW_PHYSMEM64 constant (not always exported by libc)
212+ const HW_PHYSMEM64 : libc:: c_int = 9 ;
213+
214+ // Try native sysctl syscall first (more reliable in restricted environments)
215+ let mut size: u64 = 0 ;
216+ let mut len = mem:: size_of :: < u64 > ( ) ;
217+ let mut mib = [ libc:: CTL_HW , HW_PHYSMEM64 ] ;
218+
219+ let result = unsafe {
220+ libc:: sysctl (
221+ mib. as_mut_ptr ( ) ,
222+ 2 ,
223+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
224+ & mut len,
225+ ptr:: null_mut ( ) ,
226+ 0 ,
227+ )
228+ } ;
229+
230+ if result == 0 {
231+ return Ok ( size as u128 ) ;
232+ }
233+
234+ // Fallback to subprocess if native call fails
130235 let output = std:: process:: Command :: new ( "sysctl" )
131236 . arg ( "-n" )
132237 . arg ( "hw.physmem64" )
0 commit comments