@@ -15,7 +15,9 @@ pub struct File {
1515
1616//TODO: We may be able to get some of this info
1717#[ derive( Clone ) ]
18- pub struct FileAttr ;
18+ pub struct FileAttr {
19+ size : u64 ,
20+ }
1921
2022pub struct ReadDir ( !) ;
2123
@@ -26,6 +28,7 @@ pub struct OpenOptions {
2628 read : bool ,
2729 write : bool ,
2830 append : bool ,
31+ create_new : bool ,
2932}
3033
3134#[ derive( Copy , Clone , Debug , Default ) ]
@@ -44,7 +47,7 @@ pub struct DirBuilder {}
4447
4548impl FileAttr {
4649 pub fn size ( & self ) -> u64 {
47- todo ! ( )
50+ self . size
4851 }
4952
5053 pub fn perm ( & self ) -> FilePermissions {
@@ -131,7 +134,7 @@ impl DirEntry {
131134
132135impl OpenOptions {
133136 pub fn new ( ) -> OpenOptions {
134- OpenOptions { read : false , write : false , append : false }
137+ OpenOptions { read : false , write : false , append : false , create_new : false }
135138 }
136139
137140 pub fn read ( & mut self , read : bool ) {
@@ -143,11 +146,17 @@ impl OpenOptions {
143146 pub fn append ( & mut self , append : bool ) {
144147 self . append = append;
145148 }
146- pub fn truncate ( & mut self , _truncate : bool ) { }
149+ pub fn truncate ( & mut self , truncate : bool ) {
150+ if truncate {
151+ panic ! ( "Truncation is not supported" )
152+ }
153+ }
147154 pub fn create ( & mut self , create : bool ) {
148155 self . write = create;
149156 }
150- pub fn create_new ( & mut self , _create_new : bool ) { }
157+ pub fn create_new ( & mut self , create_new : bool ) {
158+ self . create_new = create_new;
159+ }
151160}
152161
153162impl File {
@@ -159,6 +168,18 @@ impl File {
159168 io:: Error :: new ( io:: ErrorKind :: InvalidData , "Path contained a null byte" )
160169 } ) ?;
161170
171+ if opts. create_new {
172+ let file_exists = unsafe {
173+ vex_sdk:: vexFileStatus ( path. as_ptr ( ) )
174+ } ;
175+ if file_exists != 0 {
176+ return Err ( io:: Error :: new (
177+ io:: ErrorKind :: AlreadyExists ,
178+ "File already exists"
179+ ) )
180+ }
181+ }
182+
162183 let file = if opts. read && !opts. write {
163184 // The second argument to this function is ignored.
164185 // Open in read only mode
@@ -313,8 +334,19 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
313334 unsupported ( )
314335}
315336
316- pub fn try_exists ( _path : & Path ) -> io:: Result < bool > {
317- todo ! ( )
337+ pub fn try_exists ( path : & Path ) -> io:: Result < bool > {
338+ let path = CString :: new ( path. as_os_str ( ) . as_encoded_bytes ( ) ) . map_err ( |_| {
339+ io:: Error :: new ( io:: ErrorKind :: InvalidData , "Path contained a null byte" )
340+ } ) ?;
341+
342+ let file_exists = unsafe {
343+ vex_sdk:: vexFileStatus ( path. as_ptr ( ) )
344+ } ;
345+ if file_exists != 0 {
346+ Ok ( true )
347+ } else {
348+ Ok ( false )
349+ }
318350}
319351
320352pub fn readlink ( _p : & Path ) -> io:: Result < PathBuf > {
@@ -329,12 +361,34 @@ pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
329361 unsupported ( )
330362}
331363
332- pub fn stat ( _p : & Path ) -> io:: Result < FileAttr > {
333- todo ! ( )
364+ pub fn stat ( p : & Path ) -> io:: Result < FileAttr > {
365+ let mut opts = OpenOptions :: new ( ) ;
366+ opts. read ( true ) ;
367+ let file = File :: open ( p, & opts) ?;
368+ let fd = file. fd . 0 ;
369+
370+ const SEEK_END : i32 = 2 ;
371+
372+ let end = unsafe {
373+ map_fresult ( vex_sdk:: vexFileSeek ( fd, 0 , SEEK_END ) ) ?;
374+ vex_sdk:: vexFileTell ( fd)
375+ } ;
376+
377+ if end >= 0 {
378+ Ok ( FileAttr {
379+ size : end as u64 ,
380+ } )
381+ } else {
382+ Err ( io:: Error :: new (
383+ io:: ErrorKind :: NotSeekable ,
384+ "Failed to seek file"
385+ ) )
386+ }
334387}
335388
336- pub fn lstat ( _p : & Path ) -> io:: Result < FileAttr > {
337- unsupported ( )
389+ pub fn lstat ( p : & Path ) -> io:: Result < FileAttr > {
390+ // Symlinks aren't supported in our filesystem
391+ stat ( p)
338392}
339393
340394pub fn canonicalize ( _p : & Path ) -> io:: Result < PathBuf > {
0 commit comments