FenrirWolf
6 years ago
committed by
GitHub
101 changed files with 3171 additions and 1383 deletions
@ -0,0 +1,116 @@ |
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
//! Asynchronous values.
|
||||||
|
|
||||||
|
use core::cell::Cell; |
||||||
|
use core::marker::Unpin; |
||||||
|
use core::mem::PinMut; |
||||||
|
use core::option::Option; |
||||||
|
use core::ptr::NonNull; |
||||||
|
use core::task::{self, Poll}; |
||||||
|
use core::ops::{Drop, Generator, GeneratorState}; |
||||||
|
|
||||||
|
#[doc(inline)] |
||||||
|
pub use core::future::*; |
||||||
|
|
||||||
|
/// Wrap a future in a generator.
|
||||||
|
///
|
||||||
|
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
|
||||||
|
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
|
||||||
|
#[unstable(feature = "gen_future", issue = "50547")] |
||||||
|
pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> { |
||||||
|
GenFuture(x) |
||||||
|
} |
||||||
|
|
||||||
|
/// A wrapper around generators used to implement `Future` for `async`/`await` code.
|
||||||
|
#[unstable(feature = "gen_future", issue = "50547")] |
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] |
||||||
|
struct GenFuture<T: Generator<Yield = ()>>(T); |
||||||
|
|
||||||
|
// We rely on the fact that async/await futures are immovable in order to create
|
||||||
|
// self-referential borrows in the underlying generator.
|
||||||
|
impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {} |
||||||
|
|
||||||
|
#[unstable(feature = "gen_future", issue = "50547")] |
||||||
|
impl<T: Generator<Yield = ()>> Future for GenFuture<T> { |
||||||
|
type Output = T::Return; |
||||||
|
fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> { |
||||||
|
set_task_cx(cx, || match unsafe { PinMut::get_mut_unchecked(self).0.resume() } { |
||||||
|
GeneratorState::Yielded(()) => Poll::Pending, |
||||||
|
GeneratorState::Complete(x) => Poll::Ready(x), |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
thread_local! { |
||||||
|
static TLS_CX: Cell<Option<NonNull<task::Context<'static>>>> = Cell::new(None); |
||||||
|
} |
||||||
|
|
||||||
|
struct SetOnDrop(Option<NonNull<task::Context<'static>>>); |
||||||
|
|
||||||
|
impl Drop for SetOnDrop { |
||||||
|
fn drop(&mut self) { |
||||||
|
TLS_CX.with(|tls_cx| { |
||||||
|
tls_cx.set(self.0.take()); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[unstable(feature = "gen_future", issue = "50547")] |
||||||
|
/// Sets the thread-local task context used by async/await futures.
|
||||||
|
pub fn set_task_cx<F, R>(cx: &mut task::Context, f: F) -> R |
||||||
|
where |
||||||
|
F: FnOnce() -> R |
||||||
|
{ |
||||||
|
let old_cx = TLS_CX.with(|tls_cx| { |
||||||
|
tls_cx.replace(NonNull::new( |
||||||
|
cx |
||||||
|
as *mut task::Context |
||||||
|
as *mut () |
||||||
|
as *mut task::Context<'static> |
||||||
|
)) |
||||||
|
}); |
||||||
|
let _reset_cx = SetOnDrop(old_cx); |
||||||
|
f() |
||||||
|
} |
||||||
|
|
||||||
|
#[unstable(feature = "gen_future", issue = "50547")] |
||||||
|
/// Retrieves the thread-local task context used by async/await futures.
|
||||||
|
///
|
||||||
|
/// This function acquires exclusive access to the task context.
|
||||||
|
///
|
||||||
|
/// Panics if no task has been set or if the task context has already been
|
||||||
|
/// retrived by a surrounding call to get_task_cx.
|
||||||
|
pub fn get_task_cx<F, R>(f: F) -> R |
||||||
|
where |
||||||
|
F: FnOnce(&mut task::Context) -> R |
||||||
|
{ |
||||||
|
let cx_ptr = TLS_CX.with(|tls_cx| { |
||||||
|
// Clear the entry so that nested `with_get_cx` calls
|
||||||
|
// will fail or set their own value.
|
||||||
|
tls_cx.replace(None) |
||||||
|
}); |
||||||
|
let _reset_cx = SetOnDrop(cx_ptr); |
||||||
|
|
||||||
|
let mut cx_ptr = cx_ptr.expect( |
||||||
|
"TLS task::Context not set. This is a rustc bug. \ |
||||||
|
Please file an issue on https://github.com/rust-lang/rust.");
|
||||||
|
unsafe { f(cx_ptr.as_mut()) } |
||||||
|
} |
||||||
|
|
||||||
|
#[unstable(feature = "gen_future", issue = "50547")] |
||||||
|
/// Polls a future in the current thread-local task context.
|
||||||
|
pub fn poll_in_task_cx<F>(f: PinMut<F>) -> Poll<F::Output> |
||||||
|
where |
||||||
|
F: Future |
||||||
|
{ |
||||||
|
get_task_cx(|cx| f.poll(cx)) |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
#[doc(keyword = "fn")] |
||||||
|
//
|
||||||
|
/// The `fn` keyword.
|
||||||
|
///
|
||||||
|
/// The `fn` keyword is used to declare a function.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// fn some_function() {
|
||||||
|
/// // code goes in here
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// For more information about functions, take a look at the [Rust Book][book].
|
||||||
|
///
|
||||||
|
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
|
||||||
|
mod fn_keyword { } |
||||||
|
|
||||||
|
#[doc(keyword = "let")] |
||||||
|
//
|
||||||
|
/// The `let` keyword.
|
||||||
|
///
|
||||||
|
/// The `let` keyword is used to declare a variable.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #![allow(unused_assignments)]
|
||||||
|
/// let x = 3; // We create a variable named `x` with the value `3`.
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// By default, all variables are **not** mutable. If you want a mutable variable,
|
||||||
|
/// you'll have to use the `mut` keyword.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #![allow(unused_assignments)]
|
||||||
|
/// let mut x = 3; // We create a mutable variable named `x` with the value `3`.
|
||||||
|
///
|
||||||
|
/// x += 4; // `x` is now equal to `7`.
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// For more information about the `let` keyword, take a look at the [Rust Book][book].
|
||||||
|
///
|
||||||
|
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html
|
||||||
|
mod let_keyword { } |
@ -0,0 +1,389 @@ |
|||||||
|
// Copyright 2018 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::hermit::raw; |
||||||
|
|
||||||
|
/// OS-specific extensions to [`fs::Metadata`].
|
||||||
|
///
|
||||||
|
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
||||||
|
#[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.
|
||||||
|
///
|
||||||
|
/// [`stat`]: ../../../../std/os/linux/raw/struct.stat.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// let stat = meta.as_raw_stat();
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[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; |
||||||
|
|
||||||
|
/// Returns the device ID on which this file resides.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_dev());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_dev(&self) -> u64; |
||||||
|
/// Returns the inode number.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_ino());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_ino(&self) -> u64; |
||||||
|
/// Returns the file type and mode.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_mode());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_mode(&self) -> u32; |
||||||
|
/// Returns the number of hard links to file.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_nlink());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_nlink(&self) -> u64; |
||||||
|
/// Returns the user ID of the file owner.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_uid());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_uid(&self) -> u32; |
||||||
|
/// Returns the group ID of the file owner.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_gid());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_gid(&self) -> u32; |
||||||
|
/// Returns the device ID that this file represents. Only relevant for special file.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_rdev());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_rdev(&self) -> u64; |
||||||
|
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
|
||||||
|
///
|
||||||
|
/// The size of a symbolic link is the length of the pathname it contains,
|
||||||
|
/// without a terminating null byte.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_size());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_size(&self) -> u64; |
||||||
|
/// Returns the last access time.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_atime());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_atime(&self) -> i64; |
||||||
|
/// Returns the last access time, nano seconds part.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_atime_nsec());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_atime_nsec(&self) -> i64; |
||||||
|
/// Returns the last modification time.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_mtime());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_mtime(&self) -> i64; |
||||||
|
/// Returns the last modification time, nano seconds part.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_mtime_nsec());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_mtime_nsec(&self) -> i64; |
||||||
|
/// Returns the last status change time.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_ctime());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_ctime(&self) -> i64; |
||||||
|
/// Returns the last status change time, nano seconds part.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_ctime_nsec());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_ctime_nsec(&self) -> i64; |
||||||
|
/// Returns the "preferred" blocksize for efficient filesystem I/O.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_blksize());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
||||||
|
fn st_blksize(&self) -> u64; |
||||||
|
/// Returns the number of blocks allocated to the file, 512-byte units.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs;
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::linux::fs::MetadataExt;
|
||||||
|
///
|
||||||
|
/// fn main() -> io::Result<()> {
|
||||||
|
/// let meta = fs::metadata("some_file")?;
|
||||||
|
/// println!("{}", meta.st_blocks());
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[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::stat64 |
||||||
|
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 |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
//! HermitCore-specific definitions
|
||||||
|
|
||||||
|
#![stable(feature = "raw_ext", since = "1.1.0")] |
||||||
|
|
||||||
|
pub mod raw; |
||||||
|
pub mod fs; |
@ -0,0 +1,27 @@ |
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
//! HermitCore-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)] |
||||||
|
#![allow(missing_debug_implementations)] |
||||||
|
|
||||||
|
#[stable(feature = "pthread_t", since = "1.8.0")] |
||||||
|
pub use libc::pthread_t; |
||||||
|
|
||||||
|
#[doc(inline)] |
||||||
|
#[stable(feature = "raw_ext", since = "1.1.0")] |
||||||
|
pub use libc::{dev_t, mode_t, off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
@ -0,0 +1,769 @@ |
|||||||
|
// 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 = "unix_socket_redox", since = "1.29")] |
||||||
|
|
||||||
|
//! Unix-specific networking functionality
|
||||||
|
|
||||||
|
use fmt; |
||||||
|
use io::{self, Error, ErrorKind, Initializer}; |
||||||
|
use net::Shutdown; |
||||||
|
use os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd}; |
||||||
|
use path::Path; |
||||||
|
use time::Duration; |
||||||
|
use sys::{cvt, fd::FileDesc, syscall}; |
||||||
|
|
||||||
|
/// An address associated with a Unix socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let socket = match UnixListener::bind("/tmp/sock") {
|
||||||
|
/// Ok(sock) => sock,
|
||||||
|
/// Err(e) => {
|
||||||
|
/// println!("Couldn't bind: {:?}", e);
|
||||||
|
/// return
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
|
/// ```
|
||||||
|
#[derive(Clone)] |
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub struct SocketAddr(()); |
||||||
|
|
||||||
|
impl SocketAddr { |
||||||
|
/// Returns the contents of this address if it is a `pathname` address.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// With a pathname:
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
/// use std::path::Path;
|
||||||
|
///
|
||||||
|
/// let socket = UnixListener::bind("/tmp/sock").unwrap();
|
||||||
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
|
/// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Without a pathname:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::os::unix::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// let socket = UnixDatagram::unbound().unwrap();
|
||||||
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
|
/// assert_eq!(addr.as_pathname(), None);
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn as_pathname(&self) -> Option<&Path> { |
||||||
|
None |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns true if and only if the address is unnamed.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// A named address:
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let socket = UnixListener::bind("/tmp/sock").unwrap();
|
||||||
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
|
/// assert_eq!(addr.is_unnamed(), false);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// An unnamed address:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::os::unix::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// let socket = UnixDatagram::unbound().unwrap();
|
||||||
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
|
/// assert_eq!(addr.is_unnamed(), true);
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn is_unnamed(&self) -> bool { |
||||||
|
false |
||||||
|
} |
||||||
|
} |
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl fmt::Debug for SocketAddr { |
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
||||||
|
write!(fmt, "SocketAddr") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// A Unix stream socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::io::prelude::*;
|
||||||
|
///
|
||||||
|
/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
|
||||||
|
/// stream.write_all(b"hello world").unwrap();
|
||||||
|
/// let mut response = String::new();
|
||||||
|
/// stream.read_to_string(&mut response).unwrap();
|
||||||
|
/// println!("{}", response);
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub struct UnixStream(FileDesc); |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl fmt::Debug for UnixStream { |
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
||||||
|
let mut builder = fmt.debug_struct("UnixStream"); |
||||||
|
builder.field("fd", &self.0.raw()); |
||||||
|
if let Ok(addr) = self.local_addr() { |
||||||
|
builder.field("local", &addr); |
||||||
|
} |
||||||
|
if let Ok(addr) = self.peer_addr() { |
||||||
|
builder.field("peer", &addr); |
||||||
|
} |
||||||
|
builder.finish() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl UnixStream { |
||||||
|
/// Connects to the socket named by `path`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let socket = match UnixStream::connect("/tmp/sock") {
|
||||||
|
/// Ok(sock) => sock,
|
||||||
|
/// Err(e) => {
|
||||||
|
/// println!("Couldn't connect: {:?}", e);
|
||||||
|
/// return
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> { |
||||||
|
if let Some(s) = path.as_ref().to_str() { |
||||||
|
cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC)) |
||||||
|
.map(FileDesc::new) |
||||||
|
.map(UnixStream) |
||||||
|
} else { |
||||||
|
Err(Error::new( |
||||||
|
ErrorKind::Other, |
||||||
|
"UnixStream::connect: non-utf8 paths not supported on redox" |
||||||
|
)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Creates an unnamed pair of connected sockets.
|
||||||
|
///
|
||||||
|
/// Returns two `UnixStream`s which are connected to each other.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let (sock1, sock2) = match UnixStream::pair() {
|
||||||
|
/// Ok((sock1, sock2)) => (sock1, sock2),
|
||||||
|
/// Err(e) => {
|
||||||
|
/// println!("Couldn't create a pair of sockets: {:?}", e);
|
||||||
|
/// return
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn pair() -> io::Result<(UnixStream, UnixStream)> { |
||||||
|
let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC)) |
||||||
|
.map(FileDesc::new)?; |
||||||
|
let client = server.duplicate_path(b"connect")?; |
||||||
|
let stream = server.duplicate_path(b"listen")?; |
||||||
|
Ok((UnixStream(client), UnixStream(stream))) |
||||||
|
} |
||||||
|
|
||||||
|
/// Creates a new independently owned handle to the underlying socket.
|
||||||
|
///
|
||||||
|
/// The returned `UnixStream` is a reference to the same stream that this
|
||||||
|
/// object references. Both handles will read and write the same stream of
|
||||||
|
/// data, and options set on one stream will be propagated to the other
|
||||||
|
/// stream.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn try_clone(&self) -> io::Result<UnixStream> { |
||||||
|
self.0.duplicate().map(UnixStream) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the socket address of the local half of this connection.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// let addr = socket.local_addr().expect("Couldn't get local address");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn local_addr(&self) -> io::Result<SocketAddr> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the socket address of the remote half of this connection.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// let addr = socket.peer_addr().expect("Couldn't get peer address");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn peer_addr(&self) -> io::Result<SocketAddr> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Sets the read timeout for the socket.
|
||||||
|
///
|
||||||
|
/// If the provided value is [`None`], then [`read`] calls will block
|
||||||
|
/// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
|
||||||
|
/// method.
|
||||||
|
///
|
||||||
|
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
|
||||||
|
/// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
|
||||||
|
/// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
|
||||||
|
/// [`Duration`]: ../../../../std/time/struct.Duration.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// An [`Err`] is returned if the zero [`Duration`] is passed to this
|
||||||
|
/// method:
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
|
||||||
|
/// let err = result.unwrap_err();
|
||||||
|
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Sets the write timeout for the socket.
|
||||||
|
///
|
||||||
|
/// If the provided value is [`None`], then [`write`] calls will block
|
||||||
|
/// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
|
||||||
|
/// passed to this method.
|
||||||
|
///
|
||||||
|
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
|
||||||
|
/// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
|
||||||
|
/// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
|
||||||
|
/// [`Duration`]: ../../../../std/time/struct.Duration.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// An [`Err`] is returned if the zero [`Duration`] is passed to this
|
||||||
|
/// method:
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::io;
|
||||||
|
/// use std::net::UdpSocket;
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
|
||||||
|
/// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
|
||||||
|
/// let err = result.unwrap_err();
|
||||||
|
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the read timeout of this socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
|
||||||
|
/// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn read_timeout(&self) -> io::Result<Option<Duration>> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the write timeout of this socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
|
||||||
|
/// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn write_timeout(&self) -> io::Result<Option<Duration>> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Moves the socket into or out of nonblocking mode.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { |
||||||
|
self.0.set_nonblocking(nonblocking) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the value of the `SO_ERROR` option.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// if let Ok(Some(err)) = socket.take_error() {
|
||||||
|
/// println!("Got error: {:?}", err);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Platform specific
|
||||||
|
/// On Redox this always returns None.
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> { |
||||||
|
Ok(None) |
||||||
|
} |
||||||
|
|
||||||
|
/// Shuts down the read, write, or both halves of this connection.
|
||||||
|
///
|
||||||
|
/// This function will cause all pending and future I/O calls on the
|
||||||
|
/// specified portions to immediately return with an appropriate value
|
||||||
|
/// (see the documentation of [`Shutdown`]).
|
||||||
|
///
|
||||||
|
/// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixStream;
|
||||||
|
/// use std::net::Shutdown;
|
||||||
|
///
|
||||||
|
/// let socket = UnixStream::connect("/tmp/sock").unwrap();
|
||||||
|
/// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox")) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl io::Read for UnixStream { |
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
||||||
|
io::Read::read(&mut &*self, buf) |
||||||
|
} |
||||||
|
|
||||||
|
#[inline] |
||||||
|
unsafe fn initializer(&self) -> Initializer { |
||||||
|
Initializer::nop() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl<'a> io::Read for &'a UnixStream { |
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
||||||
|
self.0.read(buf) |
||||||
|
} |
||||||
|
|
||||||
|
#[inline] |
||||||
|
unsafe fn initializer(&self) -> Initializer { |
||||||
|
Initializer::nop() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl io::Write for UnixStream { |
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
||||||
|
io::Write::write(&mut &*self, buf) |
||||||
|
} |
||||||
|
|
||||||
|
fn flush(&mut self) -> io::Result<()> { |
||||||
|
io::Write::flush(&mut &*self) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl<'a> io::Write for &'a UnixStream { |
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
||||||
|
self.0.write(buf) |
||||||
|
} |
||||||
|
|
||||||
|
fn flush(&mut self) -> io::Result<()> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl AsRawFd for UnixStream { |
||||||
|
fn as_raw_fd(&self) -> RawFd { |
||||||
|
self.0.raw() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl FromRawFd for UnixStream { |
||||||
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { |
||||||
|
UnixStream(FileDesc::new(fd)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl IntoRawFd for UnixStream { |
||||||
|
fn into_raw_fd(self) -> RawFd { |
||||||
|
self.0.into_raw() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// A structure representing a Unix domain socket server.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::thread;
|
||||||
|
/// use std::os::unix::net::{UnixStream, UnixListener};
|
||||||
|
///
|
||||||
|
/// fn handle_client(stream: UnixStream) {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// // accept connections and process them, spawning a new thread for each one
|
||||||
|
/// for stream in listener.incoming() {
|
||||||
|
/// match stream {
|
||||||
|
/// Ok(stream) => {
|
||||||
|
/// /* connection succeeded */
|
||||||
|
/// thread::spawn(|| handle_client(stream));
|
||||||
|
/// }
|
||||||
|
/// Err(err) => {
|
||||||
|
/// /* connection failed */
|
||||||
|
/// break;
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub struct UnixListener(FileDesc); |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl fmt::Debug for UnixListener { |
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
||||||
|
let mut builder = fmt.debug_struct("UnixListener"); |
||||||
|
builder.field("fd", &self.0.raw()); |
||||||
|
if let Ok(addr) = self.local_addr() { |
||||||
|
builder.field("local", &addr); |
||||||
|
} |
||||||
|
builder.finish() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl UnixListener { |
||||||
|
/// Creates a new `UnixListener` bound to the specified socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let listener = match UnixListener::bind("/path/to/the/socket") {
|
||||||
|
/// Ok(sock) => sock,
|
||||||
|
/// Err(e) => {
|
||||||
|
/// println!("Couldn't connect: {:?}", e);
|
||||||
|
/// return
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> { |
||||||
|
if let Some(s) = path.as_ref().to_str() { |
||||||
|
cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC)) |
||||||
|
.map(FileDesc::new) |
||||||
|
.map(UnixListener) |
||||||
|
} else { |
||||||
|
Err(Error::new( |
||||||
|
ErrorKind::Other, |
||||||
|
"UnixListener::bind: non-utf8 paths not supported on redox" |
||||||
|
)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Accepts a new incoming connection to this listener.
|
||||||
|
///
|
||||||
|
/// This function will block the calling thread until a new Unix connection
|
||||||
|
/// is established. When established, the corresponding [`UnixStream`] and
|
||||||
|
/// the remote peer's address will be returned.
|
||||||
|
///
|
||||||
|
/// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// match listener.accept() {
|
||||||
|
/// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
|
||||||
|
/// Err(e) => println!("accept function failed: {:?}", e),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { |
||||||
|
self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(()))) |
||||||
|
} |
||||||
|
|
||||||
|
/// Creates a new independently owned handle to the underlying socket.
|
||||||
|
///
|
||||||
|
/// The returned `UnixListener` is a reference to the same socket that this
|
||||||
|
/// object references. Both handles can be used to accept incoming
|
||||||
|
/// connections and options set on one listener will affect the other.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// let listener_copy = listener.try_clone().expect("try_clone failed");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn try_clone(&self) -> io::Result<UnixListener> { |
||||||
|
self.0.duplicate().map(UnixListener) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the local socket address of this listener.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// let addr = listener.local_addr().expect("Couldn't get local address");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn local_addr(&self) -> io::Result<SocketAddr> { |
||||||
|
Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox")) |
||||||
|
} |
||||||
|
|
||||||
|
/// Moves the socket into or out of nonblocking mode.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// listener.set_nonblocking(true).expect("Couldn't set non blocking");
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { |
||||||
|
self.0.set_nonblocking(nonblocking) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns the value of the `SO_ERROR` option.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::os::unix::net::UnixListener;
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/tmp/sock").unwrap();
|
||||||
|
///
|
||||||
|
/// if let Ok(Some(err)) = listener.take_error() {
|
||||||
|
/// println!("Got error: {:?}", err);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Platform specific
|
||||||
|
/// On Redox this always returns None.
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> { |
||||||
|
Ok(None) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns an iterator over incoming connections.
|
||||||
|
///
|
||||||
|
/// The iterator will never return [`None`] and will also not yield the
|
||||||
|
/// peer's [`SocketAddr`] structure.
|
||||||
|
///
|
||||||
|
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
|
||||||
|
/// [`SocketAddr`]: struct.SocketAddr.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::thread;
|
||||||
|
/// use std::os::unix::net::{UnixStream, UnixListener};
|
||||||
|
///
|
||||||
|
/// fn handle_client(stream: UnixStream) {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// for stream in listener.incoming() {
|
||||||
|
/// match stream {
|
||||||
|
/// Ok(stream) => {
|
||||||
|
/// thread::spawn(|| handle_client(stream));
|
||||||
|
/// }
|
||||||
|
/// Err(err) => {
|
||||||
|
/// break;
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub fn incoming<'a>(&'a self) -> Incoming<'a> { |
||||||
|
Incoming { listener: self } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl AsRawFd for UnixListener { |
||||||
|
fn as_raw_fd(&self) -> RawFd { |
||||||
|
self.0.raw() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl FromRawFd for UnixListener { |
||||||
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { |
||||||
|
UnixListener(FileDesc::new(fd)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl IntoRawFd for UnixListener { |
||||||
|
fn into_raw_fd(self) -> RawFd { |
||||||
|
self.0.into_raw() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl<'a> IntoIterator for &'a UnixListener { |
||||||
|
type Item = io::Result<UnixStream>; |
||||||
|
type IntoIter = Incoming<'a>; |
||||||
|
|
||||||
|
fn into_iter(self) -> Incoming<'a> { |
||||||
|
self.incoming() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// An iterator over incoming connections to a [`UnixListener`].
|
||||||
|
///
|
||||||
|
/// It will never return [`None`].
|
||||||
|
///
|
||||||
|
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
|
||||||
|
/// [`UnixListener`]: struct.UnixListener.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::thread;
|
||||||
|
/// use std::os::unix::net::{UnixStream, UnixListener};
|
||||||
|
///
|
||||||
|
/// fn handle_client(stream: UnixStream) {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
|
||||||
|
///
|
||||||
|
/// for stream in listener.incoming() {
|
||||||
|
/// match stream {
|
||||||
|
/// Ok(stream) => {
|
||||||
|
/// thread::spawn(|| handle_client(stream));
|
||||||
|
/// }
|
||||||
|
/// Err(err) => {
|
||||||
|
/// break;
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug)] |
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
pub struct Incoming<'a> { |
||||||
|
listener: &'a UnixListener, |
||||||
|
} |
||||||
|
|
||||||
|
#[stable(feature = "unix_socket_redox", since = "1.29")] |
||||||
|
impl<'a> Iterator for Incoming<'a> { |
||||||
|
type Item = io::Result<UnixStream>; |
||||||
|
|
||||||
|
fn next(&mut self) -> Option<io::Result<UnixStream>> { |
||||||
|
Some(self.listener.accept().map(|s| s.0)) |
||||||
|
} |
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) { |
||||||
|
(usize::max_value(), None) |
||||||
|
} |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue