Skip to content

Commit

Permalink
Auto merge of #21936 - alexcrichton:fsv2, r=aturon
Browse files Browse the repository at this point in the history
This commit is an implementation of [RFC 739][rfc] which adds a new `std::fs`
module to the standard library. This module provides much of the same
functionality as `std::old_io::fs` but it has many tweaked APIs as well as uses
the new `std::path` module.

[rfc]: rust-lang/rfcs#739
  • Loading branch information
bors committed Feb 10, 2015
2 parents 134e00b + 6bfbad9 commit 0bfe358
Show file tree
Hide file tree
Showing 15 changed files with 2,564 additions and 13 deletions.
1,501 changes: 1,501 additions & 0 deletions src/libstd/fs.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/libstd/io/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//! contained in this module.

pub use super::{Read, ReadExt, Write, WriteExt, BufRead, BufReadExt};
pub use fs::PathExt;

// FIXME: pub use as `Seek` when the name isn't in the actual prelude any more
pub use super::Seek as NewSeek;
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ pub mod dynamic_lib;
pub mod ffi;
pub mod old_io;
pub mod io;
pub mod fs;
pub mod os;
pub mod env;
pub mod path;
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,12 @@ impl cmp::Ord for PathBuf {
}
}

impl AsOsStr for PathBuf {
fn as_os_str(&self) -> &OsStr {
&self.inner[]
}
}

/// A slice of a path (akin to `str`).
///
/// This type supports a number of operations for inspecting a path, including
Expand Down
10 changes: 10 additions & 0 deletions src/libstd/sys/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,30 @@ pub fn keep_going<F>(data: &[u8], mut f: F) -> i64 where
}

/// A trait for viewing representations from std types
#[doc(hidden)]
pub trait AsInner<Inner: ?Sized> {
fn as_inner(&self) -> &Inner;
}

/// A trait for viewing representations from std types
#[doc(hidden)]
pub trait AsInnerMut<Inner: ?Sized> {
fn as_inner_mut(&mut self) -> &mut Inner;
}

/// A trait for extracting representations from std types
#[doc(hidden)]
pub trait IntoInner<Inner> {
fn into_inner(self) -> Inner;
}

/// A trait for creating std types from internal representations
#[doc(hidden)]
pub trait FromInner<Inner> {
fn from_inner(inner: Inner) -> Self;
}

#[doc(hidden)]
pub trait ProcessConfig<K: BytesContainer, V: BytesContainer> {
fn program(&self) -> &CString;
fn args(&self) -> &[CString];
Expand Down
3 changes: 3 additions & 0 deletions src/libstd/sys/unix/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ extern {
buf: *mut libc::c_char,
buflen: libc::size_t,
result: *mut *mut passwd) -> libc::c_int;

pub fn utimes(filename: *const libc::c_char,
times: *const libc::timeval) -> libc::c_int;
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
Expand Down
48 changes: 44 additions & 4 deletions src/libstd/sys/unix/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@

#![unstable(feature = "std_misc")]

use vec::Vec;
use sys::os_str::Buf;
use sys_common::{AsInner, IntoInner, FromInner};
use ffi::{OsStr, OsString};
use fs::{Permissions, OpenOptions};
use fs;
use libc;
use mem;
use sys::os_str::Buf;
use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
use vec::Vec;

use old_io;

Expand All @@ -54,6 +57,12 @@ impl AsRawFd for old_io::fs::File {
}
}

impl AsRawFd for fs::File {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd().raw()
}
}

impl AsRawFd for old_io::pipe::PipeStream {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
Expand Down Expand Up @@ -123,18 +132,49 @@ impl OsStringExt for OsString {

// Unix-specific extensions to `OsStr`.
pub trait OsStrExt {
fn from_byte_slice(slice: &[u8]) -> &OsStr;
fn as_byte_slice(&self) -> &[u8];
}

impl OsStrExt for OsStr {
fn from_byte_slice(slice: &[u8]) -> &OsStr {
unsafe { mem::transmute(slice) }
}
fn as_byte_slice(&self) -> &[u8] {
&self.as_inner().inner
}
}

// Unix-specific extensions to `Permissions`
pub trait PermissionsExt {
fn set_mode(&mut self, mode: i32);
}

impl PermissionsExt for Permissions {
fn set_mode(&mut self, mode: i32) {
*self = FromInner::from_inner(FromInner::from_inner(mode));
}
}

// Unix-specific extensions to `OpenOptions`
pub trait OpenOptionsExt {
/// Set 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
}
}

/// A prelude for conveniently writing platform-specific code.
///
/// Includes all extension traits, and some important type definitions.
pub mod prelude {
pub use super::{Fd, AsRawFd};
#[doc(no_inline)]
pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
}
70 changes: 70 additions & 0 deletions src/libstd/sys/unix/fd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 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.

use core::prelude::*;
use io::prelude::*;

use io;
use libc::{self, c_int, size_t, c_void};
use mem;
use sys::cvt;

pub type fd_t = c_int;

pub struct FileDesc {
fd: c_int,
}

impl FileDesc {
pub fn new(fd: c_int) -> FileDesc {
FileDesc { fd: fd }
}

pub fn raw(&self) -> c_int { self.fd }

/// Extract the actual filedescriptor without closing it.
pub fn into_raw(self) -> c_int {
let fd = self.fd;
unsafe { mem::forget(self) };
fd
}

pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
let ret = try!(cvt(unsafe {
libc::read(self.fd,
buf.as_mut_ptr() as *mut c_void,
buf.len() as size_t)
}));
Ok(ret as usize)
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let ret = try!(cvt(unsafe {
libc::write(self.fd,
buf.as_ptr() as *const c_void,
buf.len() as size_t)
}));
Ok(ret as usize)
}
}

impl Drop for FileDesc {
fn drop(&mut self) {
// closing stdio file handles makes no sense, so never do it. Also, note
// that errors are ignored when closing a file descriptor. The reason
// for this is that if an error occurs we don't actually know if the
// file descriptor was closed or not, and if we retried (for something
// like EINTR), we might close another valid file descriptor (opened
// after we closed ours.
if self.fd > libc::STDERR_FILENO {
let _ = unsafe { libc::close(self.fd) };
}
}
}
Loading

0 comments on commit 0bfe358

Please sign in to comment.