@@ -79,9 +79,34 @@ 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 nix:: libc;
86+ use std:: mem;
87+ use std:: ptr;
88+
89+ // Try native sysctl syscall first (more reliable in restricted environments)
90+ let mut size: u64 = 0 ;
91+ let mut len = mem:: size_of :: < u64 > ( ) ;
92+ let mut mib = [ libc:: CTL_HW , libc:: HW_MEMSIZE ] ;
93+
94+ let result = unsafe {
95+ libc:: sysctl (
96+ mib. as_mut_ptr ( ) ,
97+ 2 ,
98+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
99+ & mut len,
100+ ptr:: null_mut ( ) ,
101+ 0 ,
102+ )
103+ } ;
104+
105+ if result == 0 {
106+ return Ok ( size as u128 ) ;
107+ }
108+
109+ // Fallback to subprocess if native call fails
85110 let output = std:: process:: Command :: new ( "sysctl" )
86111 . arg ( "-n" )
87112 . arg ( "hw.memsize" )
@@ -94,9 +119,37 @@ fn total_physical_memory() -> Result<u128, SystemError> {
94119
95120/// Get the total number of bytes of physical memory on FreeBSD.
96121///
97- /// Uses the `sysctl` command to query `hw.physmem`.
122+ /// Uses native `sysctl` syscall to query `hw.physmem`, with subprocess fallback .
98123#[ cfg( target_os = "freebsd" ) ]
99124fn total_physical_memory ( ) -> Result < u128 , SystemError > {
125+ use nix:: libc;
126+ use std:: mem;
127+ use std:: ptr;
128+
129+ // HW_PHYSMEM constant (not always exported by libc)
130+ const HW_PHYSMEM : libc:: c_int = 5 ;
131+
132+ // Try native sysctl syscall first (more reliable in restricted environments)
133+ let mut size: u64 = 0 ;
134+ let mut len = mem:: size_of :: < u64 > ( ) ;
135+ let mut mib = [ libc:: CTL_HW , HW_PHYSMEM ] ;
136+
137+ let result = unsafe {
138+ libc:: sysctl (
139+ mib. as_mut_ptr ( ) ,
140+ 2 ,
141+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
142+ & mut len,
143+ ptr:: null_mut ( ) ,
144+ 0 ,
145+ )
146+ } ;
147+
148+ if result == 0 {
149+ return Ok ( size as u128 ) ;
150+ }
151+
152+ // Fallback to subprocess if native call fails
100153 let output = std:: process:: Command :: new ( "sysctl" )
101154 . arg ( "-n" )
102155 . arg ( "hw.physmem" )
@@ -109,9 +162,37 @@ fn total_physical_memory() -> Result<u128, SystemError> {
109162
110163/// Get the total number of bytes of physical memory on OpenBSD.
111164///
112- /// Uses the `sysctl` command to query `hw.physmem`.
165+ /// Uses native `sysctl` syscall to query `hw.physmem`, with subprocess fallback .
113166#[ cfg( target_os = "openbsd" ) ]
114167fn total_physical_memory ( ) -> Result < u128 , SystemError > {
168+ use nix:: libc;
169+ use std:: mem;
170+ use std:: ptr;
171+
172+ // HW_PHYSMEM constant (not always exported by libc)
173+ const HW_PHYSMEM : libc:: c_int = 19 ;
174+
175+ // Try native sysctl syscall first (more reliable in restricted environments)
176+ let mut size: u64 = 0 ;
177+ let mut len = mem:: size_of :: < u64 > ( ) ;
178+ let mut mib = [ libc:: CTL_HW , HW_PHYSMEM ] ;
179+
180+ let result = unsafe {
181+ libc:: sysctl (
182+ mib. as_mut_ptr ( ) ,
183+ 2 ,
184+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
185+ & mut len,
186+ ptr:: null_mut ( ) ,
187+ 0 ,
188+ )
189+ } ;
190+
191+ if result == 0 {
192+ return Ok ( size as u128 ) ;
193+ }
194+
195+ // Fallback to subprocess if native call fails
115196 let output = std:: process:: Command :: new ( "sysctl" )
116197 . arg ( "-n" )
117198 . arg ( "hw.physmem" )
@@ -124,9 +205,37 @@ fn total_physical_memory() -> Result<u128, SystemError> {
124205
125206/// Get the total number of bytes of physical memory on NetBSD.
126207///
127- /// Uses the `sysctl` command to query `hw.physmem64`.
208+ /// Uses native `sysctl` syscall to query `hw.physmem64`, with subprocess fallback .
128209#[ cfg( target_os = "netbsd" ) ]
129210fn total_physical_memory ( ) -> Result < u128 , SystemError > {
211+ use nix:: libc;
212+ use std:: mem;
213+ use std:: ptr;
214+
215+ // HW_PHYSMEM64 constant (not always exported by libc)
216+ const HW_PHYSMEM64 : libc:: c_int = 9 ;
217+
218+ // Try native sysctl syscall first (more reliable in restricted environments)
219+ let mut size: u64 = 0 ;
220+ let mut len = mem:: size_of :: < u64 > ( ) ;
221+ let mut mib = [ libc:: CTL_HW , HW_PHYSMEM64 ] ;
222+
223+ let result = unsafe {
224+ libc:: sysctl (
225+ mib. as_mut_ptr ( ) ,
226+ 2 ,
227+ ptr:: from_mut ( & mut size) . cast :: < libc:: c_void > ( ) ,
228+ & mut len,
229+ ptr:: null_mut ( ) ,
230+ 0 ,
231+ )
232+ } ;
233+
234+ if result == 0 {
235+ return Ok ( size as u128 ) ;
236+ }
237+
238+ // Fallback to subprocess if native call fails
130239 let output = std:: process:: Command :: new ( "sysctl" )
131240 . arg ( "-n" )
132241 . arg ( "hw.physmem64" )
0 commit comments