Skip to content

Commit

Permalink
std: Deprecate all std::os::*::raw types
Browse files Browse the repository at this point in the history
This commit is an implementation of [RFC 1415][rfc] which deprecates all types
in the `std::os::*::raw` modules.

[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1415-trim-std-os.md

Many of the types in these modules don't actually have a canonical platform
representation, for example the definition of `stat` on 32-bit Linux will change
depending on whether C code is compiled with LFS support or not. Unfortunately
the current types in `std::os::*::raw` are billed as "compatible with C", which
in light of this means it isn't really possible.

To make matters worse, platforms like Android sometimes define these types as
*smaller* than the way they're actually represented in the `stat` structure
itself. This means that when methods like `DirEntry::ino` are called on Android
the result may be truncated as we're tied to returning a `ino_t` type, not the
underlying type.

The commit here incorporates two backwards-compatible components:

* Deprecate all `raw` types that aren't in `std::os::raw`
* Expand the `std::os::*::fs::MetadataExt` trait on all platforms for method
  accessors of all fields. The fields now returned widened types which are the
  same across platforms (consistency across platforms is not required, however,
  it's just convenient).

and two also backwards-incompatible components:

* Change the definition of all `std::os::*::raw` type aliases to
  correspond to the newly widened types that are being returned on each
  platform.
* Change the definition of `std::os::*::raw::stat` on Linux to match the LFS
  definitions rather than the standard ones.

The breaking changes here will specifically break code that assumes that `libc`
and `std` agree on the definition of `std::os::*::raw` types, or that the `std`
types are faithful representations of the types in C. An [audit] has been
performed of crates.io to determine the fallout which was determined two be
minimal, with the two found cases of breakage having been fixed now.

[audit]: rust-lang/rfcs#1415 (comment)

---

Ok, so after all that, we're finally able to support LFS on Linux! This commit
then simultaneously starts using `stat64` and friends on Linux to ensure that we
can open >4GB files on 32-bit Linux. Yay!

Closes #28978
Closes #30050
Closes #31549
  • Loading branch information
alexcrichton committed Feb 13, 2016
1 parent 3f4227a commit aa23c98
Show file tree
Hide file tree
Showing 39 changed files with 2,036 additions and 482 deletions.
129 changes: 129 additions & 0 deletions src/libstd/os/android/fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2016 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 = "metadata_ext", since = "1.1.0")]

use libc;

use fs::Metadata;
use sys_common::AsInner;

#[allow(deprecated)]
use os::android::raw;

/// OS-specific extension methods for `fs::Metadata`
#[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt {
/// Gain a reference to the underlying `stat` structure which contains
/// the raw information returned by the OS.
///
/// The contents of the returned `stat` are **not** consistent across
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
/// cross-Unix abstractions contained within the raw stat.
#[stable(feature = "metadata_ext", since = "1.1.0")]
#[rustc_deprecated(since = "1.8.0",
reason = "deprecated in favor of the accessor \
methods of this trait")]
#[allow(deprecated)]
fn as_raw_stat(&self) -> &raw::stat;

#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_dev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ino(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mode(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_nlink(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_uid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_gid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_rdev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_size(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blksize(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blocks(&self) -> u64;
}

#[stable(feature = "metadata_ext", since = "1.1.0")]
impl MetadataExt for Metadata {
#[allow(deprecated)]
fn as_raw_stat(&self) -> &raw::stat {
unsafe {
&*(self.as_inner().as_inner() as *const libc::stat
as *const raw::stat)
}
}
fn st_dev(&self) -> u64 {
self.as_inner().as_inner().st_dev as u64
}
fn st_ino(&self) -> u64 {
self.as_inner().as_inner().st_ino as u64
}
fn st_mode(&self) -> u32 {
self.as_inner().as_inner().st_mode as u32
}
fn st_nlink(&self) -> u64 {
self.as_inner().as_inner().st_nlink as u64
}
fn st_uid(&self) -> u32 {
self.as_inner().as_inner().st_uid as u32
}
fn st_gid(&self) -> u32 {
self.as_inner().as_inner().st_gid as u32
}
fn st_rdev(&self) -> u64 {
self.as_inner().as_inner().st_rdev as u64
}
fn st_size(&self) -> u64 {
self.as_inner().as_inner().st_size as u64
}
fn st_atime(&self) -> i64 {
self.as_inner().as_inner().st_atime as i64
}
fn st_atime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_atime_nsec as i64
}
fn st_mtime(&self) -> i64 {
self.as_inner().as_inner().st_mtime as i64
}
fn st_mtime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_mtime_nsec as i64
}
fn st_ctime(&self) -> i64 {
self.as_inner().as_inner().st_ctime as i64
}
fn st_ctime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_ctime_nsec as i64
}
fn st_blksize(&self) -> u64 {
self.as_inner().as_inner().st_blksize as u64
}
fn st_blocks(&self) -> u64 {
self.as_inner().as_inner().st_blocks as u64
}
}

7 changes: 1 addition & 6 deletions src/libstd/os/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,4 @@
#![stable(feature = "raw_ext", since = "1.1.0")]

pub mod raw;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub mod fs {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub use sys::fs::MetadataExt;
}
pub mod fs;
38 changes: 22 additions & 16 deletions src/libstd/os/android/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
//! Android-specific raw type definitions

