55
66//! Thin zero-copy-related wrappers around functions.
77
8- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
8+ #![ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
9+
910use crate :: io:: { RawReader , RawWriter } ;
10- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
1111use rustix:: pipe:: { SpliceFlags , fcntl_setpipe_size} ;
12- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
1312use std:: {
14- fs:: File ,
1513 io:: { PipeReader , PipeWriter , Read , Write } ,
1614 os:: fd:: AsFd ,
1715 sync:: OnceLock ,
1816} ;
19- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
2017pub const MAX_ROOTLESS_PIPE_SIZE : usize = 1024 * 1024 ;
21- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
2218const KERNEL_DEFAULT_PIPE_SIZE : usize = 64 * 1024 ;
2319
2420/// return pipe larger than given size
@@ -27,7 +23,6 @@ const KERNEL_DEFAULT_PIPE_SIZE: usize = 64 * 1024;
2723///
2824/// used for resolving the limitation for splice: one of a input or output should be pipe
2925#[ inline]
30- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
3126pub fn pipe < const SIZE_REQUIRED : bool > ( s : usize ) -> std:: io:: Result < ( PipeReader , PipeWriter ) > {
3227 let pair = std:: io:: pipe ( ) ?;
3328 // guard unnecessary syscall
@@ -51,7 +46,6 @@ pub fn pipe<const SIZE_REQUIRED: bool>(s: usize) -> std::io::Result<(PipeReader,
5146/// a [`pipe`] and then from the pipe into your target (with `splice_exact`):
5247/// this is still very efficient.
5348#[ inline]
54- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
5549pub fn splice ( source : & impl AsFd , target : & impl AsFd , len : usize ) -> rustix:: io:: Result < usize > {
5650 rustix:: pipe:: splice ( source, None , target, None , len, SpliceFlags :: empty ( ) )
5751}
@@ -62,7 +56,6 @@ pub fn splice(source: &impl AsFd, target: &impl AsFd, len: usize) -> rustix::io:
6256/// In the case failed relaying splice via pipe, all content of the pipe
6357/// should be drained by `read` to keep bytes sent accurate.
6458#[ inline]
65- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
6659pub fn splice_exact ( source : & impl AsFd , target : & impl AsFd , len : usize ) -> rustix:: io:: Result < ( ) > {
6760 let mut left = len;
6861 while left > 0 {
@@ -76,15 +69,13 @@ pub fn splice_exact(source: &impl AsFd, target: &impl AsFd, len: usize) -> rusti
7669/// check that source is FUSE
7770/// we fallback to read() at FUSE <https://github.com/uutils/coreutils/issues/9609>
7871#[ inline]
79- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
8072pub fn might_fuse ( source : & impl AsFd ) -> bool {
8173 rustix:: fs:: fstatfs ( source) . map_or ( true , |stats| stats. f_type == 0x6573_5546 ) // FUSE magic number, too many platform specific clippy warning with const
8274}
8375
8476/// splice all of source to dest
8577/// returns Ok(()) at end of file
8678#[ inline]
87- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
8879pub fn splice_unbounded ( source : & impl AsFd , dest : & mut impl AsFd ) -> rustix:: io:: Result < ( ) > {
8980 // avoid fcntl overhead for small input. splice twice to catch end of file.
9081 if splice ( & source, & dest, MAX_ROOTLESS_PIPE_SIZE ) ? == 0
@@ -108,7 +99,6 @@ pub fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> rustix::io:
10899/// Thus, ?.is_err() returns serious error at early stage and checks that you can fallback
109100/// This should not be used if one of them are pipe to save resources
110101#[ inline]
111- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
112102pub fn splice_unbounded_broker (
113103 source : & impl AsFd ,
114104 dest : & mut impl AsFd ,
@@ -153,7 +143,6 @@ pub fn splice_unbounded_broker(
153143/// return true if write fallback is needed
154144/// (the fallback will be embedded to this function in the future)
155145#[ inline]
156- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
157146pub fn splice_unbounded_auto ( source : & impl AsFd , dest : & mut impl AsFd ) -> std:: io:: Result < bool > {
158147 // use splice to check that input or output is pipe which is efficient
159148 let fallback = match splice ( & source, dest, MAX_ROOTLESS_PIPE_SIZE ) {
@@ -166,7 +155,6 @@ pub fn splice_unbounded_auto(source: &impl AsFd, dest: &mut impl AsFd) -> std::i
166155/// splice `n` bytes with safe read/write fallback
167156/// return actually sent bytes
168157#[ inline]
169- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
170158pub fn send_n_bytes ( input : impl AsFd , target : impl AsFd , n : u64 ) -> std:: io:: Result < u64 > {
171159 static PIPE_CACHE : OnceLock < Option < ( PipeReader , PipeWriter ) > > = OnceLock :: new ( ) ;
172160 let pipe_size = MAX_ROOTLESS_PIPE_SIZE . min ( n as usize ) ;
@@ -242,8 +230,7 @@ pub fn send_n_bytes(input: impl AsFd, target: impl AsFd, n: u64) -> std::io::Res
242230///
243231/// `splice` to /dev/null is faster than `read` when we skip or count the non-seekable input
244232#[ inline]
245- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
246- pub fn dev_null ( ) -> Option < File > {
233+ pub fn dev_null ( ) -> Option < std:: fs:: File > {
247234 let null = std:: fs:: OpenOptions :: new ( )
248235 . write ( true )
249236 . open ( "/dev/null" )
@@ -255,7 +242,6 @@ pub fn dev_null() -> Option<File> {
255242
256243// Less noisy wrapper around tee syscall
257244#[ inline]
258- #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
259245pub fn tee ( source : & impl AsFd , target : & impl AsFd , len : usize ) -> rustix:: io:: Result < usize > {
260246 rustix:: pipe:: tee ( source, target, len, SpliceFlags :: empty ( ) )
261247}
0 commit comments