1- // Copyright (c) 2020-2024 MicroDoc Software GmbH.
1+ // Copyright (c) 2020-2025 MicroDoc Software GmbH.
22// See the "LICENSE.txt" file at the top-level directory of this distribution.
33//
44// Licensed under the MIT license. This file may not be copied, modified,
77// TODO: https://rust-lang.github.io/api-guidelines/checklist.html
88
99#![ doc = include_str ! ( "../README.md" ) ]
10- #![ doc( html_root_url = "https://docs.rs/process_vm_io/1.0.11 " ) ]
10+ #![ doc( html_root_url = "https://docs.rs/process_vm_io/1.0.12 " ) ]
1111#![ warn(
1212 unsafe_op_in_unsafe_fn,
1313 missing_docs,
2222 unused_import_braces,
2323 unused_labels,
2424 variant_size_differences,
25- unused_qualifications,
25+ unused_qualifications
26+ ) ]
27+ //#![warn(clippy::pedantic, clippy::restriction)]
28+ #![ allow(
2629 clippy:: alloc_instead_of_core,
2730 clippy:: std_instead_of_core,
28- clippy:: std_instead_of_alloc
31+ clippy:: std_instead_of_alloc,
32+ clippy:: upper_case_acronyms,
33+ clippy:: arbitrary_source_item_ordering,
34+ clippy:: single_call_fn,
35+ clippy:: pub_use,
36+ clippy:: missing_docs_in_private_items,
37+ clippy:: implicit_return,
38+ clippy:: unwrap_used,
39+ clippy:: separated_literal_suffix,
40+ clippy:: absolute_paths,
41+ clippy:: assertions_on_result_states,
42+ clippy:: undocumented_unsafe_blocks,
43+ clippy:: unwrap_in_result,
44+ clippy:: missing_inline_in_public_items,
45+ clippy:: missing_trait_methods,
46+ clippy:: question_mark_used,
47+ clippy:: else_if_without_else,
48+ clippy:: shadow_reuse,
49+ clippy:: default_numeric_fallback
2950) ]
30- #![ allow( clippy:: upper_case_acronyms) ]
3151
3252mod errors;
3353#[ cfg( test) ]
3454mod tests;
3555
3656extern crate alloc;
3757
38- pub use errors:: * ;
58+ use errors:: Result ;
59+ pub use errors:: { Error , ErrorKind } ;
3960
40- use core:: convert:: TryFrom ;
4161use core:: ffi:: c_void;
62+ use core:: num:: NonZero ;
4263use core:: { cmp, slice} ;
4364use std:: io:: { IoSlice , IoSliceMut , Read , Seek , SeekFrom , Write } ;
4465use std:: os:: raw:: c_ulong;
@@ -52,10 +73,11 @@ lazy_static! {
5273 ///
5374 /// Failure to fetch the information will result in a size
5475 /// of `u64::max_value()`.
55- static ref MIN_SYSTEM_PAGE_SIZE : u64 =
76+ static ref MIN_SYSTEM_PAGE_SIZE : NonZero < u64 > =
5677 match unsafe { libc:: sysconf( libc:: _SC_PAGE_SIZE) } {
57- -1 => u64 :: MAX ,
58- result => result as u64 ,
78+ -1 => NonZero :: <u64 >:: MAX ,
79+ 0 => unsafe { NonZero :: <u64 >:: new_unchecked( 4096 ) } ,
80+ result => unsafe { NonZero :: <u64 >:: new_unchecked( result as u64 ) } ,
5981 } ;
6082
6183 /// Maximum number of the `iovec` structures that can be provided to
@@ -70,9 +92,9 @@ lazy_static! {
7092}
7193
7294/// Align a given number down to a specified alignment boundary.
73- const fn align_down ( n : u64 , alignment : u64 ) -> u64 {
95+ const fn align_down ( n : u64 , alignment : NonZero < u64 > ) -> u64 {
7496 // Notice that the calculation below never causes an overflow.
75- n & !( alignment - 1 )
97+ n & !alignment. get ( ) . saturating_sub ( 1 )
7698}
7799
78100/// Prototype of the APIs `process_vm_readv()` and `process_vm_writev()`.
@@ -116,13 +138,13 @@ impl PageAwareAddressRange {
116138 let distance_to_preceeding_page_boundary =
117139 start_address - align_down ( start_address, min_page_size) ;
118140
119- let inside_one_page = ( size <= min_page_size)
120- && ( ( distance_to_preceeding_page_boundary + size) <= min_page_size) ;
141+ let inside_one_page = ( size <= min_page_size. get ( ) )
142+ && ( ( distance_to_preceeding_page_boundary + size) <= min_page_size. get ( ) ) ;
121143
122144 if inside_one_page {
123145 // | -- distance_to_preceeding_page_boundary -- v ---- size ---- v |
124146 // preceeding_page_boundary --> start_address --> end_address --> next_page_boundary
125- return if distance_to_preceeding_page_boundary == 0 && size == min_page_size {
147+ return if distance_to_preceeding_page_boundary == 0 && size == min_page_size. get ( ) {
126148 Self {
127149 start_address,
128150 size_in_first_page : 0 ,
@@ -146,7 +168,7 @@ impl PageAwareAddressRange {
146168 let size_in_first_page = if distance_to_preceeding_page_boundary == 0 {
147169 0
148170 } else {
149- min_page_size - distance_to_preceeding_page_boundary
171+ min_page_size. get ( ) - distance_to_preceeding_page_boundary
150172 } ;
151173
152174 size -= size_in_first_page;
@@ -174,7 +196,7 @@ impl PageAwareAddressRange {
174196 /// (if any) is also returned. Returning a vector of `iovec`s that covers
175197 /// only a prefix of this address range is not considered a failure.
176198 fn into_iov_buffers ( mut self ) -> Result < ( SmallVec < [ libc:: iovec ; 3 ] > , u64 ) > {
177- let min_page_size = * MIN_SYSTEM_PAGE_SIZE ;
199+ let min_page_size = MIN_SYSTEM_PAGE_SIZE . get ( ) ;
178200 let max_iov_count = * SYSTEM_IOV_MAX ;
179201 let mut size_of_not_covered_suffix = 0 ;
180202
@@ -238,7 +260,7 @@ impl PageAwareAddressRange {
238260 result. push ( libc:: iovec {
239261 iov_base : usize:: try_from ( self . start_address ) ? as * mut c_void ,
240262 iov_len : usize:: try_from ( self . size_in_first_page ) ?,
241- } )
263+ } ) ;
242264 }
243265
244266 let mut page_address = self . start_address . wrapping_add ( self . size_in_first_page ) ;
@@ -258,7 +280,7 @@ impl PageAwareAddressRange {
258280 result. push ( libc:: iovec {
259281 iov_base : usize:: try_from ( start_of_last_page) ? as * mut c_void ,
260282 iov_len : usize:: try_from ( self . size_in_last_page ) ?,
261- } )
283+ } ) ;
262284 }
263285 Ok ( ( result, size_of_not_covered_suffix) )
264286 }
@@ -329,6 +351,7 @@ impl ProcessVirtualMemoryIO {
329351 }
330352
331353 /// Return the process identifier of the target process.
354+ #[ must_use]
332355 pub fn process_id ( & self ) -> u32 {
333356 self . process_id as u32
334357 }
@@ -390,11 +413,9 @@ impl ProcessVirtualMemoryIO {
390413 ) ) ;
391414 }
392415
393- self . address = if ( transferred_bytes_count as u64 ) < max_remaining_bytes {
394- Some ( address + ( transferred_bytes_count as u64 ) )
395- } else {
396- None // End of file (actually, address space).
397- } ;
416+ self . address = ( ( transferred_bytes_count as u64 ) < max_remaining_bytes)
417+ . then_some ( address + ( transferred_bytes_count as u64 ) ) ;
418+ // If self.address is None, then we reached the end of address space.
398419
399420 Ok ( transferred_bytes_count as usize )
400421 }
@@ -422,18 +443,19 @@ impl Seek for ProcessVirtualMemoryIO {
422443 address. checked_add ( forward)
423444 }
424445
425- ( None , SeekFrom :: Current ( n) ) /* if n < 0 */ => {
426- let backward = n. wrapping_neg ( ) as u64 ;
427- Some ( ( u64:: MAX - backward) + 1 )
428- }
429- ( _, SeekFrom :: End ( n) ) /* if n < 0 */ => {
446+ ( None , SeekFrom :: Current ( n) ) | ( _, SeekFrom :: End ( n) ) => {
447+ // n < 0
430448 let backward = n. wrapping_neg ( ) as u64 ;
431449 Some ( ( u64:: MAX - backward) + 1 )
432450 }
433451
434- ( Some ( address) , SeekFrom :: Current ( n) ) /* if n < 0 */ => {
452+ ( Some ( address) , SeekFrom :: Current ( n) ) => {
453+ // n < 0
435454 let backward = n. wrapping_neg ( ) as u64 ;
436- address. checked_sub ( backward) . ok_or_else ( || io:: Error :: from ( io:: ErrorKind :: InvalidInput ) ) . map ( Some ) ?
455+ address
456+ . checked_sub ( backward)
457+ . ok_or_else ( || io:: Error :: from ( io:: ErrorKind :: InvalidInput ) )
458+ . map ( Some ) ?
437459 }
438460 } ;
439461
@@ -444,7 +466,7 @@ impl Seek for ProcessVirtualMemoryIO {
444466impl Read for ProcessVirtualMemoryIO {
445467 fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
446468 let local_io_vector = libc:: iovec {
447- iov_base : buf. as_ptr ( ) as * mut c_void ,
469+ iov_base : buf. as_mut_ptr ( ) . cast ( ) ,
448470 iov_len : buf. len ( ) ,
449471 } ;
450472
@@ -454,8 +476,7 @@ impl Read for ProcessVirtualMemoryIO {
454476
455477 fn read_vectored ( & mut self , bufs : & mut [ IoSliceMut ] ) -> io:: Result < usize > {
456478 let bytes_to_read = bufs. iter ( ) . map ( |buf| buf. len ( ) as u64 ) . sum ( ) ;
457- let local_io_vectors =
458- unsafe { slice:: from_raw_parts ( bufs. as_ptr ( ) as * const _ , bufs. len ( ) ) } ;
479+ let local_io_vectors = unsafe { slice:: from_raw_parts ( bufs. as_ptr ( ) . cast ( ) , bufs. len ( ) ) } ;
459480
460481 self . io_vectored ( libc:: process_vm_readv, local_io_vectors, bytes_to_read)
461482 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) )
@@ -479,8 +500,7 @@ impl Write for ProcessVirtualMemoryIO {
479500
480501 fn write_vectored ( & mut self , bufs : & [ IoSlice ] ) -> io:: Result < usize > {
481502 let bytes_to_write = bufs. iter ( ) . map ( |buf| buf. len ( ) as u64 ) . sum ( ) ;
482- let local_io_vectors =
483- unsafe { slice:: from_raw_parts ( bufs. as_ptr ( ) as * const _ , bufs. len ( ) ) } ;
503+ let local_io_vectors = unsafe { slice:: from_raw_parts ( bufs. as_ptr ( ) . cast ( ) , bufs. len ( ) ) } ;
484504
485505 self . io_vectored ( libc:: process_vm_writev, local_io_vectors, bytes_to_write)
486506 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) )
0 commit comments