#![stable(feature = "raw_ext", since = "1.1.0")]
#![rustc_deprecated(since = "1.8.0",
reason = "these type aliases are no longer supported by \
the standard library, the `libc` crate on \
crates.io should be used instead for the correct \
definitions")]
#![allow(deprecated)]

use os::raw::c_long;

Expand All @@ -26,22 +32,22 @@ mod arch {
use os::unix::raw::{uid_t, gid_t};

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = u32;
pub type dev_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = u16;
pub type mode_t = u32;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = u32;
pub type blkcnt_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = u32;
pub type blksize_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = u32;
pub type ino_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = u16;
pub type nlink_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = i32;
pub type off_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = i32;
pub type time_t = i64;

#[repr(C)]
#[derive(Clone)]
Expand All @@ -52,7 +58,7 @@ mod arch {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __pad0: [c_uchar; 4],
#[stable(feature = "raw_ext", since = "1.1.0")]
pub __st_ino: ino_t,
pub __st_ino: u32,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mode: c_uint,
#[stable(feature = "raw_ext", since = "1.1.0")]
Expand All @@ -68,19 +74,19 @@ mod arch {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_size: c_longlong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blksize: blksize_t,
pub st_blksize: u32,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blocks: c_ulonglong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime: time_t,
pub st_atime: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime: time_t,
pub st_mtime: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime: time_t,
pub st_ctime: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime_nsec: c_ulong,
#[stable(feature = "raw_ext", since = "1.1.0")]
Expand All @@ -103,13 +109,13 @@ mod arch {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = u32;
pub type blksize_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = u32;
pub type nlink_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = i64;
pub type off_t = u64;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = i64;

Expand Down
149 changes: 149 additions & 0 deletions src/libstd/os/bitrig/fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright 2016 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 = "metadata_ext", since = "1.1.0")]

use libc;

use fs::Metadata;
use sys_common::AsInner;

#[allow(deprecated)]
use os::bitrig::raw;

/// OS-specific extension methods for `fs::Metadata`
#[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt {
/// Gain a reference to the underlying `stat` structure which contains
/// the raw information returned by the OS.
///
/// The contents of the returned `stat` are **not** consistent across
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
/// cross-Unix abstractions contained within the raw stat.
#[stable(feature = "metadata_ext", since = "1.1.0")]
#[rustc_deprecated(since = "1.8.0",
reason = "deprecated in favor of the accessor \
methods of this trait")]
#[allow(deprecated)]
fn as_raw_stat(&self) -> &raw::stat;

#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_dev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ino(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mode(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_nlink(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_uid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_gid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_rdev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_size(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_birthtime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_birthtime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blksize(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blocks(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_flags(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_gen(&self) -> u32;
}

#[stable(feature = "metadata_ext", since = "1.1.0")]
impl MetadataExt for Metadata {
#[allow(deprecated)]
fn as_raw_stat(&self) -> &raw::stat {
unsafe {
&*(self.as_inner().as_inner() as *const libc::stat
as *const raw::stat)
}
}
fn st_dev(&self) -> u64 {
self.as_inner().as_inner().st_dev as u64
}
fn st_ino(&self) -> u64 {
self.as_inner().as_inner().st_ino as u64
}
fn st_mode(&self) -> u32 {
self.as_inner().as_inner().st_mode as u32
}
fn st_nlink(&self) -> u64 {
self.as_inner().as_inner().st_nlink as u64
}
fn st_uid(&self) -> u32 {
self.as_inner().as_inner().st_uid as u32
}
fn st_gid(&self) -> u32 {
self.as_inner().as_inner().st_gid as u32
}
fn st_rdev(&self) -> u64 {
self.as_inner().as_inner().st_rdev as u64
}
fn st_size(&self) -> u64 {
self.as_inner().as_inner().st_size as u64
}
fn st_atime(&self) -> i64 {
self.as_inner().as_inner().st_atime as i64
}
fn st_atime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_atime_nsec as i64
}
fn st_mtime(&self) -> i64 {
self.as_inner().as_inner().st_mtime as i64
}
fn st_mtime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_mtime_nsec as i64
}
fn st_ctime(&self) -> i64 {
self.as_inner().as_inner().st_ctime as i64
}
fn st_ctime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_ctime_nsec as i64
}
fn st_birthtime(&self) -> i64 {
self.as_inner().as_inner().st_birthtime as i64
}
fn st_birthtime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_birthtime_nsec as i64
}
fn st_blksize(&self) -> u64 {
self.as_inner().as_inner().st_blksize as u64
}
fn st_blocks(&self) -> u64 {
self.as_inner().as_inner().st_blocks as u64
}
fn st_gen(&self) -> u32 {
self.as_inner().as_inner().st_gen as u32
}
fn st_flags(&self) -> u32 {
self.as_inner().as_inner().st_flags as u32
}
}

7 changes: 1 addition & 6 deletions src/libstd/os/bitrig/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,4 @@
#![stable(feature = "raw_ext", since = "1.1.0")]

pub mod raw;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub mod fs {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub use sys::fs::MetadataExt;
}
pub mod fs;
Loading

0 comments on commit aa23c98

Please sign in to comment.