1
- // Copyright (c) 2020-2024 MicroDoc Software GmbH.
1
+ // Copyright (c) 2020-2025 MicroDoc Software GmbH.
2
2
// See the "LICENSE.txt" file at the top-level directory of this distribution.
3
3
//
4
4
// Licensed under the MIT license. This file may not be copied, modified,
7
7
// TODO: https://rust-lang.github.io/api-guidelines/checklist.html
8
8
9
9
#![ 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 " ) ]
11
11
#![ warn(
12
12
unsafe_op_in_unsafe_fn,
13
13
missing_docs,
22
22
unused_import_braces,
23
23
unused_labels,
24
24
variant_size_differences,
25
- unused_qualifications,
25
+ unused_qualifications
26
+ ) ]
27
+ //#![warn(clippy::pedantic, clippy::restriction)]
28
+ #![ allow(
26
29
clippy:: alloc_instead_of_core,
27
30
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
29
50
) ]
30
- #![ allow( clippy:: upper_case_acronyms) ]
31
51
32
52
mod errors;
33
53
#[ cfg( test) ]
34
54
mod tests;
35
55
36
56
extern crate alloc;
37
57
38
- pub use errors:: * ;
58
+ use errors:: Result ;
59
+ pub use errors:: { Error , ErrorKind } ;
39
60
40
- use core:: convert:: TryFrom ;
41
61
use core:: ffi:: c_void;
62
+ use core:: num:: NonZero ;
42
63
use core:: { cmp, slice} ;
43
64
use std:: io:: { IoSlice , IoSliceMut , Read , Seek , SeekFrom , Write } ;
44
65
use std:: os:: raw:: c_ulong;
@@ -52,10 +73,11 @@ lazy_static! {
52
73
///
53
74
/// Failure to fetch the information will result in a size
54
75
/// of `u64::max_value()`.
55
- static ref MIN_SYSTEM_PAGE_SIZE : u64 =
76
+ static ref MIN_SYSTEM_PAGE_SIZE : NonZero < u64 > =
56
77
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 ) } ,
59
81
} ;
60
82
61
83
/// Maximum number of the `iovec` structures that can be provided to
@@ -70,9 +92,9 @@ lazy_static! {
70
92
}
71
93
72
94
/// 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 {
74
96
// Notice that the calculation below never causes an overflow.
75
- n & !( alignment - 1 )
97
+ n & !alignment. get ( ) . saturating_sub ( 1 )
76
98
}
77
99
78
100
/// Prototype of the APIs `process_vm_readv()` and `process_vm_writev()`.
@@ -116,13 +138,13 @@ impl PageAwareAddressRange {
116
138
let distance_to_preceeding_page_boundary =
117
139
start_address - align_down ( start_address, min_page_size) ;
118
140
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 ( ) ) ;
121
143
122
144
if inside_one_page {
123
145
// | -- distance_to_preceeding_page_boundary -- v ---- size ---- v |
124
146
// 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 ( ) {
126
148
Self {
127
149
start_address,
128
150
size_in_first_page : 0 ,
@@ -146,7 +168,7 @@ impl PageAwareAddressRange {
146
168
let size_in_first_page = if distance_to_preceeding_page_boundary == 0 {
147
169
0
148
170
} else {
149
- min_page_size - distance_to_preceeding_page_boundary
171
+ min_page_size. get ( ) - distance_to_preceeding_page_boundary
150
172
} ;
151
173
152
174
size -= size_in_first_page;
@@ -174,7 +196,7 @@ impl PageAwareAddressRange {
174
196
/// (if any) is also returned. Returning a vector of `iovec`s that covers
175
197
/// only a prefix of this address range is not considered a failure.
176
198
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 ( ) ;
178
200
let max_iov_count = * SYSTEM_IOV_MAX ;
179
201
let mut size_of_not_covered_suffix = 0 ;
180
202
@@ -238,7 +260,7 @@ impl PageAwareAddressRange {
238
260
result. push ( libc:: iovec {
239
261
iov_base : usize:: try_from ( self . start_address ) ? as * mut c_void ,
240
262
iov_len : usize:: try_from ( self . size_in_first_page ) ?,
241
- } )
263
+ } ) ;
242
264
}
243
265
244
266
let mut page_address = self . start_address . wrapping_add ( self . size_in_first_page ) ;
@@ -258,7 +280,7 @@ impl PageAwareAddressRange {
258
280
result. push ( libc:: iovec {
259
281
iov_base : usize:: try_from ( start_of_last_page) ? as * mut c_void ,
260
282
iov_len : usize:: try_from ( self . size_in_last_page ) ?,
261
- } )
283
+ } ) ;
262
284
}
263
285
Ok ( ( result, size_of_not_covered_suffix) )
264
286
}
@@ -329,6 +351,7 @@ impl ProcessVirtualMemoryIO {
329
351
}
330
352
331
353
/// Return the process identifier of the target process.
354
+ #[ must_use]
332
355
pub fn process_id ( & self ) -> u32 {
333
356
self . process_id as u32
334
357
}
@@ -390,11 +413,9 @@ impl ProcessVirtualMemoryIO {
390
413
) ) ;
391
414
}
392
415
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.
398
419
399
420
Ok ( transferred_bytes_count as usize )
400
421
}
@@ -422,18 +443,19 @@ impl Seek for ProcessVirtualMemoryIO {
422
443
address. checked_add ( forward)
423
444
}
424
445
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
430
448
let backward = n. wrapping_neg ( ) as u64 ;
431
449
Some ( ( u64:: MAX - backward) + 1 )
432
450
}
433
451
434
- ( Some ( address) , SeekFrom :: Current ( n) ) /* if n < 0 */ => {
452
+ ( Some ( address) , SeekFrom :: Current ( n) ) => {
453
+ // n < 0
435
454
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 ) ?
437
459
}
438
460
} ;
439
461
@@ -444,7 +466,7 @@ impl Seek for ProcessVirtualMemoryIO {
444
466
impl Read for ProcessVirtualMemoryIO {
445
467
fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
446
468
let local_io_vector = libc:: iovec {
447
- iov_base : buf. as_ptr ( ) as * mut c_void ,
469
+ iov_base : buf. as_mut_ptr ( ) . cast ( ) ,
448
470
iov_len : buf. len ( ) ,
449
471
} ;
450
472
@@ -454,8 +476,7 @@ impl Read for ProcessVirtualMemoryIO {
454
476
455
477
fn read_vectored ( & mut self , bufs : & mut [ IoSliceMut ] ) -> io:: Result < usize > {
456
478
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 ( ) ) } ;
459
480
460
481
self . io_vectored ( libc:: process_vm_readv, local_io_vectors, bytes_to_read)
461
482
. map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) )
@@ -479,8 +500,7 @@ impl Write for ProcessVirtualMemoryIO {
479
500
480
501
fn write_vectored ( & mut self , bufs : & [ IoSlice ] ) -> io:: Result < usize > {
481
502
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 ( ) ) } ;
484
504
485
505
self . io_vectored ( libc:: process_vm_writev, local_io_vectors, bytes_to_write)
486
506
. map_err ( |err| io:: Error :: new ( io:: ErrorKind :: Other , err) )
0 commit comments