Skip to content

Commit 56b96a3

Browse files
committed
path2: Implement stat support
1 parent 7fcdcae commit 56b96a3

File tree

3 files changed

+393
-0
lines changed

3 files changed

+393
-0
lines changed

src/libstd/path2/mod.rs

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,3 +650,224 @@ pub trait GenericPathUnsafe {
650650
fn contains_nul(v: &[u8]) -> bool {
651651
v.iter().any(|&x| x == 0)
652652
}
653+
654+
// FIXME (#9537): libc::stat should derive Default
655+
#[cfg(target_os = "linux")]
656+
#[cfg(target_os = "android")]
657+
mod stat {
658+
#[allow(missing_doc)];
659+
660+
#[cfg(target_arch = "x86")]
661+
pub mod arch {
662+
use libc;
663+
664+
pub fn default_stat() -> libc::stat {
665+
libc::stat {
666+
st_dev: 0,
667+
__pad1: 0,
668+
st_ino: 0,
669+
st_mode: 0,
670+
st_nlink: 0,
671+
st_uid: 0,
672+
st_gid: 0,
673+
st_rdev: 0,
674+
__pad2: 0,
675+
st_size: 0,
676+
st_blksize: 0,
677+
st_blocks: 0,
678+
st_atime: 0,
679+
st_atime_nsec: 0,
680+
st_mtime: 0,
681+
st_mtime_nsec: 0,
682+
st_ctime: 0,
683+
st_ctime_nsec: 0,
684+
__unused4: 0,
685+
__unused5: 0,
686+
}
687+
}
688+
}
689+
690+
#[cfg(target_arch = "arm")]
691+
pub mod arch {
692+
use libc;
693+
694+
pub fn default_stat() -> libc::stat {
695+
libc::stat {
696+
st_dev: 0,
697+
__pad0: [0, ..4],
698+
__st_ino: 0,
699+
st_mode: 0,
700+
st_nlink: 0,
701+
st_uid: 0,
702+
st_gid: 0,
703+
st_rdev: 0,
704+
__pad3: [0, ..4],
705+
st_size: 0,
706+
st_blksize: 0,
707+
st_blocks: 0,
708+
st_atime: 0,
709+
st_atime_nsec: 0,
710+
st_mtime: 0,
711+
st_mtime_nsec: 0,
712+
st_ctime: 0,
713+
st_ctime_nsec: 0,
714+
st_ino: 0
715+
}
716+
}
717+
}
718+
719+
#[cfg(target_arch = "mips")]
720+
pub mod arch {
721+
use libc;
722+
723+
pub fn default_stat() -> libc::stat {
724+
libc::stat {
725+
st_dev: 0,
726+
st_pad1: [0, ..3],
727+
st_ino: 0,
728+
st_mode: 0,
729+
st_nlink: 0,
730+
st_uid: 0,
731+
st_gid: 0,
732+
st_rdev: 0,
733+
st_pad2: [0, ..2],
734+
st_size: 0,
735+
st_pad3: 0,
736+
st_atime: 0,
737+
st_atime_nsec: 0,
738+
st_mtime: 0,
739+
st_mtime_nsec: 0,
740+
st_ctime: 0,
741+
st_ctime_nsec: 0,
742+
st_blksize: 0,
743+
st_blocks: 0,
744+
st_pad5: [0, ..14],
745+
}
746+
}
747+
}
748+
749+
#[cfg(target_arch = "x86_64")]
750+
pub mod arch {
751+
use libc;
752+
753+
pub fn default_stat() -> libc::stat {
754+
libc::stat {
755+
st_dev: 0,
756+
st_ino: 0,
757+
st_nlink: 0,
758+
st_mode: 0,
759+
st_uid: 0,
760+
st_gid: 0,
761+
__pad0: 0,
762+
st_rdev: 0,
763+
st_size: 0,
764+
st_blksize: 0,
765+
st_blocks: 0,
766+
st_atime: 0,
767+
st_atime_nsec: 0,
768+
st_mtime: 0,
769+
st_mtime_nsec: 0,
770+
st_ctime: 0,
771+
st_ctime_nsec: 0,
772+
__unused: [0, 0, 0],
773+
}
774+
}
775+
}
776+
}
777+
778+
#[cfg(target_os = "freebsd")]
779+
mod stat {
780+
#[allow(missing_doc)];
781+
782+
#[cfg(target_arch = "x86_64")]
783+
pub mod arch {
784+
use libc;
785+
786+
pub fn default_stat() -> libc::stat {
787+
libc::stat {
788+
st_dev: 0,
789+
st_ino: 0,
790+
st_mode: 0,
791+
st_nlink: 0,
792+
st_uid: 0,
793+
st_gid: 0,
794+
st_rdev: 0,
795+
st_atime: 0,
796+
st_atime_nsec: 0,
797+
st_mtime: 0,
798+
st_mtime_nsec: 0,
799+
st_ctime: 0,
800+
st_ctime_nsec: 0,
801+
st_size: 0,
802+
st_blocks: 0,
803+
st_blksize: 0,
804+
st_flags: 0,
805+
st_gen: 0,
806+
st_lspare: 0,
807+
st_birthtime: 0,
808+
st_birthtime_nsec: 0,
809+
__unused: [0, 0],
810+
}
811+
}
812+
}
813+
}
814+
815+
#[cfg(target_os = "macos")]
816+
mod stat {
817+
#[allow(missing_doc)];
818+
819+
pub mod arch {
820+
use libc;
821+
822+
pub fn default_stat() -> libc::stat {
823+
libc::stat {
824+
st_dev: 0,
825+
st_mode: 0,
826+
st_nlink: 0,
827+
st_ino: 0,
828+
st_uid: 0,
829+
st_gid: 0,
830+
st_rdev: 0,
831+
st_atime: 0,
832+
st_atime_nsec: 0,
833+
st_mtime: 0,
834+
st_mtime_nsec: 0,
835+
st_ctime: 0,
836+
st_ctime_nsec: 0,
837+
st_birthtime: 0,
838+
st_birthtime_nsec: 0,
839+
st_size: 0,
840+
st_blocks: 0,
841+
st_blksize: 0,
842+
st_flags: 0,
843+
st_gen: 0,
844+
st_lspare: 0,
845+
st_qspare: [0, 0],
846+
}
847+
}
848+
}
849+
}
850+
851+
#[cfg(target_os = "win32")]
852+
mod stat {
853+
#[allow(missing_doc)];
854+
855+
pub mod arch {
856+
use libc;
857+
pub fn default_stat() -> libc::stat {
858+
libc::stat {
859+
st_dev: 0,
860+
st_ino: 0,
861+
st_mode: 0,
862+
st_nlink: 0,
863+
st_uid: 0,
864+
st_gid: 0,
865+
st_rdev: 0,
866+
st_size: 0,
867+
st_atime: 0,
868+
st_mtime: 0,
869+
st_ctime: 0,
870+
}
871+
}
872+
}
873+
}

src/libstd/path2/posix.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ use vec::CopyableVector;
2626
use vec::{Vector, VectorVector};
2727
use super::{GenericPath, GenericPathUnsafe};
2828

29+
#[cfg(not(target_os = "win32"))]
30+
use libc;
31+
2932
/// Iterator that yields successive components of a Path
3033
pub type ComponentIter<'self> = vec::SplitIterator<'self, u8>;
3134

@@ -422,6 +425,102 @@ fn contains_nul(v: &[u8]) -> bool {
422425
static dot_static: &'static [u8] = &'static ['.' as u8];
423426
static dot_dot_static: &'static [u8] = &'static ['.' as u8, '.' as u8];
424427

428+
// Stat support
429+
#[cfg(not(target_os = "win32"))]
430+
impl Path {
431+
/// Calls stat() on the represented file and returns the resulting libc::stat
432+
pub fn stat(&self) -> Option<libc::stat> {
433+
#[fixed_stack_segment]; #[inline(never)];
434+
do self.with_c_str |buf| {
435+
let mut st = super::stat::arch::default_stat();
436+
match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
437+
0 => Some(st),
438+
_ => None
439+
}
440+
}
441+
}
442+
443+
/// Returns whether the represented file exists
444+
pub fn exists(&self) -> bool {
445+
match self.stat() {
446+
None => false,
447+
Some(_) => true
448+
}
449+
}
450+
451+
/// Returns the filesize of the represented file
452+
pub fn get_size(&self) -> Option<i64> {
453+
match self.stat() {
454+
None => None,
455+
Some(st) => Some(st.st_size as i64)
456+
}
457+
}
458+
459+
/// Returns the mode of the represented file
460+
pub fn get_mode(&self) -> Option<uint> {
461+
match self.stat() {
462+
None => None,
463+
Some(st) => Some(st.st_mode as uint)
464+
}
465+
}
466+
}
467+
468+
#[cfg(target_os = "freebsd")]
469+
#[cfg(target_os = "linux")]
470+
#[cfg(target_os = "macos")]
471+
impl Path {
472+
/// Returns the atime of the represented file, as (secs, nsecs)
473+
pub fn get_atime(&self) -> Option<(i64, int)> {
474+
match self.stat() {
475+
None => None,
476+
Some(st) => Some((st.st_atime as i64, st.st_atime_nsec as int))
477+
}
478+
}
479+
480+
/// Returns the mtime of the represented file, as (secs, nsecs)
481+
pub fn get_mtime(&self) -> Option<(i64, int)> {
482+
match self.stat() {
483+
None => None,
484+
Some(st) => Some((st.st_mtime as i64, st.st_mtime_nsec as int))
485+
}
486+
}
487+
488+
/// Returns the ctime of the represented file, as (secs, nsecs)
489+
pub fn get_ctime(&self) -> Option<(i64, int)> {
490+
match self.stat() {
491+
None => None,
492+
Some(st) => Some((st.st_ctime as i64, st.st_ctime_nsec as int))
493+
}
494+
}
495+
}
496+
497+
#[cfg(unix)]
498+
impl Path {
499+
/// Calls lstat() on the represented file and returns the resulting libc::stat
500+
pub fn lstat(&self) -> Option<libc::stat> {
501+
#[fixed_stack_segment]; #[inline(never)];
502+
do self.with_c_str |buf| {
503+
let mut st = super::stat::arch::default_stat();
504+
match unsafe { libc::lstat(buf, &mut st) } {
505+
0 => Some(st),
506+
_ => None
507+
}
508+
}
509+
}
510+
}
511+
512+
#[cfg(target_os = "freebsd")]
513+
#[cfg(target_os = "macos")]
514+
impl Path {
515+
/// Returns the birthtime of the represented file
516+
pub fn get_birthtime(&self) -> Option<(i64, int)> {
517+
match self.stat() {
518+
None => None,
519+
Some(st) => Some((st.st_birthtime as i64, st.st_birthtime_nsec as int))
520+
}
521+
}
522+
}
523+
425524
#[cfg(test)]
426525
mod tests {
427526
use super::*;

0 commit comments

Comments
 (0)