Skip to content

Commit 0bfe358

Browse files
committed
Auto merge of #21936 - alexcrichton:fsv2, r=aturon
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
2 parents 134e00b + 6bfbad9 commit 0bfe358

File tree

15 files changed

+2564
-13
lines changed

15 files changed

+2564
-13
lines changed

src/libstd/fs.rs

+1,501
Large diffs are not rendered by default.

src/libstd/io/prelude.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
//! contained in this module.
2323
2424
pub use super::{Read, ReadExt, Write, WriteExt, BufRead, BufReadExt};
25+
pub use fs::PathExt;
2526

2627
// FIXME: pub use as `Seek` when the name isn't in the actual prelude any more
2728
pub use super::Seek as NewSeek;

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ pub mod dynamic_lib;
249249
pub mod ffi;
250250
pub mod old_io;
251251
pub mod io;
252+
pub mod fs;
252253
pub mod os;
253254
pub mod env;
254255
pub mod path;

src/libstd/path.rs

+6
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,12 @@ impl cmp::Ord for PathBuf {
999999
}
10001000
}
10011001

1002+
impl AsOsStr for PathBuf {
1003+
fn as_os_str(&self) -> &OsStr {
1004+
&self.inner[]
1005+
}
1006+
}
1007+
10021008
/// A slice of a path (akin to `str`).
10031009
///
10041010
/// This type supports a number of operations for inspecting a path, including

src/libstd/sys/common/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,30 @@ pub fn keep_going<F>(data: &[u8], mut f: F) -> i64 where
9595
}
9696

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

103+
/// A trait for viewing representations from std types
104+
#[doc(hidden)]
105+
pub trait AsInnerMut<Inner: ?Sized> {
106+
fn as_inner_mut(&mut self) -> &mut Inner;
107+
}
108+
102109
/// A trait for extracting representations from std types
110+
#[doc(hidden)]
103111
pub trait IntoInner<Inner> {
104112
fn into_inner(self) -> Inner;
105113
}
106114

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

121+
#[doc(hidden)]
112122
pub trait ProcessConfig<K: BytesContainer, V: BytesContainer> {
113123
fn program(&self) -> &CString;
114124
fn args(&self) -> &[CString];

src/libstd/sys/unix/c.rs

+3
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ extern {
154154
buf: *mut libc::c_char,
155155
buflen: libc::size_t,
156156
result: *mut *mut passwd) -> libc::c_int;
157+
158+
pub fn utimes(filename: *const libc::c_char,
159+
times: *const libc::timeval) -> libc::c_int;
157160
}
158161

159162
#[cfg(any(target_os = "macos", target_os = "ios"))]

src/libstd/sys/unix/ext.rs

+44-4
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@
3131
3232
#![unstable(feature = "std_misc")]
3333

34-
use vec::Vec;
35-
use sys::os_str::Buf;
36-
use sys_common::{AsInner, IntoInner, FromInner};
3734
use ffi::{OsStr, OsString};
35+
use fs::{Permissions, OpenOptions};
36+
use fs;
3837
use libc;
38+
use mem;
39+
use sys::os_str::Buf;
40+
use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
41+
use vec::Vec;
3942

4043
use old_io;
4144

@@ -54,6 +57,12 @@ impl AsRawFd for old_io::fs::File {
5457
}
5558
}
5659

60+
impl AsRawFd for fs::File {
61+
fn as_raw_fd(&self) -> Fd {
62+
self.as_inner().fd().raw()
63+
}
64+
}
65+
5766
impl AsRawFd for old_io::pipe::PipeStream {
5867
fn as_raw_fd(&self) -> Fd {
5968
self.as_inner().fd()
@@ -123,18 +132,49 @@ impl OsStringExt for OsString {
123132

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

129139
impl OsStrExt for OsStr {
140+
fn from_byte_slice(slice: &[u8]) -> &OsStr {
141+
unsafe { mem::transmute(slice) }
142+
}
130143
fn as_byte_slice(&self) -> &[u8] {
131144
&self.as_inner().inner
132145
}
133146
}
134147

148+
// Unix-specific extensions to `Permissions`
149+
pub trait PermissionsExt {
150+
fn set_mode(&mut self, mode: i32);
151+
}
152+
153+
impl PermissionsExt for Permissions {
154+
fn set_mode(&mut self, mode: i32) {
155+
*self = FromInner::from_inner(FromInner::from_inner(mode));
156+
}
157+
}
158+
159+
// Unix-specific extensions to `OpenOptions`
160+
pub trait OpenOptionsExt {
161+
/// Set the mode bits that a new file will be created with.
162+
///
163+
/// If a new file is created as part of a `File::open_opts` call then this
164+
/// specified `mode` will be used as the permission bits for the new file.
165+
fn mode(&mut self, mode: i32) -> &mut Self;
166+
}
167+
168+
impl OpenOptionsExt for OpenOptions {
169+
fn mode(&mut self, mode: i32) -> &mut OpenOptions {
170+
self.as_inner_mut().mode(mode); self
171+
}
172+
}
173+
135174
/// A prelude for conveniently writing platform-specific code.
136175
///
137176
/// Includes all extension traits, and some important type definitions.
138177
pub mod prelude {
139-
pub use super::{Fd, AsRawFd};
178+
#[doc(no_inline)]
179+
pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
140180
}

src/libstd/sys/unix/fd.rs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use core::prelude::*;
12+
use io::prelude::*;
13+
14+
use io;
15+
use libc::{self, c_int, size_t, c_void};
16+
use mem;
17+
use sys::cvt;
18+
19+
pub type fd_t = c_int;
20+
21+
pub struct FileDesc {
22+
fd: c_int,
23+
}
24+
25+
impl FileDesc {
26+
pub fn new(fd: c_int) -> FileDesc {
27+
FileDesc { fd: fd }
28+
}
29+
30+
pub fn raw(&self) -> c_int { self.fd }
31+
32+
/// Extract the actual filedescriptor without closing it.
33+
pub fn into_raw(self) -> c_int {
34+
let fd = self.fd;
35+
unsafe { mem::forget(self) };
36+
fd
37+
}
38+
39+
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
40+
let ret = try!(cvt(unsafe {
41+
libc::read(self.fd,
42+
buf.as_mut_ptr() as *mut c_void,
43+
buf.len() as size_t)
44+
}));
45+
Ok(ret as usize)
46+
}
47+
48+
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
49+
let ret = try!(cvt(unsafe {
50+
libc::write(self.fd,
51+
buf.as_ptr() as *const c_void,
52+
buf.len() as size_t)
53+
}));
54+
Ok(ret as usize)
55+
}
56+
}
57+
58+
impl Drop for FileDesc {
59+
fn drop(&mut self) {
60+
// closing stdio file handles makes no sense, so never do it. Also, note
61+
// that errors are ignored when closing a file descriptor. The reason
62+
// for this is that if an error occurs we don't actually know if the
63+
// file descriptor was closed or not, and if we retried (for something
64+
// like EINTR), we might close another valid file descriptor (opened
65+
// after we closed ours.
66+
if self.fd > libc::STDERR_FILENO {
67+
let _ = unsafe { libc::close(self.fd) };
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)