File tree Expand file tree Collapse file tree 5 files changed +88
-0
lines changed Expand file tree Collapse file tree 5 files changed +88
-0
lines changed Original file line number Diff line number Diff line change @@ -20,3 +20,6 @@ mod statx;
2020pub use statx:: is_dir_regfile;
2121pub use statx:: statx;
2222pub use statx:: StatxBuilder ;
23+
24+ mod symlink;
25+ pub use symlink:: symlink;
Original file line number Diff line number Diff line change 1+ use crate :: runtime:: driver:: op:: Op ;
2+ use std:: io;
3+ use std:: path:: Path ;
4+
5+ /// Creates a new symbolic link on the filesystem.
6+ /// The dst path will be a symbolic link pointing to the src path.
7+ /// This is an async version of std::os::unix::fs::symlink.
8+ pub async fn symlink < P : AsRef < Path > , Q : AsRef < Path > > ( src : P , dst : Q ) -> io:: Result < ( ) > {
9+ Op :: symlink ( src, dst) ?. await
10+ }
Original file line number Diff line number Diff line change @@ -43,6 +43,8 @@ pub(crate) use socket::Socket;
4343
4444mod statx;
4545
46+ mod symlink;
47+
4648mod unlink_at;
4749
4850mod util;
Original file line number Diff line number Diff line change 1+ use crate :: runtime:: driver:: op:: { Completable , CqeResult , Op } ;
2+ use crate :: runtime:: CONTEXT ;
3+
4+ use super :: util:: cstr;
5+
6+ use std:: ffi:: CString ;
7+ use std:: io;
8+ use std:: path:: Path ;
9+
10+ pub ( crate ) struct Symlink {
11+ pub ( crate ) _from : CString ,
12+ pub ( crate ) _to : CString ,
13+ }
14+
15+ impl Op < Symlink > {
16+ pub ( crate ) fn symlink < P : AsRef < Path > , Q : AsRef < Path > > (
17+ from : P ,
18+ to : Q ,
19+ ) -> io:: Result < Op < Symlink > > {
20+ use io_uring:: { opcode, types} ;
21+
22+ let _from = cstr ( from. as_ref ( ) ) ?;
23+ let _to = cstr ( to. as_ref ( ) ) ?;
24+
25+ CONTEXT . with ( |x| {
26+ x. handle ( ) . expect ( "Not in a runtime context" ) . submit_op (
27+ Symlink { _from, _to } ,
28+ |symlink| {
29+ let from_ref = symlink. _from . as_c_str ( ) . as_ptr ( ) ;
30+ let to_ref = symlink. _to . as_c_str ( ) . as_ptr ( ) ;
31+
32+ opcode:: SymlinkAt :: new ( types:: Fd ( libc:: AT_FDCWD ) , from_ref, to_ref) . build ( )
33+ } ,
34+ )
35+ } )
36+ }
37+ }
38+
39+ impl Completable for Symlink {
40+ type Output = io:: Result < ( ) > ;
41+
42+ fn complete ( self , cqe : CqeResult ) -> Self :: Output {
43+ cqe. result . map ( |_| ( ) )
44+ }
45+ }
Original file line number Diff line number Diff line change 1+ #[ path = "../src/future.rs" ]
2+ #[ allow( warnings) ]
3+ mod future;
4+
5+ use std:: io:: Write ;
6+ use tokio_test:: assert_ok;
7+ use tokio_uring:: fs;
8+
9+ use tempfile:: tempdir;
10+ use tempfile:: NamedTempFile ;
11+
12+ const TEST_PAYLOAD : & [ u8 ] = b"I am data in the source file" ;
13+
14+ #[ test]
15+ fn test_create_symlink ( ) {
16+ tokio_uring:: start ( async {
17+ let mut src_file = NamedTempFile :: new ( ) . unwrap ( ) ;
18+ src_file. write_all ( TEST_PAYLOAD ) . unwrap ( ) ;
19+
20+ let dst_enclosing_dir = tempdir ( ) . unwrap ( ) ;
21+
22+ assert_ok ! ( fs:: symlink( src_file. path( ) , dst_enclosing_dir. path( ) . join( "abc" ) ) . await ) ;
23+
24+ let content = std:: fs:: read ( dst_enclosing_dir. path ( ) . join ( "abc" ) ) . unwrap ( ) ;
25+
26+ assert_eq ! ( content, TEST_PAYLOAD ) ;
27+ } ) ;
28+ }
You can’t perform that action at this time.
0 commit comments