diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-04-15 23:21:13 -0700 | 
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-04-27 17:16:44 -0700 | 
| commit | 9348700007c6ac913df97c8e9e1ab7df6f91f130 (patch) | |
| tree | a69d87dfe3b7e1e8c7cd9f7f48fdabdb1436c308 /src/libstd/sys/unix/ext | |
| parent | b772ce6342962792620e21623997d0d3b98164b7 (diff) | |
| download | rust-9348700007c6ac913df97c8e9e1ab7df6f91f130.tar.gz rust-9348700007c6ac913df97c8e9e1ab7df6f91f130.zip | |
std: Expand the area of std::fs
This commit is an implementation of [RFC 1044][rfc] which adds additional
surface area to the `std::fs` module. All new APIs are `#[unstable]` behind
assorted feature names for each one.
[rfc]: https://github.com/rust-lang/rfcs/pull/1044
The new APIs added are:
* `fs::canonicalize` - bindings to `realpath` on unix and
  `GetFinalPathNameByHandle` on windows.
* `fs::symlink_metadata` - similar to `lstat` on unix
* `fs::FileType` and accessor methods as `is_{file,dir,symlink}`
* `fs::Metadata::file_type` - accessor for the raw file type
* `fs::DirEntry::metadata` - acquisition of metadata which is free on Windows
  but requires a syscall on unix.
* `fs::DirEntry::file_type` - access the file type which may not require a
  syscall on most platforms.
* `fs::DirEntry::file_name` - access just the file name without leading
  components.
* `fs::PathExt::symlink_metadata` - convenience method for the top-level
  function.
* `fs::PathExt::canonicalize` - convenience method for the top-level
  function.
* `fs::PathExt::read_link` - convenience method for the top-level
  function.
* `fs::PathExt::read_dir` - convenience method for the top-level
  function.
* `std::os::raw` - type definitions for raw OS/C types available on all
  platforms.
* `std::os::$platform` - new modules have been added for all currently supported
  platforms (e.g. those more specific than just `unix`).
* `std::os::$platform::raw` - platform-specific type definitions. These modules
  are populated with the bare essentials necessary for lowing I/O types into
  their raw representations, and currently largely consist of the `stat`
  definition for unix platforms.
This commit also deprecates `Metadata::{modified, accessed}` in favor of
inspecting the raw representations via the lowering methods of `Metadata`.
Diffstat (limited to 'src/libstd/sys/unix/ext')
| -rw-r--r-- | src/libstd/sys/unix/ext/ffi.rs | 62 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/fs.rs | 191 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/io.rs | 108 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/mod.rs | 53 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/process.rs | 65 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/raw.rs | 22 | 
6 files changed, 501 insertions, 0 deletions
| diff --git a/src/libstd/sys/unix/ext/ffi.rs b/src/libstd/sys/unix/ext/ffi.rs new file mode 100644 index 00000000000..825e74cabde --- /dev/null +++ b/src/libstd/sys/unix/ext/ffi.rs @@ -0,0 +1,62 @@ +// 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 + } +} diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs new file mode 100644 index 00000000000..ad6a856d5bc --- /dev/null +++ b/src/libstd/sys/unix/ext/fs.rs @@ -0,0 +1,191 @@ +// 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()) +} diff --git a/src/libstd/sys/unix/ext/io.rs b/src/libstd/sys/unix/ext/io.rs new file mode 100644 index 00000000000..8cb4b4907f6 --- /dev/null +++ b/src/libstd/sys/unix/ext/io.rs @@ -0,0 +1,108 @@ +// 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)) + } +} diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs new file mode 100644 index 00000000000..6fde45a7301 --- /dev/null +++ b/src/libstd/sys/unix/ext/mod.rs @@ -0,0 +1,53 @@ +// 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}; +} diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs new file mode 100644 index 00000000000..8c9d0a86583 --- /dev/null +++ b/src/libstd/sys/unix/ext/process.rs @@ -0,0 +1,65 @@ +// 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 + } + } +} diff --git a/src/libstd/sys/unix/ext/raw.rs b/src/libstd/sys/unix/ext/raw.rs new file mode 100644 index 00000000000..8fe4b90456a --- /dev/null +++ b/src/libstd/sys/unix/ext/raw.rs @@ -0,0 +1,22 @@ +// 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}; | 
