1- use crate :: io:: { Error as IoError , Result as IoResult } ;
1+ use crate :: cmp;
2+ use crate :: io:: { Error as IoError , Result as IoResult , IoSlice , IoSliceMut } ;
23use crate :: time:: Duration ;
34
45pub ( crate ) mod alloc;
@@ -8,13 +9,27 @@ pub(crate) mod raw;
89use self :: raw:: * ;
910
1011/// Usercall `read`. See the ABI documentation for more information.
12+ ///
13+ /// This will do a single `read` usercall and scatter the read data among
14+ /// `bufs`. To read to a single buffer, just pass a slice of length one.
1115#[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
12- pub fn read ( fd : Fd , buf : & mut [ u8 ] ) -> IoResult < usize > {
16+ pub fn read ( fd : Fd , bufs : & mut [ IoSliceMut < ' _ > ] ) -> IoResult < usize > {
1317 unsafe {
14- let mut userbuf = alloc:: User :: < [ u8 ] > :: uninitialized ( buf. len ( ) ) ;
15- let len = raw:: read ( fd, userbuf. as_mut_ptr ( ) , userbuf. len ( ) ) . from_sgx_result ( ) ?;
16- userbuf[ ..len] . copy_to_enclave ( & mut buf[ ..len] ) ;
17- Ok ( len)
18+ let total_len = bufs. iter ( ) . fold ( 0usize , |sum, buf| sum. saturating_add ( buf. len ( ) ) ) ;
19+ let mut userbuf = alloc:: User :: < [ u8 ] > :: uninitialized ( total_len) ;
20+ let ret_len = raw:: read ( fd, userbuf. as_mut_ptr ( ) , userbuf. len ( ) ) . from_sgx_result ( ) ?;
21+ let userbuf = & userbuf[ ..ret_len] ;
22+ let mut index = 0 ;
23+ for buf in bufs {
24+ let end = cmp:: min ( index + buf. len ( ) , userbuf. len ( ) ) ;
25+ if let Some ( buflen) = end. checked_sub ( index) {
26+ userbuf[ index..end] . copy_to_enclave ( & mut buf[ ..buflen] ) ;
27+ index += buf. len ( ) ;
28+ } else {
29+ break
30+ }
31+ }
32+ Ok ( userbuf. len ( ) )
1833 }
1934}
2035
@@ -30,10 +45,24 @@ pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
3045}
3146
3247/// Usercall `write`. See the ABI documentation for more information.
48+ ///
49+ /// This will do a single `write` usercall and gather the written data from
50+ /// `bufs`. To write from a single buffer, just pass a slice of length one.
3351#[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
34- pub fn write ( fd : Fd , buf : & [ u8 ] ) -> IoResult < usize > {
52+ pub fn write ( fd : Fd , bufs : & [ IoSlice < ' _ > ] ) -> IoResult < usize > {
3553 unsafe {
36- let userbuf = alloc:: User :: new_from_enclave ( buf) ;
54+ let total_len = bufs. iter ( ) . fold ( 0usize , |sum, buf| sum. saturating_add ( buf. len ( ) ) ) ;
55+ let mut userbuf = alloc:: User :: < [ u8 ] > :: uninitialized ( total_len) ;
56+ let mut index = 0 ;
57+ for buf in bufs {
58+ let end = cmp:: min ( index + buf. len ( ) , userbuf. len ( ) ) ;
59+ if let Some ( buflen) = end. checked_sub ( index) {
60+ userbuf[ index..end] . copy_from_enclave ( & buf[ ..buflen] ) ;
61+ index += buf. len ( ) ;
62+ } else {
63+ break
64+ }
65+ }
3766 raw:: write ( fd, userbuf. as_ptr ( ) , userbuf. len ( ) ) . from_sgx_result ( )
3867 }
3968}
0 commit comments