#![feature(path_ext)]
#![feature(str_char)]
#![feature(into_cow)]
+#![feature(fs_canonicalize)]
#![feature(slice_patterns)]
#![cfg_attr(test, feature(test))]
pub mod lint;
pub mod util {
- pub use rustc_back::fs;
pub use rustc_back::sha2;
pub mod common;
use metadata::loader;
use metadata::loader::CratePaths;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use std::rc::Rc;
+use std::fs;
+
use syntax::ast;
use syntax::abi;
use syntax::attr;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit;
-use util::fs;
use log;
pub struct CrateReader<'a> {
let source = self.sess.cstore.get_used_crate_source(cnum).unwrap();
if let Some(locs) = self.sess.opts.externs.get(name) {
let found = locs.iter().any(|l| {
- let l = fs::realpath(&Path::new(&l[..])).ok();
+ let l = fs::canonicalize(l).ok();
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
});
use std::io::prelude::*;
use std::path::{Path, PathBuf};
-use util::fs as myfs;
use session::search_paths::{SearchPaths, PathKind};
#[derive(Copy, Clone)]
// Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
path.and_then(|path| {
- match myfs::realpath(&path) {
+ match fs::canonicalize(&path) {
Ok(canon) => Some(canon),
Err(e) => panic!("failed to get realpath: {}", e),
}
use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
use syntax::codemap::Span;
use syntax::diagnostic::SpanHandler;
-use util::fs;
use util::common;
use rustc_back::target::Target;
use std::cmp;
use std::collections::HashMap;
+use std::fs;
use std::io::prelude::*;
use std::io;
use std::path::{Path, PathBuf};
.or_insert_with(|| (HashMap::new(), HashMap::new()));
let (ref mut rlibs, ref mut dylibs) = *slot;
if rlib {
- rlibs.insert(fs::realpath(path).unwrap(), kind);
+ rlibs.insert(fs::canonicalize(path).unwrap(), kind);
} else {
- dylibs.insert(fs::realpath(path).unwrap(), kind);
+ dylibs.insert(fs::canonicalize(path).unwrap(), kind);
}
FileMatches
// there's at most one rlib and at most one dylib.
for loc in locs {
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
- rlibs.insert(fs::realpath(&loc).unwrap(),
+ rlibs.insert(fs::canonicalize(&loc).unwrap(),
PathKind::ExternFlag);
} else {
- dylibs.insert(fs::realpath(&loc).unwrap(),
+ dylibs.insert(fs::canonicalize(&loc).unwrap(),
PathKind::ExternFlag);
}
}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::io;
-use std::path::{Path, PathBuf};
-
-#[cfg(windows)]
-pub fn realpath(original: &Path) -> io::Result<PathBuf> {
- Ok(original.to_path_buf())
-}
-
-#[cfg(unix)]
-pub fn realpath(original: &Path) -> io::Result<PathBuf> {
- use libc;
- use std::ffi::{OsString, CString};
- use std::os::unix::prelude::*;
-
- extern {
- fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
- -> *mut libc::c_char;
- }
-
- let path = try!(CString::new(original.as_os_str().as_bytes()));
- let mut buf = vec![0u8; 16 * 1024];
- unsafe {
- let r = realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _);
- if r.is_null() {
- return Err(io::Error::last_os_error())
- }
- }
- let p = buf.iter().position(|i| *i == 0).unwrap();
- buf.truncate(p);
- Ok(PathBuf::from(OsString::from_vec(buf)))
-}
-
-#[cfg(all(not(windows), test))]
-mod tests {
- use tempdir::TempDir;
- use std::fs::{self, File};
- use super::realpath;
-
- #[test]
- fn realpath_works() {
- let tmpdir = TempDir::new("rustc-fs").unwrap();
- let tmpdir = realpath(tmpdir.path()).unwrap();
- let file = tmpdir.join("test");
- let dir = tmpdir.join("test2");
- let link = dir.join("link");
- let linkdir = tmpdir.join("test3");
-
- File::create(&file).unwrap();
- fs::create_dir(&dir).unwrap();
- fs::soft_link(&file, &link).unwrap();
- fs::soft_link(&dir, &linkdir).unwrap();
-
- assert_eq!(realpath(&tmpdir).unwrap(), tmpdir);
- assert_eq!(realpath(&file).unwrap(), file);
- assert_eq!(realpath(&link).unwrap(), file);
- assert_eq!(realpath(&linkdir).unwrap(), dir);
- assert_eq!(realpath(&linkdir.join("link")).unwrap(), file);
- }
-
- #[test]
- fn realpath_works_tricky() {
- let tmpdir = TempDir::new("rustc-fs").unwrap();
- let tmpdir = realpath(tmpdir.path()).unwrap();
-
- let a = tmpdir.join("a");
- let b = a.join("b");
- let c = b.join("c");
- let d = a.join("d");
- let e = d.join("e");
- let f = a.join("f");
-
- fs::create_dir_all(&b).unwrap();
- fs::create_dir_all(&d).unwrap();
- File::create(&f).unwrap();
- fs::soft_link("../d/e", &c).unwrap();
- fs::soft_link("../f", &e).unwrap();
-
- assert_eq!(realpath(&c).unwrap(), f);
- assert_eq!(realpath(&e).unwrap(), f);
- }
-}
#![feature(path_ext)]
#![feature(step_by)]
#![feature(libc)]
+#![feature(fs_canonicalize)]
#![cfg_attr(test, feature(test, rand))]
extern crate syntax;
pub mod archive;
pub mod tempdir;
pub mod arm;
-pub mod fs;
pub mod mips;
pub mod mipsel;
pub mod rpath;
use std::collections::HashSet;
use std::env;
-use std::io;
use std::path::{Path, PathBuf};
+use std::fs;
use syntax::ast;
pub struct RPathConfig<'a> {
pub is_like_osx: bool,
pub has_rpath: bool,
pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
- pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>,
}
pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
};
let cwd = env::current_dir().unwrap();
- let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
+ let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or(cwd.join(lib));
lib.pop();
let mut output = cwd.join(&config.out_filename);
output.pop();
- let output = (config.realpath)(&output).unwrap();
+ let output = fs::canonicalize(&output).unwrap_or(output);
let relative = path_relative_from(&lib, &output)
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
// FIXME (#9639): This needs to handle non-utf8 paths
is_like_osx: true,
out_filename: PathBuf::from("bin/rustc"),
get_install_prefix_lib_path: &mut || panic!(),
- realpath: &mut |p| Ok(p.to_path_buf()),
};
let res = get_rpath_relative_to_output(config,
Path::new("lib/libstd.so"));
get_install_prefix_lib_path: &mut || panic!(),
has_rpath: true,
is_like_osx: false,
- realpath: &mut |p| Ok(p.to_path_buf()),
};
let res = get_rpath_relative_to_output(config,
Path::new("lib/libstd.so"));
use std::fs::{self, PathExt};
use std::io::{self, Read, Write};
use std::mem;
-use std::path::{Path, PathBuf};
+use std::path::{self, Path, PathBuf};
use std::process::Command;
use std::str;
use flate;
// stripped away as much as it could. This has not been seen to impact
// link times negatively.
//
- // -dead_strip can't be part of the pre_link_args because it's also used for partial
- // linking when using multiple codegen units (-r). So we insert it here.
+ // -dead_strip can't be part of the pre_link_args because it's also used
+ // for partial linking when using multiple codegen units (-r). So we
+ // insert it here.
cmd.arg("-Wl,-dead_strip");
}
has_rpath: sess.target.target.options.has_rpath,
is_like_osx: sess.target.target.options.is_like_osx,
get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
- realpath: &mut ::util::fs::realpath
};
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
}
}
});
} else {
- cmd.arg(cratepath);
+ cmd.arg(&fix_windows_verbatim_for_gcc(cratepath));
}
}
// Just need to tell the linker about where the library lives and
// what its name is
if let Some(dir) = cratepath.parent() {
- cmd.arg("-L").arg(dir);
+ cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(dir));
}
let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
}
}
}
+
+// Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
+// (a verbatim path). This form of path is generally pretty rare, but the
+// implementation of `fs::canonicalize` currently generates paths of this form,
+// meaning that we're going to be passing quite a few of these down to gcc.
+//
+// For now we just strip the "verbatim prefix" of `\\?\` from the path. This
+// will probably lose information in some cases, but there's not a whole lot
+// more we can do with a buggy gcc...
+fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
+ if !cfg!(windows) {
+ return p.to_path_buf()
+ }
+ let mut components = p.components();
+ let prefix = match components.next() {
+ Some(path::Component::Prefix(p)) => p,
+ _ => return p.to_path_buf(),
+ };
+ let disk = match prefix.kind() {
+ path::Prefix::VerbatimDisk(disk) => disk,
+ _ => return p.to_path_buf(),
+ };
+ let mut base = OsString::from(format!("{}:", disk as char));
+ base.push(components.as_path());
+ PathBuf::from(base)
+}
use core::prelude::*;
use fmt;
+use ffi::OsString;
use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write};
use path::{Path, PathBuf};
use sys::fs2 as fs_imp;
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Permissions(fs_imp::FilePermissions);
+/// An structure representing a type of file with accessors for each file type.
+#[unstable(feature = "file_type", reason = "recently added API")]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+pub struct FileType(fs_imp::FileType);
+
impl File {
/// Attempts to open a file in read-only mode.
///
}
impl Metadata {
+ /// Returns the file type for this metadata.
+ #[unstable(feature = "file_type", reason = "recently added API")]
+ pub fn file_type(&self) -> FileType {
+ FileType(self.0.file_type())
+ }
+
/// Returns whether this metadata is for a directory.
///
/// # Examples
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn is_dir(&self) -> bool { self.0.is_dir() }
+ pub fn is_dir(&self) -> bool { self.file_type().is_dir() }
/// Returns whether this metadata is for a regular file.
///
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn is_file(&self) -> bool { self.0.is_file() }
+ pub fn is_file(&self) -> bool { self.file_type().is_file() }
/// Returns the size of the file, in bytes, this metadata is for.
///
reason = "the return type of u64 is not quite appropriate for \
this method and may change if the standard library \
gains a type to represent a moment in time")]
- pub fn accessed(&self) -> u64 { self.0.accessed() }
+ #[deprecated(since = "1.1.0",
+ reason = "use os::platform::fs::MetadataExt extension traits")]
+ pub fn accessed(&self) -> u64 {
+ self.adjust_time(self.0.accessed())
+ }
/// Returns the most recent modification time for a file.
///
reason = "the return type of u64 is not quite appropriate for \
this method and may change if the standard library \
gains a type to represent a moment in time")]
- pub fn modified(&self) -> u64 { self.0.modified() }
+ #[deprecated(since = "1.1.0",
+ reason = "use os::platform::fs::MetadataExt extension traits")]
+ pub fn modified(&self) -> u64 {
+ self.adjust_time(self.0.modified())
+ }
+
+ fn adjust_time(&self, val: u64) -> u64 {
+ // FILETIME (what `val` represents) is in 100ns intervals and there are
+ // 10000 intervals in a millisecond.
+ if cfg!(windows) {val / 10000} else {val}
+ }
+}
+
+impl AsInner<fs_imp::FileAttr> for Metadata {
+ fn as_inner(&self) -> &fs_imp::FileAttr { &self.0 }
}
impl Permissions {
}
}
+#[unstable(feature = "file_type", reason = "recently added API")]
+impl FileType {
+ /// Test whether this file type represents a directory.
+ pub fn is_dir(&self) -> bool { self.0.is_dir() }
+
+ /// Test whether this file type represents a regular file.
+ pub fn is_file(&self) -> bool { self.0.is_file() }
+
+ /// Test whether this file type represents a symbolic link.
+ pub fn is_symlink(&self) -> bool { self.0.is_symlink() }
+}
+
impl FromInner<fs_imp::FilePermissions> for Permissions {
fn from_inner(f: fs_imp::FilePermissions) -> Permissions {
Permissions(f)
/// The exact text, of course, depends on what files you have in `.`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn path(&self) -> PathBuf { self.0.path() }
+
+ /// Return the metadata for the file that this entry points at.
+ ///
+ /// This function will not traverse symlinks if this entry points at a
+ /// symlink.
+ ///
+ /// # Platform behavior
+ ///
+ /// On Windows this function is cheap to call (no extra system calls
+ /// needed), but on Unix platforms this function is the equivalent of
+ /// calling `symlink_metadata` on the path.
+ #[unstable(feature = "dir_entry_ext", reason = "recently added API")]
+ pub fn metadata(&self) -> io::Result<Metadata> {
+ self.0.metadata().map(Metadata)
+ }
+
+ /// Return the file type for the file that this entry points at.
+ ///
+ /// This function will not traverse symlinks if this entry points at a
+ /// symlink.
+ ///
+ /// # Platform behavior
+ ///
+ /// On Windows and most Unix platforms this function is free (no extra
+ /// system calls needed), but some Unix platforms may require the equivalent
+ /// call to `symlink_metadata` to learn about the target file type.
+ #[unstable(feature = "dir_entry_ext", reason = "recently added API")]
+ pub fn file_type(&self) -> io::Result<FileType> {
+ self.0.file_type().map(FileType)
+ }
+
+ /// Returns the bare file name of this directory entry without any other
+ /// leading path component.
+ #[unstable(feature = "dir_entry_ext", reason = "recently added API")]
+ pub fn file_name(&self) -> OsString {
+ self.0.file_name()
+ }
+}
+
+impl AsInner<fs_imp::DirEntry> for DirEntry {
+ fn as_inner(&self) -> &fs_imp::DirEntry { &self.0 }
}
/// Removes a file from the underlying filesystem.
fs_imp::stat(path.as_ref()).map(Metadata)
}
+/// Query the metadata about a file without following symlinks.
+///
+/// # Examples
+///
+/// ```rust
+/// #![feature(symlink_metadata)]
+/// # fn foo() -> std::io::Result<()> {
+/// use std::fs;
+///
+/// let attr = try!(fs::symlink_metadata("/some/file/path.txt"));
+/// // inspect attr ...
+/// # Ok(())
+/// # }
+/// ```
+#[unstable(feature = "symlink_metadata", reason = "recently added API")]
+pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
+ fs_imp::lstat(path.as_ref()).map(Metadata)
+}
+
/// Rename a file or directory to a new name.
///
/// # Errors
fs_imp::readlink(path.as_ref())
}
+/// Returns the canonical form of a path with all intermediate components
+/// normalized and symbolic links resolved.
+#[unstable(feature = "fs_canonicalize", reason = "recently added API")]
+pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
+ fs_imp::canonicalize(path.as_ref())
+}
+
/// Creates a new, empty directory at the provided path
///
/// # Errors
let path = path.as_ref();
for child in try!(read_dir(path)) {
let child = try!(child).path();
- let stat = try!(lstat(&*child));
+ let stat = try!(symlink_metadata(&*child));
if stat.is_dir() {
try!(remove_dir_all(&*child));
} else {
try!(remove_file(&*child));
}
}
- return remove_dir(path);
-
- #[cfg(unix)]
- fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::lstat(path) }
- #[cfg(windows)]
- fn lstat(path: &Path) -> io::Result<fs_imp::FileAttr> { fs_imp::stat(path) }
+ remove_dir(path)
}
/// Returns an iterator over the entries within a directory.
pub trait PathExt {
/// Gets information on the file, directory, etc at this path.
///
- /// Consult the `fs::stat` documentation for more info.
+ /// Consult the `fs::metadata` documentation for more info.
///
- /// This call preserves identical runtime/error semantics with `file::stat`.
+ /// This call preserves identical runtime/error semantics with
+ /// `fs::metadata`.
fn metadata(&self) -> io::Result<Metadata>;
+ /// Gets information on the file, directory, etc at this path.
+ ///
+ /// Consult the `fs::symlink_metadata` documentation for more info.
+ ///
+ /// This call preserves identical runtime/error semantics with
+ /// `fs::symlink_metadata`.
+ fn symlink_metadata(&self) -> io::Result<Metadata>;
+
+ /// Returns the canonical form of a path, normalizing all components and
+ /// eliminate all symlinks.
+ ///
+ /// This call preserves identical runtime/error semantics with
+ /// `fs::canonicalize`.
+ fn canonicalize(&self) -> io::Result<PathBuf>;
+
+ /// Reads the symlink at this path.
+ ///
+ /// For more information see `fs::read_link`.
+ fn read_link(&self) -> io::Result<PathBuf>;
+
+ /// Reads the directory at this path.
+ ///
+ /// For more information see `fs::read_dir`.
+ fn read_dir(&self) -> io::Result<ReadDir>;
+
/// Boolean value indicator whether the underlying file exists on the local
/// filesystem. Returns false in exactly the cases where `fs::stat` fails.
fn exists(&self) -> bool;
impl PathExt for Path {
fn metadata(&self) -> io::Result<Metadata> { metadata(self) }
-
+ fn symlink_metadata(&self) -> io::Result<Metadata> { symlink_metadata(self) }
+ fn canonicalize(&self) -> io::Result<PathBuf> { canonicalize(self) }
+ fn read_link(&self) -> io::Result<PathBuf> { read_link(self) }
+ fn read_dir(&self) -> io::Result<ReadDir> { read_dir(self) }
fn exists(&self) -> bool { metadata(self).is_ok() }
fn is_file(&self) -> bool {
metadata(self).map(|s| s.is_file()).unwrap_or(false)
}
+
fn is_dir(&self) -> bool {
metadata(self).map(|s| s.is_dir()).unwrap_or(false)
}
let path = tmpdir.join("file");
check!(fs::create_dir_all(&path.join("a/")));
}
+
+ #[test]
+ #[cfg(not(windows))]
+ fn realpath_works() {
+ let tmpdir = tmpdir();
+ let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
+ let file = tmpdir.join("test");
+ let dir = tmpdir.join("test2");
+ let link = dir.join("link");
+ let linkdir = tmpdir.join("test3");
+
+ File::create(&file).unwrap();
+ fs::create_dir(&dir).unwrap();
+ fs::soft_link(&file, &link).unwrap();
+ fs::soft_link(&dir, &linkdir).unwrap();
+
+ assert!(link.symlink_metadata().unwrap().file_type().is_symlink());
+
+ assert_eq!(fs::canonicalize(&tmpdir).unwrap(), tmpdir);
+ assert_eq!(fs::canonicalize(&file).unwrap(), file);
+ assert_eq!(fs::canonicalize(&link).unwrap(), file);
+ assert_eq!(fs::canonicalize(&linkdir).unwrap(), dir);
+ assert_eq!(fs::canonicalize(&linkdir.join("link")).unwrap(), file);
+ }
+
+ #[test]
+ #[cfg(not(windows))]
+ fn realpath_works_tricky() {
+ let tmpdir = tmpdir();
+ let tmpdir = fs::canonicalize(tmpdir.path()).unwrap();
+
+ let a = tmpdir.join("a");
+ let b = a.join("b");
+ let c = b.join("c");
+ let d = a.join("d");
+ let e = d.join("e");
+ let f = a.join("f");
+
+ fs::create_dir_all(&b).unwrap();
+ fs::create_dir_all(&d).unwrap();
+ File::create(&f).unwrap();
+ fs::soft_link("../d/e", &c).unwrap();
+ fs::soft_link("../f", &e).unwrap();
+
+ assert_eq!(fs::canonicalize(&c).unwrap(), f);
+ assert_eq!(fs::canonicalize(&e).unwrap(), f);
+ }
+
+ #[test]
+ fn dir_entry_methods() {
+ let tmpdir = tmpdir();
+
+ fs::create_dir_all(&tmpdir.join("a")).unwrap();
+ File::create(&tmpdir.join("b")).unwrap();
+
+ for file in tmpdir.path().read_dir().unwrap().map(|f| f.unwrap()) {
+ let fname = file.file_name();
+ match fname.to_str() {
+ Some("a") => {
+ assert!(file.file_type().unwrap().is_dir());
+ assert!(file.metadata().unwrap().is_dir());
+ }
+ Some("b") => {
+ assert!(file.file_type().unwrap().is_file());
+ assert!(file.metadata().unwrap().is_file());
+ }
+ f => panic!("unknown file name: {:?}", f),
+ }
+ }
+ }
}
+++ /dev/null
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! OS-specific functionality
-
-#![stable(feature = "os", since = "1.0.0")]
-
-#[cfg(unix)] pub use sys::ext as unix;
-#[cfg(windows)] pub use sys::ext as windows;
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Android-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Android-specific raw type definitions
+
+use os::raw::{c_uint, c_uchar, c_ulonglong, c_longlong, c_ulong};
+use os::unix::raw::{uid_t, gid_t};
+
+pub type blkcnt_t = u32;
+pub type blksize_t = u32;
+pub type dev_t = u32;
+pub type ino_t = u32;
+pub type mode_t = u16;
+pub type nlink_t = u16;
+pub type off_t = i32;
+pub type time_t = i32;
+
+#[repr(C)]
+pub struct stat {
+ pub st_dev: c_ulonglong,
+ pub __pad0: [c_uchar; 4],
+ pub __st_ino: ino_t,
+ pub st_mode: c_uint,
+ pub st_nlink: c_uint,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: c_ulonglong,
+ pub __pad3: [c_uchar; 4],
+ pub st_size: c_longlong,
+ pub st_blksize: blksize_t,
+ pub st_blocks: c_ulonglong,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_ulong,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_ulong,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_ulong,
+ pub st_ino: c_ulonglong,
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Bitrig-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Bitrig-specific raw type definitions
+
+use os::raw::c_long;
+use os::unix::raw::{uid_t, gid_t};
+
+pub type blkcnt_t = i64;
+pub type blksize_t = u32;
+pub type dev_t = i32;
+pub type fflags_t = u32; // type not declared, but struct stat have u_int32_t
+pub type ino_t = u64;
+pub type mode_t = u32;
+pub type nlink_t = u32;
+pub type off_t = i64;
+pub type time_t = i64;
+
+#[repr(C)]
+pub struct stat {
+ pub st_mode: mode_t,
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_size: off_t,
+ pub st_blocks: blkcnt_t,
+ pub st_blksize: blksize_t,
+ pub st_flags: fflags_t,
+ pub st_gen: u32,
+ pub st_birthtime: time_t,
+ pub st_birthtime_nsec: c_long,
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Dragonfly-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Dragonfly-specific raw type definitions
+
+use os::raw::c_long;
+use os::unix::raw::{pid_t, uid_t, gid_t};
+
+pub type blkcnt_t = i64;
+pub type blksize_t = u32;
+pub type dev_t = u32;
+pub type fflags_t = u32;
+pub type ino_t = u64;
+pub type mode_t = u16;
+pub type nlink_t = u16;
+pub type off_t = i64;
+pub type time_t = i64;
+
+#[repr(C)]
+pub struct stat {
+ pub st_ino: ino_t,
+ pub st_nlink: nlink_t,
+ pub st_dev: dev_t,
+ pub st_mode: mode_t,
+ pub st_padding1: u16,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_size: off_t,
+ pub st_blocks: blkcnt_t,
+ pub st_blksize: blksize_t,
+ pub st_flags: fflags_t,
+ pub st_gen: uint32_t,
+ pub st_lspare: int32_t,
+ pub st_qspare1: int64_t,
+ pub st_qspare2: int64_t,
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! FreeBSD-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! FreeBSD-specific raw type definitions
+
+use os::raw::c_long;
+use os::unix::raw::{uid_t, gid_t, pid_t};
+
+pub type blkcnt_t = i64;
+pub type blksize_t = i64;
+pub type dev_t = u32;
+pub type fflags_t = u32;
+pub type ino_t = u32;
+pub type mode_t = u16;
+pub type nlink_t = u16;
+pub type off_t = i64;
+pub type time_t = i64;
+
+#[repr(C)]
+pub struct stat {
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_size: off_t,
+ pub st_blocks: blkcnt_t,
+ pub st_blksize: blksize_t,
+ pub st_flags: fflags_t,
+ pub st_gen: u32,
+ pub st_lspare: i32,
+ pub st_birthtime: time_t,
+ pub st_birthtime_nsec: c_long,
+ pub __unused: [u8; 2],
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! iOS-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! iOS-specific raw type definitions
+
+use os::raw::c_long;
+use os::unix::raw::{uid_t, gid_t, pid_t};
+
+pub type blkcnt_t = i64;
+pub type blksize_t = i32;
+pub type dev_t = i32;
+pub type ino_t = u64;
+pub type mode_t = u16;
+pub type nlink_t = u16;
+pub type off_t = i64;
+pub type time_t = c_long;
+
+#[repr(C)]
+pub struct stat {
+ pub st_dev: dev_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_ino: ino_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_birthtime: time_t,
+ pub st_birthtime_nsec: c_long,
+ pub st_size: off_t,
+ pub st_blocks: blkcnt_t,
+ pub st_blksize: blksize_t,
+ pub st_flags: u32,
+ pub st_gen: u32,
+ pub st_lspare: i32,
+ pub st_qspare: [i64; 2],
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Linux-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Linux-specific raw type definitions
+
+pub type dev_t = u64;
+pub type mode_t = u32;
+
+#[doc(inline)]
+pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
+
+#[cfg(any(target_arch = "x86",
+ target_arch = "le32",
+ target_arch = "powerpc",
+ target_arch = "arm"))]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::{c_long, c_short};
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i32;
+ pub type blksize_t = i32;
+ pub type ino_t = u32;
+ pub type nlink_t = u32;
+ pub type off_t = i32;
+ pub type time_t = i32;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: dev_t,
+ pub __pad1: c_short,
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub __pad2: c_short,
+ pub st_size: off_t,
+ pub st_blksize: blksize_t,
+ pub st_blocks: blkcnt_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub __unused4: c_long,
+ pub __unused5: c_long,
+ }
+}
+
+#[cfg(any(target_arch = "mips",
+ target_arch = "mipsel"))]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::c_long;
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i32;
+ pub type blksize_t = i32;
+ pub type ino_t = u32;
+ pub type nlink_t = u32;
+ pub type off_t = i32;
+ pub type time_t = i32;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: c_ulong,
+ pub st_pad1: [c_long; 3],
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: c_ulong,
+ pub st_pad2: [c_long; 2],
+ pub st_size: off_t,
+ pub st_pad3: c_long,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_blksize: blksize_t,
+ pub st_blocks: blkcnt_t,
+ pub st_pad5: [c_long; 14],
+ }
+}
+
+#[cfg(target_arch = "aarch64")]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::{c_long, c_int};
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i64;
+ pub type blksize_t = i32;
+ pub type ino_t = u64;
+ pub type nlink_t = u32;
+ pub type off_t = i64;
+ pub type time_t = i64;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub __pad1: dev_t,
+ pub st_size: off_t,
+ pub st_blksize: blksize_t,
+ pub __pad2: c_int,
+ pub st_blocks: blkcnt_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub __unused: [c_int; 2],
+ }
+}
+
+#[cfg(target_arch = "x86_64")]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::{c_long, c_int};
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i64;
+ pub type blksize_t = i64;
+ pub type ino_t = u64;
+ pub type nlink_t = u64;
+ pub type off_t = i64;
+ pub type time_t = i64;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_nlink: nlink_t,
+ pub st_mode: mode_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub __pad0: c_int,
+ pub st_rdev: dev_t,
+ pub st_size: off_t,
+ pub st_blksize: blksize_t,
+ pub st_blocks: blkcnt_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub __unused: [c_long; 3],
+ }
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! MacOS-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! MacOS-specific raw type definitions
+
+use os::raw::c_long;
+use os::unix::raw::{uid_t, gid_t};
+
+pub type blkcnt_t = i64;
+pub type blksize_t = i32;
+pub type dev_t = i32;
+pub type ino_t = u64;
+pub type mode_t = u16;
+pub type nlink_t = u16;
+pub type off_t = i64;
+pub type time_t = c_long;
+
+#[repr(C)]
+pub struct stat {
+ pub st_dev: dev_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_ino: ino_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_birthtime: time_t,
+ pub st_birthtime_nsec: c_long,
+ pub st_size: off_t,
+ pub st_blocks: blkcnt_t,
+ pub st_blksize: blksize_t,
+ pub st_flags: u32,
+ pub st_gen: u32,
+ pub st_lspare: i32,
+ pub st_qspare: [i64; 2],
+}
--- /dev/null
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! OS-specific functionality
+
+#![stable(feature = "os", since = "1.0.0")]
+#![allow(missing_docs, bad_style)]
+
+#[cfg(unix)] pub use sys::ext as unix;
+#[cfg(windows)] pub use sys::ext as windows;
+
+#[cfg(target_os = "android")] pub mod android;
+#[cfg(target_os = "bitrig")] pub mod bitrig;
+#[cfg(target_os = "dragonfly")] pub mod dragonfly;
+#[cfg(target_os = "freebsd")] pub mod freebsd;
+#[cfg(target_os = "ios")] pub mod ios;
+#[cfg(target_os = "linux")] pub mod linux;
+#[cfg(target_os = "macos")] pub mod macos;
+#[cfg(target_os = "nacl")] pub mod nacl;
+#[cfg(target_os = "openbsd")] pub mod openbsd;
+
+pub mod raw;
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Nacl-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Nacl-specific raw type definitions
+
+pub type dev_t = u64;
+pub type mode_t = u32;
+
+pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
+
+#[cfg(any(target_arch = "x86",
+ target_arch = "le32",
+ target_arch = "powerpc",
+ target_arch = "arm"))]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::{c_long, c_short};
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i32;
+ pub type blksize_t = i32;
+ pub type ino_t = u32;
+ pub type nlink_t = u32;
+ pub type off_t = i32;
+ pub type time_t = i32;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: dev_t,
+ pub __pad1: c_short,
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub __pad2: c_short,
+ pub st_size: off_t,
+ pub st_blksize: blksize_t,
+ pub st_blocks: blkcnt_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub __unused4: c_long,
+ pub __unused5: c_long,
+ }
+}
+
+#[cfg(any(target_arch = "mips",
+ target_arch = "mipsel"))]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::c_long;
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i32;
+ pub type blksize_t = i32;
+ pub type ino_t = u32;
+ pub type nlink_t = u32;
+ pub type off_t = i32;
+ pub type time_t = i32;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: c_ulong,
+ pub st_pad1: [c_long; 3],
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: c_ulong,
+ pub st_pad2: [c_long; 2],
+ pub st_size: off_t,
+ pub st_pad3: c_long,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_blksize: blksize_t,
+ pub st_blocks: blkcnt_t,
+ pub st_pad5: [c_long; 14],
+ }
+}
+
+#[cfg(target_arch = "aarch64")]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::{c_long, c_int};
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i64;
+ pub type blksize_t = i32;
+ pub type ino_t = u64;
+ pub type nlink_t = u32;
+ pub type off_t = i64;
+ pub type time_t = i64;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_mode: mode_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub __pad1: dev_t,
+ pub st_size: off_t,
+ pub st_blksize: blksize_t,
+ pub __pad2: c_int,
+ pub st_blocks: blkcnt_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub __unused: [c_int; 2],
+ }
+}
+
+#[cfg(target_arch = "x86_64")]
+mod arch {
+ use super::{dev_t, mode_t};
+ use os::raw::{c_long, c_int};
+ use os::unix::raw::{gid_t, uid_t};
+
+ pub type blkcnt_t = i64;
+ pub type blksize_t = i64;
+ pub type ino_t = u64;
+ pub type nlink_t = u64;
+ pub type off_t = i64;
+ pub type time_t = i64;
+
+ #[repr(C)]
+ pub struct stat {
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_nlink: nlink_t,
+ pub st_mode: mode_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub __pad0: c_int,
+ pub st_rdev: dev_t,
+ pub st_size: off_t,
+ pub st_blksize: blksize_t,
+ pub st_blocks: blkcnt_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub __unused: [c_long; 3],
+ }
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! OpenBSD-specific definitions
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub mod raw;
+
+pub mod fs {
+ pub use sys::fs2::MetadataExt;
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! OpenBSD-specific raw type definitions
+
+use os::raw::c_long;
+use os::unix::raw::{uid_t, gid_t, pid_t};
+
+pub type blkcnt_t = i64;
+pub type blksize_t = u32;
+pub type dev_t = i32;
+pub type fflags_t = u32; // type not declared, but struct stat have u_int32_t
+pub type ino_t = u64;
+pub type mode_t = u32;
+pub type nlink_t = u32;
+pub type off_t = i64;
+pub type time_t = i64;
+
+#[repr(C)]
+pub struct stat {
+ pub st_mode: mode_t,
+ pub st_dev: dev_t,
+ pub st_ino: ino_t,
+ pub st_nlink: nlink_t,
+ pub st_uid: uid_t,
+ pub st_gid: gid_t,
+ pub st_rdev: dev_t,
+ pub st_atime: time_t,
+ pub st_atime_nsec: c_long,
+ pub st_mtime: time_t,
+ pub st_mtime_nsec: c_long,
+ pub st_ctime: time_t,
+ pub st_ctime_nsec: c_long,
+ pub st_size: off_t,
+ pub st_blocks: blkcnt_t,
+ pub st_blksize: blksize_t,
+ pub st_flags: fflags_t,
+ pub st_gen: u32,
+ pub st_birthtime: time_t,
+ pub st_birthtime_nsec: c_long,
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Raw OS-specific types for the current platform/architecture
+
+#![unstable(feature = "raw_os", reason = "recently added API")]
+
+#[cfg(target_arch = "aarch64")] pub type c_char = u8;
+#[cfg(not(target_arch = "aarch64"))] pub type c_char = i8;
+pub type c_schar = i8;
+pub type c_uchar = u8;
+pub type c_short = i16;
+pub type c_ushort = u16;
+pub type c_int = i32;
+pub type c_uint = u32;
+#[cfg(any(target_pointer_width = "32", windows))] pub type c_long = i32;
+#[cfg(any(target_pointer_width = "32", windows))] pub type c_ulong = u32;
+#[cfg(all(target_pointer_width = "64", not(windows)))] pub type c_long = i64;
+#[cfg(all(target_pointer_width = "64", not(windows)))] pub type c_ulong = u64;
+pub type c_longlong = i64;
+pub type c_ulonglong = u64;
+pub type c_float = f32;
+pub type c_double = f64;
+
+/// Type used to construct void pointers for use with C.
+///
+/// This type is only useful as a pointer target. Do not use it as a
+/// return type for FFI functions which have the `void` return type in
+/// C. Use the unit type `()` or omit the return type instead.
+// NB: For LLVM to recognize the void pointer type and by extension
+// functions like malloc(), we need to have it represented as i8* in
+// LLVM bitcode. The enum used here ensures this and prevents misuse
+// of the "raw" type by only having private variants.. We need two
+// variants, because the compiler complains about the repr attribute
+// otherwise.
+#[repr(u8)]
+pub enum c_void {
+ #[doc(hidden)] __variant1,
+ #[doc(hidden)] __variant2,
+}
+
+#[cfg(test)]
+mod tests {
+ use any::TypeId;
+ use libc;
+ use mem;
+
+ macro_rules! ok {
+ ($($t:ident)*) => {$(
+ assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(),
+ "{} is wrong", stringify!($t));
+ )*}
+ }
+
+ macro_rules! ok_size {
+ ($($t:ident)*) => {$(
+ assert!(mem::size_of::<libc::$t>() == mem::size_of::<raw::$t>(),
+ "{} is wrong", stringify!($t));
+ )*}
+ }
+
+ #[test]
+ fn same() {
+ use os::raw;
+ ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong
+ c_longlong c_ulonglong c_float c_double);
+ }
+
+ #[cfg(unix)]
+ fn unix() {
+ {
+ use os::unix::raw;
+ ok!(uid_t gid_t dev_t ino_t mode_t nlink_t off_t blksize_t blkcnt_t);
+ }
+ {
+ use sys::platform::raw;
+ ok_size!(stat);
+ }
+ }
+
+ #[cfg(windows)]
+ fn windows() {
+ use os::windows::raw;
+ }
+}
pub fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
pub fn setgroups(ngroups: libc::c_int,
ptr: *const libc::c_void) -> libc::c_int;
+ pub fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
+ -> *mut libc::c_char;
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Experimental extensions to `std` for Unix platforms.
-//!
-//! For now, this module is limited to extracting file descriptors,
-//! but its functionality will grow over time.
-//!
-//! # Example
-//!
-//! ```no_run
-//! use std::fs::File;
-//! use std::os::unix::prelude::*;
-//!
-//! fn main() {
-//! let f = File::create("foo.txt").unwrap();
-//! let fd = f.as_raw_fd();
-//!
-//! // use fd with native unix bindings
-//! }
-//! ```
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-/// Unix-specific extensions to general I/O primitives
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod io {
- use fs;
- use libc;
- use net;
- use sys_common::{net2, AsInner, FromInner};
- use sys;
-
- /// Raw file descriptors.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub type RawFd = libc::c_int;
-
- /// A trait to extract the raw unix file descriptor from an underlying
- /// object.
- ///
- /// This is only available on unix platforms and must be imported in order
- /// to call the method. Windows platforms have a corresponding `AsRawHandle`
- /// and `AsRawSocket` set of traits.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait AsRawFd {
- /// Extracts the raw file descriptor.
- ///
- /// This method does **not** pass ownership of the raw file descriptor
- /// to the caller. The descriptor is only guarantee to be valid while
- /// the original object has not yet been destroyed.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_raw_fd(&self) -> RawFd;
- }
-
- /// A trait to express the ability to construct an object from a raw file
- /// descriptor.
- #[unstable(feature = "from_raw_os",
- reason = "recent addition to std::os::unix::io")]
- pub trait FromRawFd {
- /// Constructs a new instances of `Self` from the given raw file
- /// descriptor.
- ///
- /// This function **consumes ownership** of the specified file
- /// descriptor. The returned object will take responsibility for closing
- /// it when the object goes out of scope.
- ///
- /// This function is also unsafe as the primitives currently returned
- /// have the contract that they are the sole owner of the file
- /// descriptor they are wrapping. Usage of this function could
- /// accidentally allow violating this contract which can cause memory
- /// unsafety in code that relies on it being true.
- unsafe fn from_raw_fd(fd: RawFd) -> Self;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawFd for fs::File {
- fn as_raw_fd(&self) -> RawFd {
- self.as_inner().fd().raw()
- }
- }
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawFd for fs::File {
- unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
- fs::File::from_inner(sys::fs2::File::from_inner(fd))
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawFd for net::TcpStream {
- fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
- }
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawFd for net::TcpListener {
- fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
- }
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawFd for net::UdpSocket {
- fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
- }
-
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawFd for net::TcpStream {
- unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
- let socket = sys::net::Socket::from_inner(fd);
- net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
- }
- }
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawFd for net::TcpListener {
- unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
- let socket = sys::net::Socket::from_inner(fd);
- net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
- }
- }
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawFd for net::UdpSocket {
- unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
- let socket = sys::net::Socket::from_inner(fd);
- net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OsString and OsStr
-////////////////////////////////////////////////////////////////////////////////
-
-/// Unix-specific extension to the primitives in the `std::ffi` module
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod ffi {
- use ffi::{OsStr, OsString};
- use mem;
- use prelude::v1::*;
- use sys::os_str::Buf;
- use sys_common::{FromInner, IntoInner, AsInner};
-
- /// Unix-specific extensions to `OsString`.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait OsStringExt {
- /// Creates an `OsString` from a byte vector.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_vec(vec: Vec<u8>) -> Self;
-
- /// Yields the underlying byte vector of this `OsString`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn into_vec(self) -> Vec<u8>;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl OsStringExt for OsString {
- fn from_vec(vec: Vec<u8>) -> OsString {
- FromInner::from_inner(Buf { inner: vec })
- }
- fn into_vec(self) -> Vec<u8> {
- self.into_inner().inner
- }
- }
-
- /// Unix-specific extensions to `OsStr`.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait OsStrExt {
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_bytes(slice: &[u8]) -> &Self;
-
- /// Gets the underlying byte view of the `OsStr` slice.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_bytes(&self) -> &[u8];
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl OsStrExt for OsStr {
- fn from_bytes(slice: &[u8]) -> &OsStr {
- unsafe { mem::transmute(slice) }
- }
- fn as_bytes(&self) -> &[u8] {
- &self.as_inner().inner
- }
- }
-}
-
-/// Unix-specific extensions to primitives in the `std::fs` module.
-#[unstable(feature = "fs_ext",
- reason = "may want a more useful mode abstraction")]
-pub mod fs {
- use sys;
- use sys_common::{FromInner, AsInner, AsInnerMut};
- use fs::{Permissions, OpenOptions};
- use path::Path;
- use convert::AsRef;
- use io;
-
- /// Unix-specific extensions to `Permissions`
- pub trait PermissionsExt {
- fn mode(&self) -> i32;
- fn set_mode(&mut self, mode: i32);
- }
-
- impl PermissionsExt for Permissions {
- fn mode(&self) -> i32 { self.as_inner().mode() }
-
- fn set_mode(&mut self, mode: i32) {
- *self = FromInner::from_inner(FromInner::from_inner(mode));
- }
- }
-
- /// Unix-specific extensions to `OpenOptions`
- pub trait OpenOptionsExt {
- /// Sets the mode bits that a new file will be created with.
- ///
- /// If a new file is created as part of a `File::open_opts` call then this
- /// specified `mode` will be used as the permission bits for the new file.
- fn mode(&mut self, mode: i32) -> &mut Self;
- }
-
- impl OpenOptionsExt for OpenOptions {
- fn mode(&mut self, mode: i32) -> &mut OpenOptions {
- self.as_inner_mut().mode(mode); self
- }
- }
-
- /// Creates a new symbolic link on the filesystem.
- ///
- /// The `dst` path will be a symbolic link pointing to the `src` path.
- ///
- /// # Note
- ///
- /// On Windows, you must specify whether a symbolic link points to a file
- /// or directory. Use `os::windows::fs::symlink_file` to create a
- /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
- /// symbolic link to a directory. Additionally, the process must have
- /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
- /// symbolic link.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(fs_ext)]
- /// use std::os::unix::fs;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// try!(fs::symlink("a.txt", "b.txt"));
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
- {
- sys::fs2::symlink(src.as_ref(), dst.as_ref())
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Process and Command
-////////////////////////////////////////////////////////////////////////////////
-
-/// Unix-specific extensions to primitives in the `std::process` module.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod process {
- use prelude::v1::*;
- use libc::{uid_t, gid_t};
- use process;
- use sys;
- use sys_common::{AsInnerMut, AsInner};
-
- /// Unix-specific extensions to the `std::process::Command` builder
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait CommandExt {
- /// Sets the child process's user id. This translates to a
- /// `setuid` call in the child process. Failure in the `setuid`
- /// call will cause the spawn to fail.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn uid(&mut self, id: uid_t) -> &mut process::Command;
-
- /// Similar to `uid`, but sets the group id of the child process. This has
- /// the same semantics as the `uid` field.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn gid(&mut self, id: gid_t) -> &mut process::Command;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl CommandExt for process::Command {
- fn uid(&mut self, id: uid_t) -> &mut process::Command {
- self.as_inner_mut().uid = Some(id);
- self
- }
-
- fn gid(&mut self, id: gid_t) -> &mut process::Command {
- self.as_inner_mut().gid = Some(id);
- self
- }
- }
-
- /// Unix-specific extensions to `std::process::ExitStatus`
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait ExitStatusExt {
- /// If the process was terminated by a signal, returns that signal.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn signal(&self) -> Option<i32>;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl ExitStatusExt for process::ExitStatus {
- fn signal(&self) -> Option<i32> {
- match *self.as_inner() {
- sys::process2::ExitStatus::Signal(s) => Some(s),
- _ => None
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Prelude
-////////////////////////////////////////////////////////////////////////////////
-
-/// A prelude for conveniently writing platform-specific code.
-///
-/// Includes all extension traits, and some important type definitions.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod prelude {
- #[doc(no_inline)]
- pub use super::io::{RawFd, AsRawFd};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::ffi::{OsStrExt, OsStringExt};
- #[doc(no_inline)]
- pub use super::fs::{PermissionsExt, OpenOptionsExt};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::process::{CommandExt, ExitStatusExt};
-}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unix-specific extension to the primitives in the `std::ffi` module
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use ffi::{OsStr, OsString};
+use mem;
+use prelude::v1::*;
+use sys::os_str::Buf;
+use sys_common::{FromInner, IntoInner, AsInner};
+
+/// Unix-specific extensions to `OsString`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStringExt {
+ /// Creates an `OsString` from a byte vector.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn from_vec(vec: Vec<u8>) -> Self;
+
+ /// Yields the underlying byte vector of this `OsString`.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn into_vec(self) -> Vec<u8>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStringExt for OsString {
+ fn from_vec(vec: Vec<u8>) -> OsString {
+ FromInner::from_inner(Buf { inner: vec })
+ }
+ fn into_vec(self) -> Vec<u8> {
+ self.into_inner().inner
+ }
+}
+
+/// Unix-specific extensions to `OsStr`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStrExt {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn from_bytes(slice: &[u8]) -> &Self;
+
+ /// Gets the underlying byte view of the `OsStr` slice.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_bytes(&self) -> &[u8];
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStrExt for OsStr {
+ fn from_bytes(slice: &[u8]) -> &OsStr {
+ unsafe { mem::transmute(slice) }
+ }
+ fn as_bytes(&self) -> &[u8] {
+ &self.as_inner().inner
+ }
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unix-specific extensions to primitives in the `std::fs` module.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use prelude::v1::*;
+
+use fs::{self, Permissions, OpenOptions};
+use io;
+use mem;
+use os::raw::c_long;
+use os::unix::raw;
+use path::Path;
+use sys::platform;
+use sys;
+use sys_common::{FromInner, AsInner, AsInnerMut};
+
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const USER_READ: raw::mode_t = 0o400;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const USER_WRITE: raw::mode_t = 0o200;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const USER_EXECUTE: raw::mode_t = 0o100;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const USER_RWX: raw::mode_t = 0o700;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const GROUP_READ: raw::mode_t = 0o040;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const GROUP_WRITE: raw::mode_t = 0o020;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const GROUP_EXECUTE: raw::mode_t = 0o010;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const GROUP_RWX: raw::mode_t = 0o070;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const OTHER_READ: raw::mode_t = 0o004;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const OTHER_WRITE: raw::mode_t = 0o002;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const OTHER_EXECUTE: raw::mode_t = 0o001;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const OTHER_RWX: raw::mode_t = 0o007;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const ALL_READ: raw::mode_t = 0o444;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const ALL_WRITE: raw::mode_t = 0o222;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const ALL_EXECUTE: raw::mode_t = 0o111;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const ALL_RWX: raw::mode_t = 0o777;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const SETUID: raw::mode_t = 0o4000;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const SETGID: raw::mode_t = 0o2000;
+#[unstable(feature = "fs_mode", reason = "recently added API")]
+pub const STICKY_BIT: raw::mode_t = 0o1000;
+
+/// Unix-specific extensions to `Permissions`
+#[unstable(feature = "fs_ext",
+ reason = "may want a more useful mode abstraction")]
+pub trait PermissionsExt {
+ fn mode(&self) -> raw::mode_t;
+ fn set_mode(&mut self, mode: raw::mode_t);
+ fn from_mode(mode: raw::mode_t) -> Self;
+}
+
+impl PermissionsExt for Permissions {
+ fn mode(&self) -> raw::mode_t { self.as_inner().mode() }
+
+ fn set_mode(&mut self, mode: raw::mode_t) {
+ *self = FromInner::from_inner(FromInner::from_inner(mode));
+ }
+
+ fn from_mode(mode: raw::mode_t) -> Permissions {
+ FromInner::from_inner(FromInner::from_inner(mode))
+ }
+}
+
+/// Unix-specific extensions to `OpenOptions`
+#[unstable(feature = "fs_ext",
+ reason = "may want a more useful mode abstraction")]
+pub trait OpenOptionsExt {
+ /// Sets the mode bits that a new file will be created with.
+ ///
+ /// If a new file is created as part of a `File::open_opts` call then this
+ /// specified `mode` will be used as the permission bits for the new file.
+ fn mode(&mut self, mode: raw::mode_t) -> &mut Self;
+}
+
+impl OpenOptionsExt for OpenOptions {
+ fn mode(&mut self, mode: raw::mode_t) -> &mut OpenOptions {
+ self.as_inner_mut().mode(mode); self
+ }
+}
+
+#[unstable(feature = "metadata_ext", reason = "recently added API")]
+pub struct Metadata(sys::fs2::FileAttr);
+
+#[unstable(feature = "metadata_ext", reason = "recently added API")]
+pub trait MetadataExt {
+ fn as_raw(&self) -> &Metadata;
+}
+
+impl MetadataExt for fs::Metadata {
+ fn as_raw(&self) -> &Metadata {
+ let inner: &sys::fs2::FileAttr = self.as_inner();
+ unsafe { mem::transmute(inner) }
+ }
+}
+
+impl AsInner<platform::raw::stat> for Metadata {
+ fn as_inner(&self) -> &platform::raw::stat { self.0.as_inner() }
+}
+
+// Hm, why are there casts here to the returned type, shouldn't the types always
+// be the same? Right you are! Turns out, however, on android at least the types
+// in the raw `stat` structure are not the same as the types being returned. Who
+// knew!
+//
+// As a result to make sure this compiles for all platforms we do the manual
+// casts and rely on manual lowering to `stat` if the raw type is desired.
+#[unstable(feature = "metadata_ext", reason = "recently added API")]
+impl Metadata {
+ pub fn dev(&self) -> raw::dev_t { self.0.raw().st_dev as raw::dev_t }
+ pub fn ino(&self) -> raw::ino_t { self.0.raw().st_ino as raw::ino_t }
+ pub fn mode(&self) -> raw::mode_t { self.0.raw().st_mode as raw::mode_t }
+ pub fn nlink(&self) -> raw::nlink_t { self.0.raw().st_nlink as raw::nlink_t }
+ pub fn uid(&self) -> raw::uid_t { self.0.raw().st_uid as raw::uid_t }
+ pub fn gid(&self) -> raw::gid_t { self.0.raw().st_gid as raw::gid_t }
+ pub fn rdev(&self) -> raw::dev_t { self.0.raw().st_rdev as raw::dev_t }
+ pub fn size(&self) -> raw::off_t { self.0.raw().st_size as raw::off_t }
+ pub fn atime(&self) -> raw::time_t { self.0.raw().st_atime }
+ pub fn atime_nsec(&self) -> c_long { self.0.raw().st_atime }
+ pub fn mtime(&self) -> raw::time_t { self.0.raw().st_mtime }
+ pub fn mtime_nsec(&self) -> c_long { self.0.raw().st_mtime }
+ pub fn ctime(&self) -> raw::time_t { self.0.raw().st_ctime }
+ pub fn ctime_nsec(&self) -> c_long { self.0.raw().st_ctime }
+
+ pub fn blksize(&self) -> raw::blksize_t {
+ self.0.raw().st_blksize as raw::blksize_t
+ }
+ pub fn blocks(&self) -> raw::blkcnt_t {
+ self.0.raw().st_blocks as raw::blkcnt_t
+ }
+}
+
+#[unstable(feature = "dir_entry_ext", reason = "recently added API")]
+pub trait DirEntryExt {
+ fn ino(&self) -> raw::ino_t;
+}
+
+impl DirEntryExt for fs::DirEntry {
+ fn ino(&self) -> raw::ino_t { self.as_inner().ino() }
+}
+
+/// Creates a new symbolic link on the filesystem.
+///
+/// The `dst` path will be a symbolic link pointing to the `src` path.
+///
+/// # Note
+///
+/// On Windows, you must specify whether a symbolic link points to a file
+/// or directory. Use `os::windows::fs::symlink_file` to create a
+/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
+/// symbolic link to a directory. Additionally, the process must have
+/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
+/// symbolic link.
+///
+/// # Examples
+///
+/// ```
+/// use std::os::unix::fs;
+///
+/// # fn foo() -> std::io::Result<()> {
+/// try!(fs::symlink("a.txt", "b.txt"));
+/// # Ok(())
+/// # }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
+{
+ sys::fs2::symlink(src.as_ref(), dst.as_ref())
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unix-specific extensions to general I/O primitives
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use fs;
+use net;
+use os::raw;
+use sys;
+use sys_common::{net2, AsInner, FromInner};
+
+/// Raw file descriptors.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type RawFd = raw::c_int;
+
+/// A trait to extract the raw unix file descriptor from an underlying
+/// object.
+///
+/// This is only available on unix platforms and must be imported in order
+/// to call the method. Windows platforms have a corresponding `AsRawHandle`
+/// and `AsRawSocket` set of traits.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait AsRawFd {
+ /// Extracts the raw file descriptor.
+ ///
+ /// This method does **not** pass ownership of the raw file descriptor
+ /// to the caller. The descriptor is only guarantee to be valid while
+ /// the original object has not yet been destroyed.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_raw_fd(&self) -> RawFd;
+}
+
+/// A trait to express the ability to construct an object from a raw file
+/// descriptor.
+#[unstable(feature = "from_raw_os",
+ reason = "recent addition to std::os::unix::io")]
+pub trait FromRawFd {
+ /// Constructs a new instances of `Self` from the given raw file
+ /// descriptor.
+ ///
+ /// This function **consumes ownership** of the specified file
+ /// descriptor. The returned object will take responsibility for closing
+ /// it when the object goes out of scope.
+ ///
+ /// This function is also unsafe as the primitives currently returned
+ /// have the contract that they are the sole owner of the file
+ /// descriptor they are wrapping. Usage of this function could
+ /// accidentally allow violating this contract which can cause memory
+ /// unsafety in code that relies on it being true.
+ unsafe fn from_raw_fd(fd: RawFd) -> Self;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for fs::File {
+ fn as_raw_fd(&self) -> RawFd {
+ self.as_inner().fd().raw()
+ }
+}
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawFd for fs::File {
+ unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
+ fs::File::from_inner(sys::fs2::File::from_inner(fd))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for net::TcpStream {
+ fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for net::TcpListener {
+ fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for net::UdpSocket {
+ fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+}
+
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawFd for net::TcpStream {
+ unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
+ let socket = sys::net::Socket::from_inner(fd);
+ net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
+ }
+}
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawFd for net::TcpListener {
+ unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
+ let socket = sys::net::Socket::from_inner(fd);
+ net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
+ }
+}
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawFd for net::UdpSocket {
+ unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
+ let socket = sys::net::Socket::from_inner(fd);
+ net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
+ }
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Experimental extensions to `std` for Unix platforms.
+//!
+//! For now, this module is limited to extracting file descriptors,
+//! but its functionality will grow over time.
+//!
+//! # Example
+//!
+//! ```no_run
+//! use std::fs::File;
+//! use std::os::unix::prelude::*;
+//!
+//! fn main() {
+//! let f = File::create("foo.txt").unwrap();
+//! let fd = f.as_raw_fd();
+//!
+//! // use fd with native unix bindings
+//! }
+//! ```
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+pub mod io;
+pub mod ffi;
+pub mod fs;
+pub mod process;
+pub mod raw;
+
+/// A prelude for conveniently writing platform-specific code.
+///
+/// Includes all extension traits, and some important type definitions.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod prelude {
+ #[doc(no_inline)]
+ pub use super::io::{RawFd, AsRawFd};
+ #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+ pub use super::ffi::{OsStrExt, OsStringExt};
+ #[doc(no_inline)]
+ pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt};
+ #[doc(no_inline)]
+ pub use super::fs::{DirEntryExt};
+ #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+ pub use super::process::{CommandExt, ExitStatusExt};
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unix-specific extensions to primitives in the `std::process` module.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use os::unix::raw::{uid_t, gid_t};
+use prelude::v1::*;
+use process;
+use sys;
+use sys_common::{AsInnerMut, AsInner};
+
+/// Unix-specific extensions to the `std::process::Command` builder
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait CommandExt {
+ /// Sets the child process's user id. This translates to a
+ /// `setuid` call in the child process. Failure in the `setuid`
+ /// call will cause the spawn to fail.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn uid(&mut self, id: uid_t) -> &mut process::Command;
+
+ /// Similar to `uid`, but sets the group id of the child process. This has
+ /// the same semantics as the `uid` field.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gid(&mut self, id: gid_t) -> &mut process::Command;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl CommandExt for process::Command {
+ fn uid(&mut self, id: uid_t) -> &mut process::Command {
+ self.as_inner_mut().uid = Some(id);
+ self
+ }
+
+ fn gid(&mut self, id: gid_t) -> &mut process::Command {
+ self.as_inner_mut().gid = Some(id);
+ self
+ }
+}
+
+/// Unix-specific extensions to `std::process::ExitStatus`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait ExitStatusExt {
+ /// If the process was terminated by a signal, returns that signal.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn signal(&self) -> Option<i32>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ExitStatusExt for process::ExitStatus {
+ fn signal(&self) -> Option<i32> {
+ match *self.as_inner() {
+ sys::process2::ExitStatus::Signal(s) => Some(s),
+ _ => None
+ }
+ }
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unix-specific primitives available on all unix platforms
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+pub type uid_t = u32;
+pub type gid_t = u32;
+pub type pid_t = i32;
+
+#[doc(inline)]
+pub use sys::platform::raw::{dev_t, ino_t, mode_t, nlink_t, off_t, blksize_t};
+#[doc(inline)]
+pub use sys::platform::raw::{blkcnt_t, time_t};
use ptr;
use sync::Arc;
use sys::fd::FileDesc;
+use sys::platform::raw;
use sys::{c, cvt, cvt_r};
-use sys_common::FromInner;
+use sys_common::{AsInner, FromInner};
use vec::Vec;
pub struct File(FileDesc);
pub struct FileAttr {
- stat: libc::stat,
+ stat: raw::stat,
}
pub struct ReadDir {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FilePermissions { mode: mode_t }
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+pub struct FileType { mode: mode_t }
+
impl FileAttr {
- pub fn is_dir(&self) -> bool {
- (self.stat.st_mode as mode_t) & libc::S_IFMT == libc::S_IFDIR
- }
- pub fn is_file(&self) -> bool {
- (self.stat.st_mode as mode_t) & libc::S_IFMT == libc::S_IFREG
- }
pub fn size(&self) -> u64 { self.stat.st_size as u64 }
pub fn perm(&self) -> FilePermissions {
FilePermissions { mode: (self.stat.st_mode as mode_t) & 0o777 }
self.mktime(self.stat.st_mtime as u64, self.stat.st_mtime_nsec as u64)
}
+ pub fn file_type(&self) -> FileType {
+ FileType { mode: self.stat.st_mode as mode_t }
+ }
+
+ pub fn raw(&self) -> &raw::stat { &self.stat }
+
// times are in milliseconds (currently)
fn mktime(&self, secs: u64, nsecs: u64) -> u64 {
secs * 1000 + nsecs / 1000000
}
}
+impl AsInner<raw::stat> for FileAttr {
+ fn as_inner(&self) -> &raw::stat { &self.stat }
+}
+
+#[unstable(feature = "metadata_ext", reason = "recently added API")]
+pub trait MetadataExt {
+ fn as_raw_stat(&self) -> &raw::stat;
+}
+
+impl MetadataExt for ::fs::Metadata {
+ fn as_raw_stat(&self) -> &raw::stat { &self.as_inner().stat }
+}
+
+impl MetadataExt for ::os::unix::fs::Metadata {
+ fn as_raw_stat(&self) -> &raw::stat { self.as_inner() }
+}
+
impl FilePermissions {
pub fn readonly(&self) -> bool { self.mode & 0o222 == 0 }
pub fn set_readonly(&mut self, readonly: bool) {
self.mode |= 0o222;
}
}
- pub fn mode(&self) -> i32 { self.mode as i32 }
+ pub fn mode(&self) -> raw::mode_t { self.mode }
+}
+
+impl FileType {
+ pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) }
+ pub fn is_file(&self) -> bool { self.is(libc::S_IFREG) }
+ pub fn is_symlink(&self) -> bool { self.is(libc::S_IFLNK) }
+
+ fn is(&self, mode: mode_t) -> bool { self.mode & libc::S_IFMT == mode }
}
-impl FromInner<i32> for FilePermissions {
- fn from_inner(mode: i32) -> FilePermissions {
+impl FromInner<raw::mode_t> for FilePermissions {
+ fn from_inner(mode: raw::mode_t) -> FilePermissions {
FilePermissions { mode: mode as mode_t }
}
}
self.root.join(<OsStr as OsStrExt>::from_bytes(self.name_bytes()))
}
+ pub fn file_name(&self) -> OsString {
+ OsStr::from_bytes(self.name_bytes()).to_os_string()
+ }
+
+ pub fn metadata(&self) -> io::Result<FileAttr> {
+ lstat(&self.path())
+ }
+
+ pub fn file_type(&self) -> io::Result<FileType> {
+ extern {
+ fn rust_dir_get_mode(ptr: *mut libc::dirent_t) -> c_int;
+ }
+ unsafe {
+ match rust_dir_get_mode(self.dirent()) {
+ -1 => lstat(&self.path()).map(|m| m.file_type()),
+ n => Ok(FileType { mode: n as mode_t }),
+ }
+ }
+ }
+
+ pub fn ino(&self) -> raw::ino_t {
+ extern {
+ fn rust_dir_get_ino(ptr: *mut libc::dirent_t) -> raw::ino_t;
+ }
+ unsafe { rust_dir_get_ino(self.dirent()) }
+ }
+
fn name_bytes(&self) -> &[u8] {
extern {
fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
self.flag(libc::O_CREAT, create);
}
- pub fn mode(&mut self, mode: i32) {
+ pub fn mode(&mut self, mode: raw::mode_t) {
self.mode = mode as mode_t;
}
pub fn into_fd(self) -> FileDesc { self.0 }
pub fn file_attr(&self) -> io::Result<FileAttr> {
- let mut stat: libc::stat = unsafe { mem::zeroed() };
- try!(cvt(unsafe { libc::fstat(self.0.raw(), &mut stat) }));
+ let mut stat: raw::stat = unsafe { mem::zeroed() };
+ try!(cvt(unsafe {
+ libc::fstat(self.0.raw(), &mut stat as *mut _ as *mut _)
+ }));
Ok(FileAttr { stat: stat })
}
pub fn stat(p: &Path) -> io::Result<FileAttr> {
let p = try!(cstr(p));
- let mut stat: libc::stat = unsafe { mem::zeroed() };
- try!(cvt(unsafe { libc::stat(p.as_ptr(), &mut stat) }));
+ let mut stat: raw::stat = unsafe { mem::zeroed() };
+ try!(cvt(unsafe {
+ libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _)
+ }));
Ok(FileAttr { stat: stat })
}
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
let p = try!(cstr(p));
- let mut stat: libc::stat = unsafe { mem::zeroed() };
- try!(cvt(unsafe { libc::lstat(p.as_ptr(), &mut stat) }));
+ let mut stat: raw::stat = unsafe { mem::zeroed() };
+ try!(cvt(unsafe {
+ libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
+ }));
Ok(FileAttr { stat: stat })
}
try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) }));
Ok(())
}
+
+pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
+ let path = try!(CString::new(p.as_os_str().as_bytes()));
+ let mut buf = vec![0u8; 16 * 1024];
+ unsafe {
+ let r = c::realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _);
+ if r.is_null() {
+ return Err(io::Error::last_os_error())
+ }
+ }
+ let p = buf.iter().position(|i| *i == 0).unwrap();
+ buf.truncate(p);
+ Ok(PathBuf::from(OsString::from_vec(buf)))
+}
use num::One;
use ops::Neg;
+#[cfg(target_os = "android")] pub use os::android as platform;
+#[cfg(target_os = "bitrig")] pub use os::bitrig as platform;
+#[cfg(target_os = "dragonfly")] pub use os::dragonfly as platform;
+#[cfg(target_os = "freebsd")] pub use os::freebsd as platform;
+#[cfg(target_os = "ios")] pub use os::ios as platform;
+#[cfg(target_os = "linux")] pub use os::linux as platform;
+#[cfg(target_os = "macos")] pub use os::macos as platform;
+#[cfg(target_os = "nacl")] pub use os::nacl as platform;
+#[cfg(target_os = "openbsd")] pub use os::openbsd as platform;
+
pub mod backtrace;
pub mod c;
pub mod condvar;
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Experimental extensions to `std` for Windows.
-//!
-//! For now, this module is limited to extracting handles, file
-//! descriptors, and sockets, but its functionality will grow over
-//! time.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod io {
- use fs;
- use libc;
- use net;
- use sys_common::{net2, AsInner, FromInner};
- use sys;
-
- /// Raw HANDLEs.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub type RawHandle = libc::HANDLE;
-
- /// Raw SOCKETs.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub type RawSocket = libc::SOCKET;
-
- /// Extract raw handles.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait AsRawHandle {
- /// Extracts the raw handle, without taking any ownership.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_raw_handle(&self) -> RawHandle;
- }
-
- /// Construct I/O objects from raw handles.
- #[unstable(feature = "from_raw_os",
- reason = "recent addition to the std::os::windows::io module")]
- pub trait FromRawHandle {
- /// Constructs a new I/O object from the specified raw handle.
- ///
- /// This function will **consume ownership** of the handle given,
- /// passing responsibility for closing the handle to the returned
- /// object.
- ///
- /// This function is also unsafe as the primitives currently returned
- /// have the contract that they are the sole owner of the file
- /// descriptor they are wrapping. Usage of this function could
- /// accidentally allow violating this contract which can cause memory
- /// unsafety in code that relies on it being true.
- unsafe fn from_raw_handle(handle: RawHandle) -> Self;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawHandle for fs::File {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw()
- }
- }
-
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawHandle for fs::File {
- unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
- fs::File::from_inner(sys::fs2::File::from_inner(handle))
- }
- }
-
- /// Extract raw sockets.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait AsRawSocket {
- /// Extracts the underlying raw socket from this object.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_raw_socket(&self) -> RawSocket;
- }
-
- /// Create I/O objects from raw sockets.
- #[unstable(feature = "from_raw_os", reason = "recent addition to module")]
- pub trait FromRawSocket {
- /// Creates a new I/O object from the given raw socket.
- ///
- /// This function will **consume ownership** of the socket provided and
- /// it will be closed when the returned object goes out of scope.
- ///
- /// This function is also unsafe as the primitives currently returned
- /// have the contract that they are the sole owner of the file
- /// descriptor they are wrapping. Usage of this function could
- /// accidentally allow violating this contract which can cause memory
- /// unsafety in code that relies on it being true.
- unsafe fn from_raw_socket(sock: RawSocket) -> Self;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawSocket for net::TcpStream {
- fn as_raw_socket(&self) -> RawSocket {
- *self.as_inner().socket().as_inner()
- }
- }
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawSocket for net::TcpListener {
- fn as_raw_socket(&self) -> RawSocket {
- *self.as_inner().socket().as_inner()
- }
- }
- #[stable(feature = "rust1", since = "1.0.0")]
- impl AsRawSocket for net::UdpSocket {
- fn as_raw_socket(&self) -> RawSocket {
- *self.as_inner().socket().as_inner()
- }
- }
-
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawSocket for net::TcpStream {
- unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
- let sock = sys::net::Socket::from_inner(sock);
- net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
- }
- }
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawSocket for net::TcpListener {
- unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
- let sock = sys::net::Socket::from_inner(sock);
- net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
- }
- }
- #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
- impl FromRawSocket for net::UdpSocket {
- unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
- let sock = sys::net::Socket::from_inner(sock);
- net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
- }
- }
-}
-
-/// Windows-specific extensions to the primitives in the `std::ffi` module.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod ffi {
- use ffi::{OsString, OsStr};
- use sys::os_str::Buf;
- use sys_common::wtf8::Wtf8Buf;
- use sys_common::{FromInner, AsInner};
-
- pub use sys_common::wtf8::EncodeWide;
-
- /// Windows-specific extensions to `OsString`.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait OsStringExt {
- /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
- /// 16-bit code units.
- ///
- /// This is lossless: calling `.encode_wide()` on the resulting string
- /// will always return the original code units.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_wide(wide: &[u16]) -> Self;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl OsStringExt for OsString {
- fn from_wide(wide: &[u16]) -> OsString {
- FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
- }
- }
-
- /// Windows-specific extensions to `OsStr`.
- #[stable(feature = "rust1", since = "1.0.0")]
- pub trait OsStrExt {
- /// Re-encodes an `OsStr` as a wide character sequence,
- /// i.e. potentially ill-formed UTF-16.
- ///
- /// This is lossless. Note that the encoding does not include a final
- /// null.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn encode_wide(&self) -> EncodeWide;
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- impl OsStrExt for OsStr {
- fn encode_wide(&self) -> EncodeWide {
- self.as_inner().inner.encode_wide()
- }
- }
-}
-
-/// Windows-specific extensions for the primitives in `std::fs`
-#[unstable(feature = "fs_ext", reason = "may require more thought/methods")]
-pub mod fs {
- use fs::OpenOptions;
- use sys;
- use sys_common::AsInnerMut;
- use path::Path;
- use convert::AsRef;
- use io;
-
- /// Windows-specific extensions to `OpenOptions`
- pub trait OpenOptionsExt {
- /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
- /// with the specified value.
- fn desired_access(&mut self, access: i32) -> &mut Self;
-
- /// Overrides the `dwCreationDisposition` argument to the call to
- /// `CreateFile` with the specified value.
- ///
- /// This will override any values of the standard `create` flags, for
- /// example.
- fn creation_disposition(&mut self, val: i32) -> &mut Self;
-
- /// Overrides the `dwFlagsAndAttributes` argument to the call to
- /// `CreateFile` with the specified value.
- ///
- /// This will override any values of the standard flags on the
- /// `OpenOptions` structure.
- fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
-
- /// Overrides the `dwShareMode` argument to the call to `CreateFile` with
- /// the specified value.
- ///
- /// This will override any values of the standard flags on the
- /// `OpenOptions` structure.
- fn share_mode(&mut self, val: i32) -> &mut Self;
- }
-
- impl OpenOptionsExt for OpenOptions {
- fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
- self.as_inner_mut().desired_access(access); self
- }
- fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
- self.as_inner_mut().creation_disposition(access); self
- }
- fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
- self.as_inner_mut().flags_and_attributes(access); self
- }
- fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
- self.as_inner_mut().share_mode(access); self
- }
- }
-
- /// Creates a new file symbolic link on the filesystem.
- ///
- /// The `dst` path will be a file symbolic link pointing to the `src`
- /// path.
- ///
- /// # Examples
- ///
- /// ```ignore
- /// #![feature(fs_ext)]
- /// use std::os::windows::fs;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// try!(fs::symlink_file("a.txt", "b.txt"));
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
- -> io::Result<()>
- {
- sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), false)
- }
-
- /// Creates a new directory symlink on the filesystem.
- ///
- /// The `dst` path will be a directory symbolic link pointing to the `src`
- /// path.
- ///
- /// # Examples
- ///
- /// ```ignore
- /// #![feature(fs_ext)]
- /// use std::os::windows::fs;
- ///
- /// # fn foo() -> std::io::Result<()> {
- /// try!(fs::symlink_file("a", "b"));
- /// # Ok(())
- /// # }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>> (src: P, dst: Q)
- -> io::Result<()>
- {
- sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), true)
- }
-}
-
-/// A prelude for conveniently writing platform-specific code.
-///
-/// Includes all extension traits, and some important type definitions.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod prelude {
- #[doc(no_inline)]
- pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::ffi::{OsStrExt, OsStringExt};
- #[doc(no_inline)]
- pub use super::fs::OpenOptionsExt;
-}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Windows-specific extensions to the primitives in the `std::ffi` module.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use ffi::{OsString, OsStr};
+use sys::os_str::Buf;
+use sys_common::wtf8::Wtf8Buf;
+use sys_common::{FromInner, AsInner};
+
+pub use sys_common::wtf8::EncodeWide;
+
+/// Windows-specific extensions to `OsString`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStringExt {
+ /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
+ /// 16-bit code units.
+ ///
+ /// This is lossless: calling `.encode_wide()` on the resulting string
+ /// will always return the original code units.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn from_wide(wide: &[u16]) -> Self;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStringExt for OsString {
+ fn from_wide(wide: &[u16]) -> OsString {
+ FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
+ }
+}
+
+/// Windows-specific extensions to `OsStr`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStrExt {
+ /// Re-encodes an `OsStr` as a wide character sequence,
+ /// i.e. potentially ill-formed UTF-16.
+ ///
+ /// This is lossless. Note that the encoding does not include a final
+ /// null.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn encode_wide(&self) -> EncodeWide;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStrExt for OsStr {
+ fn encode_wide(&self) -> EncodeWide {
+ self.as_inner().inner.encode_wide()
+ }
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Windows-specific extensions for the primitives in `std::fs`
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use prelude::v1::*;
+
+use fs::{OpenOptions, Metadata};
+use io;
+use path::Path;
+use sys;
+use sys_common::{AsInnerMut, AsInner};
+
+/// Windows-specific extensions to `OpenOptions`
+#[unstable(feature = "fs_ext", reason = "may require more thought/methods")]
+pub trait OpenOptionsExt {
+ /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
+ /// with the specified value.
+ fn desired_access(&mut self, access: i32) -> &mut Self;
+
+ /// Overrides the `dwCreationDisposition` argument to the call to
+ /// `CreateFile` with the specified value.
+ ///
+ /// This will override any values of the standard `create` flags, for
+ /// example.
+ fn creation_disposition(&mut self, val: i32) -> &mut Self;
+
+ /// Overrides the `dwFlagsAndAttributes` argument to the call to
+ /// `CreateFile` with the specified value.
+ ///
+ /// This will override any values of the standard flags on the
+ /// `OpenOptions` structure.
+ fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
+
+ /// Overrides the `dwShareMode` argument to the call to `CreateFile` with
+ /// the specified value.
+ ///
+ /// This will override any values of the standard flags on the
+ /// `OpenOptions` structure.
+ fn share_mode(&mut self, val: i32) -> &mut Self;
+}
+
+impl OpenOptionsExt for OpenOptions {
+ fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
+ self.as_inner_mut().desired_access(access); self
+ }
+ fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
+ self.as_inner_mut().creation_disposition(access); self
+ }
+ fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
+ self.as_inner_mut().flags_and_attributes(access); self
+ }
+ fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
+ self.as_inner_mut().share_mode(access); self
+ }
+}
+
+/// Extension methods for `fs::Metadata` to access the raw fields contained
+/// within.
+#[unstable(feature = "metadata_ext", reason = "recently added API")]
+pub trait MetadataExt {
+ /// Returns the value of the `dwFileAttributes` field of this metadata.
+ ///
+ /// This field contains the file system attribute information for a file
+ /// or directory.
+ fn file_attributes(&self) -> u32;
+
+ /// Returns the value of the `ftCreationTime` field of this metadata.
+ ///
+ /// The returned 64-bit value represents the number of 100-nanosecond
+ /// intervals since January 1, 1601 (UTC).
+ fn creation_time(&self) -> u64;
+
+ /// Returns the value of the `ftLastAccessTime` field of this metadata.
+ ///
+ /// The returned 64-bit value represents the number of 100-nanosecond
+ /// intervals since January 1, 1601 (UTC).
+ fn last_access_time(&self) -> u64;
+
+ /// Returns the value of the `ftLastWriteTime` field of this metadata.
+ ///
+ /// The returned 64-bit value represents the number of 100-nanosecond
+ /// intervals since January 1, 1601 (UTC).
+ fn last_write_time(&self) -> u64;
+
+ /// Returns the value of the `nFileSize{High,Low}` fields of this
+ /// metadata.
+ ///
+ /// The returned value does not have meaning for directories.
+ fn file_size(&self) -> u64;
+}
+
+impl MetadataExt for Metadata {
+ fn file_attributes(&self) -> u32 { self.as_inner().attrs() }
+ fn creation_time(&self) -> u64 { self.as_inner().created() }
+ fn last_access_time(&self) -> u64 { self.as_inner().accessed() }
+ fn last_write_time(&self) -> u64 { self.as_inner().modified() }
+ fn file_size(&self) -> u64 { self.as_inner().size() }
+}
+
+/// Creates a new file symbolic link on the filesystem.
+///
+/// The `dst` path will be a file symbolic link pointing to the `src`
+/// path.
+///
+/// # Examples
+///
+/// ```ignore
+/// use std::os::windows::fs;
+///
+/// # fn foo() -> std::io::Result<()> {
+/// try!(fs::symlink_file("a.txt", "b.txt"));
+/// # Ok(())
+/// # }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
+ -> io::Result<()> {
+ sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), false)
+}
+
+/// Creates a new directory symlink on the filesystem.
+///
+/// The `dst` path will be a directory symbolic link pointing to the `src`
+/// path.
+///
+/// # Examples
+///
+/// ```ignore
+/// use std::os::windows::fs;
+///
+/// # fn foo() -> std::io::Result<()> {
+/// try!(fs::symlink_file("a", "b"));
+/// # Ok(())
+/// # }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
+ -> io::Result<()> {
+ sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), true)
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use fs;
+use os::windows::raw;
+use net;
+use sys_common::{net2, AsInner, FromInner};
+use sys;
+
+/// Raw HANDLEs.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type RawHandle = raw::HANDLE;
+
+/// Raw SOCKETs.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type RawSocket = raw::SOCKET;
+
+/// Extract raw handles.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait AsRawHandle {
+ /// Extracts the raw handle, without taking any ownership.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_raw_handle(&self) -> RawHandle;
+}
+
+/// Construct I/O objects from raw handles.
+#[unstable(feature = "from_raw_os",
+ reason = "recent addition to the std::os::windows::io module")]
+pub trait FromRawHandle {
+ /// Constructs a new I/O object from the specified raw handle.
+ ///
+ /// This function will **consume ownership** of the handle given,
+ /// passing responsibility for closing the handle to the returned
+ /// object.
+ ///
+ /// This function is also unsafe as the primitives currently returned
+ /// have the contract that they are the sole owner of the file
+ /// descriptor they are wrapping. Usage of this function could
+ /// accidentally allow violating this contract which can cause memory
+ /// unsafety in code that relies on it being true.
+ unsafe fn from_raw_handle(handle: RawHandle) -> Self;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawHandle for fs::File {
+ fn as_raw_handle(&self) -> RawHandle {
+ self.as_inner().handle().raw() as RawHandle
+ }
+}
+
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawHandle for fs::File {
+ unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
+ let handle = handle as ::libc::HANDLE;
+ fs::File::from_inner(sys::fs2::File::from_inner(handle))
+ }
+}
+
+/// Extract raw sockets.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait AsRawSocket {
+ /// Extracts the underlying raw socket from this object.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_raw_socket(&self) -> RawSocket;
+}
+
+/// Create I/O objects from raw sockets.
+#[unstable(feature = "from_raw_os", reason = "recent addition to module")]
+pub trait FromRawSocket {
+ /// Creates a new I/O object from the given raw socket.
+ ///
+ /// This function will **consume ownership** of the socket provided and
+ /// it will be closed when the returned object goes out of scope.
+ ///
+ /// This function is also unsafe as the primitives currently returned
+ /// have the contract that they are the sole owner of the file
+ /// descriptor they are wrapping. Usage of this function could
+ /// accidentally allow violating this contract which can cause memory
+ /// unsafety in code that relies on it being true.
+ unsafe fn from_raw_socket(sock: RawSocket) -> Self;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawSocket for net::TcpStream {
+ fn as_raw_socket(&self) -> RawSocket {
+ *self.as_inner().socket().as_inner()
+ }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawSocket for net::TcpListener {
+ fn as_raw_socket(&self) -> RawSocket {
+ *self.as_inner().socket().as_inner()
+ }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawSocket for net::UdpSocket {
+ fn as_raw_socket(&self) -> RawSocket {
+ *self.as_inner().socket().as_inner()
+ }
+}
+
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawSocket for net::TcpStream {
+ unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
+ let sock = sys::net::Socket::from_inner(sock);
+ net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
+ }
+}
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawSocket for net::TcpListener {
+ unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
+ let sock = sys::net::Socket::from_inner(sock);
+ net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
+ }
+}
+#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+impl FromRawSocket for net::UdpSocket {
+ unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
+ let sock = sys::net::Socket::from_inner(sock);
+ net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
+ }
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Experimental extensions to `std` for Windows.
+//!
+//! For now, this module is limited to extracting handles, file
+//! descriptors, and sockets, but its functionality will grow over
+//! time.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+pub mod ffi;
+pub mod fs;
+pub mod io;
+pub mod raw;
+
+/// A prelude for conveniently writing platform-specific code.
+///
+/// Includes all extension traits, and some important type definitions.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod prelude {
+ #[doc(no_inline)]
+ pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
+ #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+ pub use super::ffi::{OsStrExt, OsStringExt};
+ #[doc(no_inline)]
+ pub use super::fs::{OpenOptionsExt, MetadataExt};
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Windows-specific primitives
+
+#![unstable(feature = "raw_ext", reason = "recently added API")]
+
+use os::raw;
+
+pub type HANDLE = *mut raw::c_void;
+#[cfg(target_pointer_width = "32")]
+pub type SOCKET = u32;
+#[cfg(target_pointer_width = "64")]
+pub type SOCKET = u64;
use vec::Vec;
pub struct File { handle: Handle }
-pub struct FileAttr { data: c::WIN32_FILE_ATTRIBUTE_DATA }
+
+pub struct FileAttr {
+ data: c::WIN32_FILE_ATTRIBUTE_DATA,
+ is_symlink: bool,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+pub enum FileType {
+ Dir, File, Symlink, ReparsePoint
+}
pub struct ReadDir {
handle: FindNextFileHandle,
}
pub fn path(&self) -> PathBuf {
+ self.root.join(&self.file_name())
+ }
+
+ pub fn file_name(&self) -> OsString {
let filename = super::truncate_utf16_at_nul(&self.data.cFileName);
- self.root.join(&<OsString as OsStringExt>::from_wide(filename))
+ OsString::from_wide(filename)
+ }
+
+ pub fn file_type(&self) -> io::Result<FileType> {
+ Ok(FileType::new(self.data.dwFileAttributes,
+ self.data.dwReserved0 == c::IO_REPARSE_TAG_SYMLINK))
+ }
+
+ pub fn metadata(&self) -> io::Result<FileAttr> {
+ Ok(FileAttr {
+ data: c::WIN32_FILE_ATTRIBUTE_DATA {
+ dwFileAttributes: self.data.dwFileAttributes,
+ ftCreationTime: self.data.ftCreationTime,
+ ftLastAccessTime: self.data.ftLastAccessTime,
+ ftLastWriteTime: self.data.ftLastWriteTime,
+ nFileSizeHigh: self.data.nFileSizeHigh,
+ nFileSizeLow: self.data.nFileSizeLow,
+ },
+ is_symlink: self.data.dwReserved0 == c::IO_REPARSE_TAG_SYMLINK,
+ })
}
}
}
impl File {
+ fn open_reparse_point(path: &Path) -> io::Result<File> {
+ let mut opts = OpenOptions::new();
+ opts.read(true);
+ opts.flags_and_attributes(c::FILE_FLAG_OPEN_REPARSE_POINT as i32);
+ File::open(path, &opts)
+ }
+
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
let path = to_utf16(path);
let handle = unsafe {
let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
try!(cvt(c::GetFileInformationByHandle(self.handle.raw(),
&mut info)));
- Ok(FileAttr {
+ let mut attr = FileAttr {
data: c::WIN32_FILE_ATTRIBUTE_DATA {
dwFileAttributes: info.dwFileAttributes,
ftCreationTime: info.ftCreationTime,
ftLastWriteTime: info.ftLastWriteTime,
nFileSizeHigh: info.nFileSizeHigh,
nFileSizeLow: info.nFileSizeLow,
- }
- })
+ },
+ is_symlink: false,
+ };
+ if attr.is_reparse_point() {
+ attr.is_symlink = self.is_symlink();
+ }
+ Ok(attr)
}
}
}
pub fn handle(&self) -> &Handle { &self.handle }
+
+ fn is_symlink(&self) -> bool {
+ self.readlink().is_ok()
+ }
+
+ fn readlink(&self) -> io::Result<PathBuf> {
+ let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ let mut bytes = 0;
+
+ unsafe {
+ try!(cvt({
+ c::DeviceIoControl(self.handle.raw(),
+ c::FSCTL_GET_REPARSE_POINT,
+ 0 as *mut _,
+ 0,
+ space.as_mut_ptr() as *mut _,
+ space.len() as libc::DWORD,
+ &mut bytes,
+ 0 as *mut _)
+ }));
+ let buf: *const c::REPARSE_DATA_BUFFER = space.as_ptr() as *const _;
+ if (*buf).ReparseTag != c::IO_REPARSE_TAG_SYMLINK {
+ return Err(io::Error::new(io::ErrorKind::Other, "not a symlink"))
+ }
+ let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
+ &(*buf).rest as *const _ as *const _;
+ let path_buffer = &(*info).PathBuffer as *const _ as *const u16;
+ let subst_off = (*info).SubstituteNameOffset / 2;
+ let subst_ptr = path_buffer.offset(subst_off as isize);
+ let subst_len = (*info).SubstituteNameLength / 2;
+ let subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
+
+ Ok(PathBuf::from(OsString::from_wide(subst)))
+ }
+ }
}
impl FromInner<libc::HANDLE> for File {
}
impl FileAttr {
- pub fn is_dir(&self) -> bool {
- self.data.dwFileAttributes & c::FILE_ATTRIBUTE_DIRECTORY != 0
- }
- pub fn is_file(&self) -> bool {
- !self.is_dir()
- }
pub fn size(&self) -> u64 {
((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64)
}
+
pub fn perm(&self) -> FilePermissions {
FilePermissions { attrs: self.data.dwFileAttributes }
}
- pub fn accessed(&self) -> u64 { self.to_ms(&self.data.ftLastAccessTime) }
- pub fn modified(&self) -> u64 { self.to_ms(&self.data.ftLastWriteTime) }
+ pub fn attrs(&self) -> u32 { self.data.dwFileAttributes as u32 }
+
+ pub fn file_type(&self) -> FileType {
+ FileType::new(self.data.dwFileAttributes, self.is_symlink)
+ }
+
+ pub fn created(&self) -> u64 { self.to_u64(&self.data.ftCreationTime) }
+ pub fn accessed(&self) -> u64 { self.to_u64(&self.data.ftLastAccessTime) }
+ pub fn modified(&self) -> u64 { self.to_u64(&self.data.ftLastWriteTime) }
- fn to_ms(&self, ft: &libc::FILETIME) -> u64 {
- // FILETIME is in 100ns intervals and there are 10000 intervals in a
- // millisecond.
- let bits = (ft.dwLowDateTime as u64) | ((ft.dwHighDateTime as u64) << 32);
- bits / 10000
+ fn to_u64(&self, ft: &libc::FILETIME) -> u64 {
+ (ft.dwLowDateTime as u64) | ((ft.dwHighDateTime as u64) << 32)
+ }
+
+ fn is_reparse_point(&self) -> bool {
+ self.data.dwFileAttributes & libc::FILE_ATTRIBUTE_REPARSE_POINT != 0
}
}
}
}
+impl FileType {
+ fn new(attrs: libc::DWORD, is_symlink: bool) -> FileType {
+ if attrs & libc::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+ if is_symlink {
+ FileType::Symlink
+ } else {
+ FileType::ReparsePoint
+ }
+ } else if attrs & c::FILE_ATTRIBUTE_DIRECTORY != 0 {
+ FileType::Dir
+ } else {
+ FileType::File
+ }
+ }
+
+ pub fn is_dir(&self) -> bool { *self == FileType::Dir }
+ pub fn is_file(&self) -> bool { *self == FileType::File }
+ pub fn is_symlink(&self) -> bool { *self == FileType::Symlink }
+}
+
pub fn mkdir(p: &Path) -> io::Result<()> {
let p = to_utf16(p);
try!(cvt(unsafe {
}
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
- let mut opts = OpenOptions::new();
- opts.read(true);
- opts.flags_and_attributes(c::FILE_FLAG_OPEN_REPARSE_POINT as i32);
- let file = try!(File::open(p, &opts));
-
- let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- let mut bytes = 0;
-
- unsafe {
- try!(cvt({
- c::DeviceIoControl(file.handle.raw(),
- c::FSCTL_GET_REPARSE_POINT,
- 0 as *mut _,
- 0,
- space.as_mut_ptr() as *mut _,
- space.len() as libc::DWORD,
- &mut bytes,
- 0 as *mut _)
- }));
- let buf: *const c::REPARSE_DATA_BUFFER = space.as_ptr() as *const _;
- if (*buf).ReparseTag != c::IO_REPARSE_TAG_SYMLINK {
- return Err(io::Error::new(io::ErrorKind::Other, "not a symlink"))
- }
- let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
- &(*buf).rest as *const _ as *const _;
- let path_buffer = &(*info).PathBuffer as *const _ as *const u16;
- let subst_off = (*info).SubstituteNameOffset / 2;
- let subst_ptr = path_buffer.offset(subst_off as isize);
- let subst_len = (*info).SubstituteNameLength / 2;
- let subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
-
- Ok(PathBuf::from(OsString::from_wide(subst)))
- }
-
+ let file = try!(File::open_reparse_point(p));
+ file.readlink()
}
pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
}
pub fn stat(p: &Path) -> io::Result<FileAttr> {
- let p = to_utf16(p);
+ let attr = try!(lstat(p));
+ if attr.data.dwFileAttributes & libc::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+ let opts = OpenOptions::new();
+ let file = try!(File::open(p, &opts));
+ file.file_attr()
+ } else {
+ Ok(attr)
+ }
+}
+
+pub fn lstat(p: &Path) -> io::Result<FileAttr> {
+ let utf16 = to_utf16(p);
unsafe {
let mut attr: FileAttr = mem::zeroed();
- try!(cvt(c::GetFileAttributesExW(p.as_ptr(),
+ try!(cvt(c::GetFileAttributesExW(utf16.as_ptr(),
c::GetFileExInfoStandard,
&mut attr.data as *mut _ as *mut _)));
+ if attr.is_reparse_point() {
+ attr.is_symlink = File::open_reparse_point(p).map(|f| {
+ f.is_symlink()
+ }).unwrap_or(false);
+ }
Ok(attr)
}
}
}));
Ok(())
}
+
+pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
+ use sys::c::compat::kernel32::GetFinalPathNameByHandleW;
+
+ let mut opts = OpenOptions::new();
+ opts.read(true);
+ let f = try!(File::open(p, &opts));
+ super::fill_utf16_buf(|buf, sz| unsafe {
+ GetFinalPathNameByHandleW(f.handle.raw(), buf, sz,
+ libc::VOLUME_NAME_DOS)
+ }, |buf| {
+ PathBuf::from(OsString::from_wide(buf))
+ })
+}
#include <stdlib.h>
#if !defined(__WIN32__)
-#include <sys/time.h>
-#include <sys/types.h>
#include <dirent.h>
+#include <pthread.h>
#include <signal.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <pthread.h>
#else
#include <windows.h>
#include <wincrypt.h>
//include valgrind.h after stdint.h so that uintptr_t is defined for msys2 w64
#include "valgrind/valgrind.h"
-#ifdef __APPLE__
-#if (TARGET_OS_IPHONE)
-extern char **environ;
-#endif
-#endif
-
-#if defined(__FreeBSD__) || defined(__linux__) || defined(__ANDROID__) || \
- defined(__DragonFly__) || defined(__Bitrig__) || defined(__OpenBSD__)
-extern char **environ;
-#endif
-
-#if defined(__WIN32__)
-char**
-rust_env_pairs() {
- return 0;
-}
-#else
-char**
-rust_env_pairs() {
-#if defined(__APPLE__) && !(TARGET_OS_IPHONE)
- char **environ = *_NSGetEnviron();
-#endif
- return environ;
-}
-#endif
-
+#ifndef _WIN32
char*
-#if defined(__WIN32__)
-rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
- return entry_ptr->cFileName;
-}
-#else
rust_list_dir_val(struct dirent* entry_ptr) {
return entry_ptr->d_name;
}
+
+int
+rust_dir_get_mode(struct dirent* entry_ptr) {
+#if defined(_DIRENT_HAVE_D_TYPE)
+ switch (entry_ptr->d_type) {
+ case DT_BLK: return S_IFBLK;
+ case DT_CHR: return S_IFCHR;
+ case DT_FIFO: return S_IFIFO;
+ case DT_LNK: return S_IFLNK;
+ case DT_REG: return S_IFREG;
+ case DT_SOCK: return S_IFSOCK;
+ }
#endif
+ return -1;
+}
-#ifndef _WIN32
+ino_t
+rust_dir_get_ino(struct dirent* entry_ptr) {
+ return entry_ptr->d_ino;
+}
DIR*
rust_opendir(char *dirname) {
rust_dirent_t_size() {
return sizeof(struct dirent);
}
-
-#else
-
-void
-rust_opendir() {
-}
-
-void
-rust_readdir() {
-}
-
-void
-rust_dirent_t_size() {
-}
-
#endif
uintptr_t
VALGRIND_STACK_DEREGISTER(id);
}
-#if defined(__WIN32__)
-
-void
-rust_unset_sigprocmask() {
- // empty stub for windows to keep linker happy
-}
-
-#else
-
-void
-rust_unset_sigprocmask() {
- // this can't be safely converted to rust code because the
- // representation of sigset_t is platform-dependent
- sigset_t sset;
- sigemptyset(&sset);
- sigprocmask(SIG_SETMASK, &sset, NULL);
-}
-
-#endif
-
#if defined(__DragonFly__)
#include <errno.h>
// In DragonFly __error() is an inline function and as such