1
1
//! Unix `pipe` wrapper for `LibAFL`
2
2
#[ cfg( feature = "std" ) ]
3
- use alloc:: rc:: Rc ;
4
- #[ cfg( feature = "std" ) ]
5
- use core:: { borrow:: Borrow , cell:: RefCell } ;
6
- #[ cfg( feature = "std" ) ]
7
3
use std:: {
8
- io:: { self , ErrorKind , Read , Write } ,
9
- os:: {
10
- fd:: { AsFd , AsRawFd , OwnedFd } ,
11
- unix:: io:: RawFd ,
12
- } ,
4
+ io:: { self , ErrorKind , PipeReader , PipeWriter , Read , Write } ,
5
+ os:: unix:: io:: RawFd ,
13
6
} ;
14
7
15
- #[ cfg( feature = "std" ) ]
16
- use nix:: unistd:: { pipe, read, write} ;
17
-
18
8
#[ cfg( feature = "std" ) ]
19
9
use crate :: Error ;
20
10
21
11
/// A unix pipe wrapper for `LibAFL`
22
12
#[ cfg( feature = "std" ) ]
23
- #[ derive( Debug , Clone ) ]
13
+ #[ derive( Debug ) ]
24
14
pub struct Pipe {
25
15
/// The read end of the pipe
26
- read_end : Option < Rc < RefCell < OwnedFd > > > ,
16
+ read_end : Option < PipeReader > ,
27
17
/// The write end of the pipe
28
- write_end : Option < Rc < RefCell < OwnedFd > > > ,
18
+ write_end : Option < PipeWriter > ,
19
+ }
20
+
21
+ #[ cfg( feature = "std" ) ]
22
+ impl Clone for Pipe {
23
+ fn clone ( & self ) -> Self {
24
+ // try_clone only fails if we run out of fds (dup2) so this should be rather safe
25
+ let read_end = self
26
+ . read_end
27
+ . as_ref ( )
28
+ . map ( PipeReader :: try_clone)
29
+ . transpose ( )
30
+ . expect ( "fail to clone read_end" ) ;
31
+ let write_end = self
32
+ . write_end
33
+ . as_ref ( )
34
+ . map ( PipeWriter :: try_clone)
35
+ . transpose ( )
36
+ . expect ( "fail to clone read_end" ) ;
37
+
38
+ Self {
39
+ read_end,
40
+ write_end,
41
+ }
42
+ }
29
43
}
30
44
31
45
#[ cfg( feature = "std" ) ]
32
46
impl Pipe {
33
47
/// Create a new `Unix` pipe
34
48
pub fn new ( ) -> Result < Self , Error > {
35
- let ( read_end, write_end) = pipe ( ) ?;
49
+ let ( read_end, write_end) = io :: pipe ( ) ?;
36
50
Ok ( Self {
37
- read_end : Some ( Rc :: new ( RefCell :: new ( read_end) ) ) ,
38
- write_end : Some ( Rc :: new ( RefCell :: new ( write_end) ) ) ,
51
+ read_end : Some ( read_end) ,
52
+ write_end : Some ( write_end) ,
39
53
} )
40
54
}
41
55
@@ -54,31 +68,22 @@ impl Pipe {
54
68
/// The read end
55
69
#[ must_use]
56
70
pub fn read_end ( & self ) -> Option < RawFd > {
57
- self . read_end . as_ref ( ) . map ( |fd| {
58
- let borrowed: & RefCell < OwnedFd > = fd. borrow ( ) ;
59
- borrowed. borrow ( ) . as_raw_fd ( )
60
- } )
71
+ self . read_end . as_ref ( ) . map ( std:: os:: fd:: AsRawFd :: as_raw_fd)
61
72
}
62
73
63
74
/// The write end
64
75
#[ must_use]
65
76
pub fn write_end ( & self ) -> Option < RawFd > {
66
- self . write_end . as_ref ( ) . map ( |fd| {
67
- let borrowed: & RefCell < OwnedFd > = fd. borrow ( ) ;
68
- borrowed. borrow ( ) . as_raw_fd ( )
69
- } )
77
+ self . write_end . as_ref ( ) . map ( std:: os:: fd:: AsRawFd :: as_raw_fd)
70
78
}
71
79
}
72
80
73
81
#[ cfg( feature = "std" ) ]
74
82
impl Read for Pipe {
75
83
/// Reads a few bytes
76
84
fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , io:: Error > {
77
- match self . read_end ( ) {
78
- Some ( read_end) => match read ( read_end, buf) {
79
- Ok ( res) => Ok ( res) ,
80
- Err ( e) => Err ( io:: Error :: from_raw_os_error ( e as i32 ) ) ,
81
- } ,
85
+ match self . read_end . as_mut ( ) {
86
+ Some ( read_end) => read_end. read ( buf) ,
82
87
None => Err ( io:: Error :: new (
83
88
ErrorKind :: BrokenPipe ,
84
89
"Read pipe end was already closed" ,
@@ -91,14 +96,8 @@ impl Read for Pipe {
91
96
impl Write for Pipe {
92
97
/// Writes a few bytes
93
98
fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize , io:: Error > {
94
- match self . write_end . as_ref ( ) {
95
- Some ( write_end) => {
96
- let borrowed: & RefCell < OwnedFd > = write_end;
97
- match write ( ( * borrowed) . borrow ( ) . as_fd ( ) , buf) {
98
- Ok ( res) => Ok ( res) ,
99
- Err ( e) => Err ( io:: Error :: from_raw_os_error ( e as i32 ) ) ,
100
- }
101
- }
99
+ match self . write_end . as_mut ( ) {
100
+ Some ( write_end) => Ok ( write_end. write ( buf) ?) ,
102
101
None => Err ( io:: Error :: new (
103
102
ErrorKind :: BrokenPipe ,
104
103
"Write pipe end was already closed" ,
0 commit comments