1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
pub use libc::dev_t; pub use libc::stat as FileStat; use {Errno, Result, NixPath}; use fcntl::AtFlags; use libc::{self, mode_t}; use std::mem; use std::os::unix::io::RawFd; mod ffi { use libc::{c_char, c_int, mode_t, dev_t}; pub use libc::{stat, fstat, lstat}; extern { pub fn mknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> c_int; pub fn umask(mask: mode_t) -> mode_t; } } libc_bitflags!( pub flags SFlag: mode_t { S_IFIFO, S_IFCHR, S_IFDIR, S_IFBLK, S_IFREG, S_IFLNK, S_IFSOCK, S_IFMT, } ); bitflags! { pub flags Mode: mode_t { const S_IRWXU = libc::S_IRWXU, const S_IRUSR = libc::S_IRUSR, const S_IWUSR = libc::S_IWUSR, const S_IXUSR = libc::S_IXUSR, const S_IRWXG = libc::S_IRWXG, const S_IRGRP = libc::S_IRGRP, const S_IWGRP = libc::S_IWGRP, const S_IXGRP = libc::S_IXGRP, const S_IRWXO = libc::S_IRWXO, const S_IROTH = libc::S_IROTH, const S_IWOTH = libc::S_IWOTH, const S_IXOTH = libc::S_IXOTH, const S_ISUID = libc::S_ISUID as mode_t, const S_ISGID = libc::S_ISGID as mode_t, const S_ISVTX = libc::S_ISVTX as mode_t, } } pub fn mknod<P: ?Sized + NixPath>(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> { let res = try!(path.with_nix_path(|cstr| { unsafe { ffi::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) } })); Errno::result(res).map(drop) } #[cfg(target_os = "linux")] pub fn major(dev: dev_t) -> u64 { ((dev >> 32) & 0xfffff000) | ((dev >> 8) & 0x00000fff) } #[cfg(target_os = "linux")] pub fn minor(dev: dev_t) -> u64 { ((dev >> 12) & 0xffffff00) | ((dev ) & 0x000000ff) } #[cfg(target_os = "linux")] pub fn makedev(major: u64, minor: u64) -> dev_t { ((major & 0xfffff000) << 32) | ((major & 0x00000fff) << 8) | ((minor & 0xffffff00) << 12) | ((minor & 0x000000ff) ) } pub fn umask(mode: Mode) -> Mode { let prev = unsafe { ffi::umask(mode.bits() as mode_t) }; Mode::from_bits(prev).expect("[BUG] umask returned invalid Mode") } pub fn stat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> { let mut dst = unsafe { mem::uninitialized() }; let res = try!(path.with_nix_path(|cstr| { unsafe { ffi::stat(cstr.as_ptr(), &mut dst as *mut FileStat) } })); try!(Errno::result(res)); Ok(dst) } pub fn lstat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> { let mut dst = unsafe { mem::uninitialized() }; let res = try!(path.with_nix_path(|cstr| { unsafe { ffi::lstat(cstr.as_ptr(), &mut dst as *mut FileStat) } })); try!(Errno::result(res)); Ok(dst) } pub fn fstat(fd: RawFd) -> Result<FileStat> { let mut dst = unsafe { mem::uninitialized() }; let res = unsafe { ffi::fstat(fd, &mut dst as *mut FileStat) }; try!(Errno::result(res)); Ok(dst) } pub fn fstatat<P: ?Sized + NixPath>(dirfd: RawFd, pathname: &P, f: AtFlags) -> Result<FileStat> { let mut dst = unsafe { mem::uninitialized() }; let res = try!(pathname.with_nix_path(|cstr| { unsafe { libc::fstatat(dirfd, cstr.as_ptr(), &mut dst as *mut FileStat, f.bits() as libc::c_int) } })); try!(Errno::result(res)); Ok(dst) }