File tree Expand file tree Collapse file tree 5 files changed +87
-1
lines changed Expand file tree Collapse file tree 5 files changed +87
-1
lines changed Original file line number Diff line number Diff line change @@ -22,7 +22,7 @@ preadv_pwritev = []
2222signalfd = []
2323
2424[dependencies ]
25- libc = { git = " https://github.com/rust-lang /libc" }
25+ libc = { git = " https://github.com/Mic92 /libc" , branch = " master " }
2626bitflags = " 0.7"
2727cfg-if = " 0.1.0"
2828void = " 1.0.2"
Original file line number Diff line number Diff line change 1+ use { Result , Error , Errno , NixPath } ;
2+ use libc:: { self , DIR } ;
3+ use std:: os:: unix:: io:: RawFd ;
4+ use errno;
5+
6+ pub struct Dir {
7+ handle : * mut DIR ,
8+ }
9+
10+ impl Drop for Dir {
11+ fn drop ( & mut self ) {
12+ unsafe { libc:: closedir ( self . handle ) } ;
13+ }
14+ }
15+
16+ pub fn fdopendir ( fd : RawFd ) -> Result < Dir > {
17+ let dirp = unsafe { libc:: fdopendir ( fd) } ;
18+ if dirp. is_null ( ) {
19+ Err ( Error :: last ( ) . into ( ) )
20+ } else {
21+ Ok ( Dir { handle : dirp } )
22+ }
23+ }
24+
25+ pub fn opendir < P : ?Sized + NixPath > ( name : & P ) -> Result < Dir > {
26+ let dirp = try!( name. with_nix_path ( |cstr| {
27+ unsafe { libc:: opendir ( cstr. as_ptr ( ) ) }
28+ } ) ) ;
29+ if dirp. is_null ( ) {
30+ Err ( Error :: last ( ) . into ( ) )
31+ } else {
32+ Ok ( Dir { handle : dirp } )
33+ }
34+ }
35+
36+ pub fn readdir < ' a > ( dir : & ' a mut Dir ) -> Result < Option < & ' a libc:: dirent > > {
37+ let dirent = unsafe {
38+ Errno :: clear ( ) ;
39+ libc:: readdir ( dir. handle )
40+ } ;
41+ if dirent. is_null ( ) {
42+ match Errno :: last ( ) {
43+ errno:: UnknownErrno => Ok ( None ) ,
44+ _ => Err ( Error :: last ( ) . into ( ) ) ,
45+ }
46+ } else {
47+ Ok ( Some ( unsafe { & * dirent} ) )
48+ }
49+ }
50+
Original file line number Diff line number Diff line change @@ -34,6 +34,7 @@ pub mod libc {
3434pub use libc:: { c_int, c_void} ;
3535pub use errno:: Errno ;
3636
37+ pub mod dirent;
3738pub mod errno;
3839pub mod features;
3940pub mod fcntl;
Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ extern crate tempfile;
88extern crate nix_test as nixtest;
99
1010mod sys;
11+ mod test_dirent;
1112mod test_fcntl;
1213mod test_net;
1314mod test_nix_path;
Original file line number Diff line number Diff line change 1+
2+ mod test_dirent {
3+ use nix:: dirent:: { opendir, fdopendir, readdir, Dir } ;
4+ use tempdir:: TempDir ;
5+ use std:: fs:: File ;
6+ use std:: path:: Path ;
7+ use std:: os:: unix:: io:: IntoRawFd ;
8+
9+ fn test_readdir < OPEN > ( open_fn : OPEN ) where OPEN : Fn ( & Path ) -> Dir {
10+ let tempdir = TempDir :: new ( "nix-test_readdir" )
11+ . unwrap_or_else ( |e| panic ! ( "tempdir failed: {}" , e) ) ;
12+ let mut dir = open_fn ( tempdir. path ( ) ) ;
13+ let entry1 = readdir ( & mut dir) . unwrap ( ) . unwrap ( ) . clone ( ) ;
14+ assert_eq ! ( entry1. d_name[ 0 ..2 ] , [ '.' as i8 , '\0' as i8 ] ) ;
15+
16+ let entry2 = readdir ( & mut dir) . unwrap ( ) . unwrap ( ) . clone ( ) ;
17+ assert_eq ! ( entry2. d_name[ 0 ..2 ] , [ '.' as i8 , '.' as i8 ] ) ;
18+
19+ assert ! ( readdir( & mut dir) . unwrap( ) . is_none( ) ) ;
20+ }
21+
22+ #[ test]
23+ fn test_opendir ( ) {
24+ test_readdir ( |path| opendir ( path) . unwrap ( ) ) ;
25+ }
26+
27+ #[ test]
28+ fn test_fdopendir ( ) {
29+ test_readdir ( |path|
30+ fdopendir ( File :: open ( path) . unwrap ( ) . into_raw_fd ( ) ) . unwrap ( )
31+ ) ;
32+ }
33+
34+ }
You can’t perform that action at this time.
0 commit comments