--- a/testing/geckodriver/Cargo.lock
+++ b/testing/geckodriver/Cargo.lock
@@ -66,16 +66,21 @@ name = "base64"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bitflags"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -151,16 +156,32 @@ name = "flate2"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "fuchsia-zircon"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "gcc"
version = "0.3.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "httparse"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -371,19 +392,20 @@ source = "registry+https://github.com/ru
[[package]]
name = "podio"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
-version = "0.3.15"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -510,17 +532,17 @@ name = "strsim"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tempdir"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "term_size"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -621,17 +643,17 @@ name = "utf8-ranges"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "uuid"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vec_map"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -689,27 +711,30 @@ dependencies = [
]
[metadata]
"checksum advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "307c92332867e586720c0222ee9d890bbe8431711efed8a1b06bc5b40fc66bd7"
"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
"checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842"
"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557"
+"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
"checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24"
"checksum bzip2-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "98ce3fff84d4e90011f464bbdf48e3428f04270439f703868fd489d2aaedfc30"
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
"checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
"checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
"checksum cookie 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa6d675d62b2f95b56b331b5222a520149a54f23a2d21974dfcc69caf0a9d"
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c"
+"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
+"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "291055c78f59ca3d84c99026c9501c469413d386bb46be1e1cf1d285cd1db3b0"
"checksum httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77f756bed9ee3a83ce98774f4155b42a31b787029013f3a7d83eca714e500e21"
"checksum hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "36e108e0b1fa2d17491cbaac4bc460dc0956029d10ccf83c913dd0e5db3e7f07"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa500db770a99afe2a0f2229be2a3d09c7ed9d7e4e8440bf71253141994e240f"
"checksum kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e014dab1082fd9d80ea1fa6fcb261b47ed3eb511612a14198bb507701add083e"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum ktmw32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f9313a869ff779ae08dd990b75a92dc06aa16d771f41305f7286649cd39a0ee"
@@ -728,17 +753,17 @@ dependencies = [
"checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958"
"checksum num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "98b15ba84e910ea7a1973bccd3df7b31ae282bf9d8bd2897779950c9b8303d40"
"checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"
"checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e"
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
"checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
-"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
+"checksum rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "61efcbcd9fa8d8fbb07c84e34a8af18a1ff177b449689ad38a6e9457ecc7b2ae"
"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
"checksum rust-ini 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06d4e8b0b50e7e7f827d609fa9746e1cf6371a1fa15404a1a0a86152a801079f"
"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon-sys/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","BUILD.gn":"862eccf06f706db5af1e0041b10b6b637dbc77257b6c4f536a72fc7d21d3dfb9","Cargo.toml":"d05607413136805977463d1c2b979e7692ea1ac06e051d598de440c64603e886","examples/hello.rs":"66c6a147b98b913fef8e7a7da6387fb735f7f1e2c00abc8794a32a8cf0320851","src/definitions.rs":"0b13b741cad9ba42c1da5b654c6d60f03183a7c79a5843e7734a95b4f934d81f","src/lib.rs":"83c8b96c64b442d72a7b87455f182e6ffef6bf2cd7aa2c0c88db992ac9060bda"},"package":"43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon-sys/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/rust/rust_library.gni")
+
+rust_library("fuchsia-zircon-sys") {
+ deps = [
+ "//third_party/rust-crates:bitflags-0.7.0",
+ ]
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon-sys/Cargo.toml
@@ -0,0 +1,21 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "fuchsia-zircon-sys"
+version = "0.2.0"
+authors = ["Raph Levien <raph@google.com>"]
+description = "Low-level Rust bindings for the Zircon kernel"
+license = "BSD-3-Clause"
+repository = "https://fuchsia.googlesource.com/garnet/"
+[dependencies.bitflags]
+version = "0.7.0"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon-sys/examples/hello.rs
@@ -0,0 +1,14 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+extern crate fuchsia_zircon_sys as zircon_sys;
+
+pub fn main() {
+ let time = unsafe { zircon_sys::zx_time_get(zircon_sys::ZX_CLOCK_MONOTONIC) };
+ println!("before sleep, time = {}", time);
+ unsafe { zircon_sys::zx_nanosleep(zircon_sys::zx_deadline_after(1000_000_000)); }
+ let time = unsafe { zircon_sys::zx_time_get(zircon_sys::ZX_CLOCK_MONOTONIC) };
+ println!("after sleep, time = {}", time);
+}
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon-sys/src/definitions.rs
@@ -0,0 +1,903 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// This is a GENERATED file, see //zircon/system/host/sysgen.
+// The license governing this file can be found in the LICENSE file.
+
+#[link(name = "zircon")]
+extern {
+ pub fn zx_time_get(
+ clock_id: u32
+ ) -> zx_time_t;
+
+ pub fn zx_nanosleep(
+ deadline: zx_time_t
+ ) -> zx_status_t;
+
+ pub fn zx_ticks_get(
+ ) -> u64;
+
+ pub fn zx_ticks_per_second(
+ ) -> u64;
+
+ pub fn zx_deadline_after(
+ nanoseconds: zx_duration_t
+ ) -> zx_time_t;
+
+ pub fn zx_clock_adjust(
+ handle: zx_handle_t,
+ clock_id: u32,
+ offset: i64
+ ) -> zx_status_t;
+
+ pub fn zx_system_get_num_cpus(
+ ) -> u32;
+
+ pub fn zx_system_get_version(
+ version: *mut u8,
+ version_len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_system_get_physmem(
+ ) -> u64;
+
+ pub fn zx_cache_flush(
+ addr: *const u8,
+ len: usize,
+ options: u32
+ ) -> zx_status_t;
+
+ pub fn zx_handle_close(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_handle_duplicate(
+ handle: zx_handle_t,
+ rights: zx_rights_t,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_handle_replace(
+ handle: zx_handle_t,
+ rights: zx_rights_t,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_object_wait_one(
+ handle: zx_handle_t,
+ waitfor: zx_signals_t,
+ deadline: zx_time_t,
+ observed: *mut zx_signals_t
+ ) -> zx_status_t;
+
+ pub fn zx_object_wait_many(
+ items: *mut zx_wait_item_t,
+ count: u32,
+ deadline: zx_time_t
+ ) -> zx_status_t;
+
+ pub fn zx_object_wait_async(
+ handle: zx_handle_t,
+ port_handle: zx_handle_t,
+ key: u64,
+ signals: zx_signals_t,
+ options: u32
+ ) -> zx_status_t;
+
+ pub fn zx_object_signal(
+ handle: zx_handle_t,
+ clear_mask: u32,
+ set_mask: u32
+ ) -> zx_status_t;
+
+ pub fn zx_object_signal_peer(
+ handle: zx_handle_t,
+ clear_mask: u32,
+ set_mask: u32
+ ) -> zx_status_t;
+
+ pub fn zx_object_get_property(
+ handle: zx_handle_t,
+ property: u32,
+ value: *mut u8,
+ size: usize
+ ) -> zx_status_t;
+
+ pub fn zx_object_set_property(
+ handle: zx_handle_t,
+ property: u32,
+ value: *const u8,
+ size: usize
+ ) -> zx_status_t;
+
+ pub fn zx_object_set_cookie(
+ handle: zx_handle_t,
+ scope: zx_handle_t,
+ cookie: u64
+ ) -> zx_status_t;
+
+ pub fn zx_object_get_cookie(
+ handle: zx_handle_t,
+ scope: zx_handle_t,
+ cookie: *mut u64
+ ) -> zx_status_t;
+
+ pub fn zx_object_get_info(
+ handle: zx_handle_t,
+ topic: u32,
+ buffer: *mut u8,
+ buffer_size: usize,
+ actual_count: *mut usize,
+ avail_count: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_object_get_child(
+ handle: zx_handle_t,
+ koid: u64,
+ rights: zx_rights_t,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_channel_create(
+ options: u32,
+ out0: *mut zx_handle_t,
+ out1: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_channel_read(
+ handle: zx_handle_t,
+ options: u32,
+ bytes: *mut u8,
+ handles: *mut zx_handle_t,
+ num_bytes: u32,
+ num_handles: u32,
+ actual_bytes: *mut u32,
+ actual_handles: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_channel_write(
+ handle: zx_handle_t,
+ options: u32,
+ bytes: *const u8,
+ num_bytes: u32,
+ handles: *const zx_handle_t,
+ num_handles: u32
+ ) -> zx_status_t;
+
+ pub fn zx_channel_call_noretry(
+ handle: zx_handle_t,
+ options: u32,
+ deadline: zx_time_t,
+ args: *const zx_channel_call_args_t,
+ actual_bytes: *mut u32,
+ actual_handles: *mut u32,
+ read_status: *mut zx_status_t
+ ) -> zx_status_t;
+
+ pub fn zx_channel_call_finish(
+ deadline: zx_time_t,
+ args: *const zx_channel_call_args_t,
+ actual_bytes: *mut u32,
+ actual_handles: *mut u32,
+ read_status: *mut zx_status_t
+ ) -> zx_status_t;
+
+ pub fn zx_channel_call(
+ handle: zx_handle_t,
+ options: u32,
+ deadline: zx_time_t,
+ args: *const zx_channel_call_args_t,
+ actual_bytes: *mut u32,
+ actual_handles: *mut u32,
+ read_status: *mut zx_status_t
+ ) -> zx_status_t;
+
+ pub fn zx_socket_create(
+ options: u32,
+ out0: *mut zx_handle_t,
+ out1: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_socket_write(
+ handle: zx_handle_t,
+ options: u32,
+ buffer: *const u8,
+ size: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_socket_read(
+ handle: zx_handle_t,
+ options: u32,
+ buffer: *mut u8,
+ size: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_thread_exit(
+ );
+
+ pub fn zx_thread_create(
+ process: zx_handle_t,
+ name: *const u8,
+ name_len: u32,
+ options: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_thread_start(
+ handle: zx_handle_t,
+ thread_entry: usize,
+ stack: usize,
+ arg1: usize,
+ arg2: usize
+ ) -> zx_status_t;
+
+ pub fn zx_thread_read_state(
+ handle: zx_handle_t,
+ kind: u32,
+ buffer: *mut u8,
+ len: u32,
+ actual: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_thread_write_state(
+ handle: zx_handle_t,
+ kind: u32,
+ buffer: *const u8,
+ buffer_len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_thread_set_priority(
+ prio: i32
+ ) -> zx_status_t;
+
+ pub fn zx_process_exit(
+ retcode: isize
+ );
+
+ pub fn zx_process_create(
+ job: zx_handle_t,
+ name: *const u8,
+ name_len: u32,
+ options: u32,
+ proc_handle: *mut zx_handle_t,
+ vmar_handle: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_process_start(
+ process_handle: zx_handle_t,
+ thread_handle: zx_handle_t,
+ entry: usize,
+ stack: usize,
+ arg_handle: zx_handle_t,
+ arg2: usize
+ ) -> zx_status_t;
+
+ pub fn zx_process_read_memory(
+ proc_: zx_handle_t,
+ vaddr: usize,
+ buffer: *mut u8,
+ len: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_process_write_memory(
+ proc_: zx_handle_t,
+ vaddr: usize,
+ buffer: *const u8,
+ len: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_job_create(
+ parent_job: zx_handle_t,
+ options: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_job_set_policy(
+ job: zx_handle_t,
+ options: u32,
+ topic: u32,
+ policy: *const u8,
+ count: u32
+ ) -> zx_status_t;
+
+ pub fn zx_task_bind_exception_port(
+ object: zx_handle_t,
+ eport: zx_handle_t,
+ key: u64,
+ options: u32
+ ) -> zx_status_t;
+
+ pub fn zx_task_suspend(
+ task_handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_task_resume(
+ task_handle: zx_handle_t,
+ options: u32
+ ) -> zx_status_t;
+
+ pub fn zx_task_kill(
+ task_handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_event_create(
+ options: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_eventpair_create(
+ options: u32,
+ out0: *mut zx_handle_t,
+ out1: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_futex_wait(
+ value_ptr: *mut zx_futex_t,
+ current_value: isize,
+ deadline: zx_time_t
+ ) -> zx_status_t;
+
+ pub fn zx_futex_wake(
+ value_ptr: *const zx_futex_t,
+ count: u32
+ ) -> zx_status_t;
+
+ pub fn zx_futex_requeue(
+ wake_ptr: *mut zx_futex_t,
+ wake_count: u32,
+ current_value: isize,
+ requeue_ptr: *mut zx_futex_t,
+ requeue_count: u32
+ ) -> zx_status_t;
+
+ pub fn zx_port_create(
+ options: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_port_queue(
+ handle: zx_handle_t,
+ packet: *const u8,
+ size: usize
+ ) -> zx_status_t;
+
+ pub fn zx_port_wait(
+ handle: zx_handle_t,
+ deadline: zx_time_t,
+ packet: *mut u8,
+ size: usize
+ ) -> zx_status_t;
+
+ pub fn zx_port_cancel(
+ handle: zx_handle_t,
+ source: zx_handle_t,
+ key: u64
+ ) -> zx_status_t;
+
+ pub fn zx_timer_create(
+ options: u32,
+ clock_id: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_timer_set(
+ handle: zx_handle_t,
+ deadline: zx_time_t,
+ slack: zx_duration_t
+ ) -> zx_status_t;
+
+ pub fn zx_timer_cancel(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_create(
+ size: u64,
+ options: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_read(
+ handle: zx_handle_t,
+ data: *mut u8,
+ offset: u64,
+ len: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_write(
+ handle: zx_handle_t,
+ data: *const u8,
+ offset: u64,
+ len: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_get_size(
+ handle: zx_handle_t,
+ size: *mut u64
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_set_size(
+ handle: zx_handle_t,
+ size: u64
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_op_range(
+ handle: zx_handle_t,
+ op: u32,
+ offset: u64,
+ size: u64,
+ buffer: *mut u8,
+ buffer_size: usize
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_clone(
+ handle: zx_handle_t,
+ options: u32,
+ offset: u64,
+ size: u64,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_set_cache_policy(
+ handle: zx_handle_t,
+ cache_policy: u32
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_allocate(
+ parent_vmar_handle: zx_handle_t,
+ offset: usize,
+ size: usize,
+ map_flags: u32,
+ child_vmar: *mut zx_handle_t,
+ child_addr: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_destroy(
+ vmar_handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_map(
+ vmar_handle: zx_handle_t,
+ vmar_offset: usize,
+ vmo_handle: zx_handle_t,
+ vmo_offset: u64,
+ len: usize,
+ map_flags: u32,
+ mapped_addr: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_unmap(
+ vmar_handle: zx_handle_t,
+ addr: usize,
+ len: usize
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_protect(
+ vmar_handle: zx_handle_t,
+ addr: usize,
+ len: usize,
+ prot_flags: u32
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_root_self() -> zx_handle_t;
+
+ pub fn zx_cprng_draw(
+ buffer: *mut u8,
+ len: usize,
+ actual: *mut usize
+ ) -> zx_status_t;
+
+ pub fn zx_cprng_add_entropy(
+ buffer: *const u8,
+ len: usize
+ ) -> zx_status_t;
+
+ pub fn zx_fifo_create(
+ elem_count: u32,
+ elem_size: u32,
+ options: u32,
+ out0: *mut zx_handle_t,
+ out1: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_fifo_read(
+ handle: zx_handle_t,
+ data: *mut u8,
+ len: usize,
+ num_written: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_fifo_write(
+ handle: zx_handle_t,
+ data: *const u8,
+ len: usize,
+ num_written: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_vmar_unmap_handle_close_thread_exit(
+ vmar_handle: zx_handle_t,
+ addr: usize,
+ len: usize,
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_futex_wake_handle_close_thread_exit(
+ value_ptr: *const zx_futex_t,
+ count: u32,
+ new_value: isize,
+ handle: zx_handle_t
+ );
+
+ pub fn zx_log_create(
+ options: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_log_write(
+ handle: zx_handle_t,
+ len: u32,
+ buffer: *const u8,
+ options: u32
+ ) -> zx_status_t;
+
+ pub fn zx_log_read(
+ handle: zx_handle_t,
+ len: u32,
+ buffer: *mut u8,
+ options: u32
+ ) -> zx_status_t;
+
+ pub fn zx_ktrace_read(
+ handle: zx_handle_t,
+ data: *mut u8,
+ offset: u32,
+ len: u32,
+ actual: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_ktrace_control(
+ handle: zx_handle_t,
+ action: u32,
+ options: u32,
+ ptr: *mut u8
+ ) -> zx_status_t;
+
+ pub fn zx_ktrace_write(
+ handle: zx_handle_t,
+ id: u32,
+ arg0: u32,
+ arg1: u32
+ ) -> zx_status_t;
+
+ pub fn zx_mtrace_control(
+ handle: zx_handle_t,
+ kind: u32,
+ action: u32,
+ options: u32,
+ ptr: *mut u8,
+ size: u32
+ ) -> zx_status_t;
+
+ pub fn zx_debug_read(
+ handle: zx_handle_t,
+ buffer: *mut u8,
+ length: u32
+ ) -> zx_status_t;
+
+ pub fn zx_debug_write(
+ buffer: *const u8,
+ length: u32
+ ) -> zx_status_t;
+
+ pub fn zx_debug_send_command(
+ resource_handle: zx_handle_t,
+ buffer: *const u8,
+ length: u32
+ ) -> zx_status_t;
+
+ pub fn zx_interrupt_create(
+ handle: zx_handle_t,
+ vector: u32,
+ options: u32,
+ out_handle: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_interrupt_complete(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_interrupt_wait(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_interrupt_signal(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_mmap_device_io(
+ handle: zx_handle_t,
+ io_addr: u32,
+ len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_create_contiguous(
+ rsrc_handle: zx_handle_t,
+ size: usize,
+ alignment_log2: u32,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vmo_create_physical(
+ rsrc_handle: zx_handle_t,
+ paddr: zx_paddr_t,
+ size: usize,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_bootloader_fb_get_info(
+ format: *mut u32,
+ width: *mut u32,
+ height: *mut u32,
+ stride: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_set_framebuffer(
+ handle: zx_handle_t,
+ vaddr: *mut u8,
+ len: u32,
+ format: u32,
+ width: u32,
+ height: u32,
+ stride: u32
+ ) -> zx_status_t;
+
+ pub fn zx_set_framebuffer_vmo(
+ handle: zx_handle_t,
+ vmo: zx_handle_t,
+ len: u32,
+ format: u32,
+ width: u32,
+ height: u32,
+ stride: u32
+ ) -> zx_status_t;
+
+ pub fn zx_pci_get_nth_device(
+ handle: zx_handle_t,
+ index: u32,
+ out_info: *mut zx_pcie_device_info_t,
+ out_handle: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_pci_enable_bus_master(
+ handle: zx_handle_t,
+ enable: bool
+ ) -> zx_status_t;
+
+ pub fn zx_pci_enable_pio(
+ handle: zx_handle_t,
+ enable: bool
+ ) -> zx_status_t;
+
+ pub fn zx_pci_reset_device(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_pci_cfg_pio_rw(
+ handle: zx_handle_t,
+ bus: u8,
+ dev: u8,
+ func: u8,
+ offset: u8,
+ val: *mut u32,
+ width: usize,
+ write: bool
+ ) -> zx_status_t;
+
+ pub fn zx_pci_get_bar(
+ handle: zx_handle_t,
+ bar_num: u32,
+ out_bar: *mut zx_pci_resource_t
+ ) -> zx_status_t;
+
+ pub fn zx_pci_get_config(
+ handle: zx_handle_t,
+ out_config: *mut zx_pci_resource_t
+ ) -> zx_status_t;
+
+ pub fn zx_pci_io_write(
+ handle: zx_handle_t,
+ bar_num: u32,
+ offset: u32,
+ len: u32,
+ value: u32
+ ) -> zx_status_t;
+
+ pub fn zx_pci_io_read(
+ handle: zx_handle_t,
+ bar_num: u32,
+ offset: u32,
+ len: u32,
+ out_value: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_pci_map_interrupt(
+ handle: zx_handle_t,
+ which_irq: i32,
+ out_handle: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_pci_query_irq_mode_caps(
+ handle: zx_handle_t,
+ mode: u32,
+ out_max_irqs: *mut u32
+ ) -> zx_status_t;
+
+ pub fn zx_pci_set_irq_mode(
+ handle: zx_handle_t,
+ mode: u32,
+ requested_irq_count: u32
+ ) -> zx_status_t;
+
+ pub fn zx_pci_init(
+ handle: zx_handle_t,
+ init_buf: *const zx_pci_init_arg_t,
+ len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_pci_add_subtract_io_range(
+ handle: zx_handle_t,
+ mmio: bool,
+ base: u64,
+ len: u64,
+ add: bool
+ ) -> zx_status_t;
+
+ pub fn zx_acpi_uefi_rsdp(
+ handle: zx_handle_t
+ ) -> u64;
+
+ pub fn zx_acpi_cache_flush(
+ handle: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_resource_create(
+ parent_handle: zx_handle_t,
+ kind: u32,
+ low: u64,
+ high: u64,
+ resource_out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_guest_create(
+ resource: zx_handle_t,
+ options: u32,
+ physmem_vmo: zx_handle_t,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_guest_set_trap(
+ guest: zx_handle_t,
+ kind: u32,
+ addr: zx_vaddr_t,
+ len: usize,
+ fifo: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vcpu_create(
+ guest: zx_handle_t,
+ options: u32,
+ args: *const zx_vcpu_create_args_t,
+ out: *mut zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_vcpu_resume(
+ vcpu: zx_handle_t,
+ packet: *mut zx_guest_packet_t
+ ) -> zx_status_t;
+
+ pub fn zx_vcpu_interrupt(
+ vcpu: zx_handle_t,
+ vector: u32
+ ) -> zx_status_t;
+
+ pub fn zx_vcpu_read_state(
+ vcpu: zx_handle_t,
+ kind: u32,
+ buffer: *mut u8,
+ len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_vcpu_write_state(
+ vcpu: zx_handle_t,
+ kind: u32,
+ buffer: *const u8,
+ len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_system_mexec(
+ kernel: zx_handle_t,
+ bootimage: zx_handle_t,
+ cmdline: *const u8,
+ cmdline_len: u32
+ ) -> zx_status_t;
+
+ pub fn zx_job_set_relative_importance(
+ root_resource: zx_handle_t,
+ job: zx_handle_t,
+ less_important_job: zx_handle_t
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_0(
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_1(
+ a: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_2(
+ a: isize,
+ b: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_3(
+ a: isize,
+ b: isize,
+ c: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_4(
+ a: isize,
+ b: isize,
+ c: isize,
+ d: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_5(
+ a: isize,
+ b: isize,
+ c: isize,
+ d: isize,
+ e: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_6(
+ a: isize,
+ b: isize,
+ c: isize,
+ d: isize,
+ e: isize,
+ f: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_7(
+ a: isize,
+ b: isize,
+ c: isize,
+ d: isize,
+ e: isize,
+ f: isize,
+ g: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_8(
+ a: isize,
+ b: isize,
+ c: isize,
+ d: isize,
+ e: isize,
+ f: isize,
+ g: isize,
+ h: isize
+ ) -> zx_status_t;
+
+ pub fn zx_syscall_test_wrapper(
+ a: isize,
+ b: isize,
+ c: isize
+ ) -> zx_status_t;
+
+
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon-sys/src/lib.rs
@@ -0,0 +1,460 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#![allow(non_camel_case_types)]
+
+#[macro_use]
+extern crate bitflags;
+
+use std::{cmp, fmt};
+
+pub type zx_handle_t = i32;
+
+pub type zx_status_t = i32;
+
+pub type zx_futex_t = isize;
+pub type zx_addr_t = usize;
+pub type zx_paddr_t = usize;
+pub type zx_vaddr_t = usize;
+pub type zx_off_t = u64;
+
+// Auto-generated using tools/gen_status.py
+pub const ZX_OK : zx_status_t = 0;
+pub const ZX_ERR_INTERNAL : zx_status_t = -1;
+pub const ZX_ERR_NOT_SUPPORTED : zx_status_t = -2;
+pub const ZX_ERR_NO_RESOURCES : zx_status_t = -3;
+pub const ZX_ERR_NO_MEMORY : zx_status_t = -4;
+pub const ZX_ERR_CALL_FAILED : zx_status_t = -5;
+pub const ZX_ERR_INTERRUPTED_RETRY : zx_status_t = -6;
+pub const ZX_ERR_INVALID_ARGS : zx_status_t = -10;
+pub const ZX_ERR_BAD_HANDLE : zx_status_t = -11;
+pub const ZX_ERR_WRONG_TYPE : zx_status_t = -12;
+pub const ZX_ERR_BAD_SYSCALL : zx_status_t = -13;
+pub const ZX_ERR_OUT_OF_RANGE : zx_status_t = -14;
+pub const ZX_ERR_BUFFER_TOO_SMALL : zx_status_t = -15;
+pub const ZX_ERR_BAD_STATE : zx_status_t = -20;
+pub const ZX_ERR_TIMED_OUT : zx_status_t = -21;
+pub const ZX_ERR_SHOULD_WAIT : zx_status_t = -22;
+pub const ZX_ERR_CANCELED : zx_status_t = -23;
+pub const ZX_ERR_PEER_CLOSED : zx_status_t = -24;
+pub const ZX_ERR_NOT_FOUND : zx_status_t = -25;
+pub const ZX_ERR_ALREADY_EXISTS : zx_status_t = -26;
+pub const ZX_ERR_ALREADY_BOUND : zx_status_t = -27;
+pub const ZX_ERR_UNAVAILABLE : zx_status_t = -28;
+pub const ZX_ERR_ACCESS_DENIED : zx_status_t = -30;
+pub const ZX_ERR_IO : zx_status_t = -40;
+pub const ZX_ERR_IO_REFUSED : zx_status_t = -41;
+pub const ZX_ERR_IO_DATA_INTEGRITY : zx_status_t = -42;
+pub const ZX_ERR_IO_DATA_LOSS : zx_status_t = -43;
+pub const ZX_ERR_BAD_PATH : zx_status_t = -50;
+pub const ZX_ERR_NOT_DIR : zx_status_t = -51;
+pub const ZX_ERR_NOT_FILE : zx_status_t = -52;
+pub const ZX_ERR_FILE_BIG : zx_status_t = -53;
+pub const ZX_ERR_NO_SPACE : zx_status_t = -54;
+pub const ZX_ERR_STOP : zx_status_t = -60;
+pub const ZX_ERR_NEXT : zx_status_t = -61;
+
+pub type zx_time_t = u64;
+pub type zx_duration_t = u64;
+pub const ZX_TIME_INFINITE : zx_time_t = ::std::u64::MAX;
+
+bitflags! {
+ #[repr(C)]
+ pub flags zx_signals_t: u32 {
+ const ZX_SIGNAL_NONE = 0,
+ const ZX_OBJECT_SIGNAL_ALL = 0x00ffffff,
+ const ZX_USER_SIGNAL_ALL = 0xff000000,
+ const ZX_OBJECT_SIGNAL_0 = 1 << 0,
+ const ZX_OBJECT_SIGNAL_1 = 1 << 1,
+ const ZX_OBJECT_SIGNAL_2 = 1 << 2,
+ const ZX_OBJECT_SIGNAL_3 = 1 << 3,
+ const ZX_OBJECT_SIGNAL_4 = 1 << 4,
+ const ZX_OBJECT_SIGNAL_5 = 1 << 5,
+ const ZX_OBJECT_SIGNAL_6 = 1 << 6,
+ const ZX_OBJECT_SIGNAL_7 = 1 << 7,
+ const ZX_OBJECT_SIGNAL_8 = 1 << 8,
+ const ZX_OBJECT_SIGNAL_9 = 1 << 9,
+ const ZX_OBJECT_SIGNAL_10 = 1 << 10,
+ const ZX_OBJECT_SIGNAL_11 = 1 << 11,
+ const ZX_OBJECT_SIGNAL_12 = 1 << 12,
+ const ZX_OBJECT_SIGNAL_13 = 1 << 13,
+ const ZX_OBJECT_SIGNAL_14 = 1 << 14,
+ const ZX_OBJECT_SIGNAL_15 = 1 << 15,
+ const ZX_OBJECT_SIGNAL_16 = 1 << 16,
+ const ZX_OBJECT_SIGNAL_17 = 1 << 17,
+ const ZX_OBJECT_SIGNAL_18 = 1 << 18,
+ const ZX_OBJECT_SIGNAL_19 = 1 << 19,
+ const ZX_OBJECT_SIGNAL_20 = 1 << 20,
+ const ZX_OBJECT_SIGNAL_21 = 1 << 21,
+ const ZX_OBJECT_LAST_HANDLE = 1 << 22,
+ const ZX_OBJECT_HANDLE_CLOSED = 1 << 23,
+ const ZX_USER_SIGNAL_0 = 1 << 24,
+ const ZX_USER_SIGNAL_1 = 1 << 25,
+ const ZX_USER_SIGNAL_2 = 1 << 26,
+ const ZX_USER_SIGNAL_3 = 1 << 27,
+ const ZX_USER_SIGNAL_4 = 1 << 28,
+ const ZX_USER_SIGNAL_5 = 1 << 29,
+ const ZX_USER_SIGNAL_6 = 1 << 30,
+ const ZX_USER_SIGNAL_7 = 1 << 31,
+
+ const ZX_OBJECT_READABLE = ZX_OBJECT_SIGNAL_0.bits,
+ const ZX_OBJECT_WRITABLE = ZX_OBJECT_SIGNAL_1.bits,
+ const ZX_OBJECT_PEER_CLOSED = ZX_OBJECT_SIGNAL_2.bits,
+
+ // Cancelation (handle was closed while waiting with it)
+ const ZX_SIGNAL_HANDLE_CLOSED = ZX_OBJECT_HANDLE_CLOSED.bits,
+
+ // Only one user-more reference (handle) to the object exists.
+ const ZX_SIGNAL_LAST_HANDLE = ZX_OBJECT_LAST_HANDLE.bits,
+
+ // Event
+ const ZX_EVENT_SIGNALED = ZX_OBJECT_SIGNAL_3.bits,
+
+ // EventPair
+ const ZX_EPAIR_SIGNALED = ZX_OBJECT_SIGNAL_3.bits,
+ const ZX_EPAIR_CLOSED = ZX_OBJECT_SIGNAL_2.bits,
+
+ // Task signals (process, thread, job)
+ const ZX_TASK_TERMINATED = ZX_OBJECT_SIGNAL_3.bits,
+
+ // Channel
+ const ZX_CHANNEL_READABLE = ZX_OBJECT_SIGNAL_0.bits,
+ const ZX_CHANNEL_WRITABLE = ZX_OBJECT_SIGNAL_1.bits,
+ const ZX_CHANNEL_PEER_CLOSED = ZX_OBJECT_SIGNAL_2.bits,
+
+ // Socket
+ const ZX_SOCKET_READABLE = ZX_OBJECT_SIGNAL_0.bits,
+ const ZX_SOCKET_WRITABLE = ZX_OBJECT_SIGNAL_1.bits,
+ const ZX_SOCKET_PEER_CLOSED = ZX_OBJECT_SIGNAL_2.bits,
+
+ // Port
+ const ZX_PORT_READABLE = ZX_OBJECT_READABLE.bits,
+
+ // Resource
+ const ZX_RESOURCE_DESTROYED = ZX_OBJECT_SIGNAL_3.bits,
+ const ZX_RESOURCE_READABLE = ZX_OBJECT_READABLE.bits,
+ const ZX_RESOURCE_WRITABLE = ZX_OBJECT_WRITABLE.bits,
+ const ZX_RESOURCE_CHILD_ADDED = ZX_OBJECT_SIGNAL_4.bits,
+
+ // Fifo
+ const ZX_FIFO_READABLE = ZX_OBJECT_READABLE.bits,
+ const ZX_FIFO_WRITABLE = ZX_OBJECT_WRITABLE.bits,
+ const ZX_FIFO_PEER_CLOSED = ZX_OBJECT_PEER_CLOSED.bits,
+
+ // Job
+ const ZX_JOB_NO_PROCESSES = ZX_OBJECT_SIGNAL_3.bits,
+ const ZX_JOB_NO_JOBS = ZX_OBJECT_SIGNAL_4.bits,
+
+ // Process
+ const ZX_PROCESS_TERMINATED = ZX_OBJECT_SIGNAL_3.bits,
+
+ // Thread
+ const ZX_THREAD_TERMINATED = ZX_OBJECT_SIGNAL_3.bits,
+
+ // Log
+ const ZX_LOG_READABLE = ZX_OBJECT_READABLE.bits,
+ const ZX_LOG_WRITABLE = ZX_OBJECT_WRITABLE.bits,
+
+ // Timer
+ const ZX_TIMER_SIGNALED = ZX_OBJECT_SIGNAL_3.bits,
+ }
+}
+
+pub type zx_size_t = usize;
+pub type zx_ssize_t = isize;
+
+bitflags! {
+ #[repr(C)]
+ pub flags zx_rights_t: u32 {
+ const ZX_RIGHT_NONE = 0,
+ const ZX_RIGHT_DUPLICATE = 1 << 0,
+ const ZX_RIGHT_TRANSFER = 1 << 1,
+ const ZX_RIGHT_READ = 1 << 2,
+ const ZX_RIGHT_WRITE = 1 << 3,
+ const ZX_RIGHT_EXECUTE = 1 << 4,
+ const ZX_RIGHT_MAP = 1 << 5,
+ const ZX_RIGHT_GET_PROPERTY = 1 << 6,
+ const ZX_RIGHT_SET_PROPERTY = 1 << 7,
+ const ZX_RIGHT_DEBUG = 1 << 8,
+ const ZX_RIGHT_SAME_RIGHTS = 1 << 31,
+ }
+}
+
+// clock ids
+pub const ZX_CLOCK_MONOTONIC: u32 = 0;
+
+// Buffer size limits on the cprng syscalls
+pub const ZX_CPRNG_DRAW_MAX_LEN: usize = 256;
+pub const ZX_CPRNG_ADD_ENTROPY_MAX_LEN: usize = 256;
+
+// Socket flags and limits.
+pub const ZX_SOCKET_HALF_CLOSE: u32 = 1;
+
+// VM Object opcodes
+pub const ZX_VMO_OP_COMMIT: u32 = 1;
+pub const ZX_VMO_OP_DECOMMIT: u32 = 2;
+pub const ZX_VMO_OP_LOCK: u32 = 3;
+pub const ZX_VMO_OP_UNLOCK: u32 = 4;
+pub const ZX_VMO_OP_LOOKUP: u32 = 5;
+pub const ZX_VMO_OP_CACHE_SYNC: u32 = 6;
+pub const ZX_VMO_OP_CACHE_INVALIDATE: u32 = 7;
+pub const ZX_VMO_OP_CACHE_CLEAN: u32 = 8;
+pub const ZX_VMO_OP_CACHE_CLEAN_INVALIDATE: u32 = 9;
+
+// VM Object clone flags
+pub const ZX_VMO_CLONE_COPY_ON_WRITE: u32 = 1;
+
+// Mapping flags to vmar routines
+bitflags! {
+ #[repr(C)]
+ pub flags zx_vmar_flags_t: u32 {
+ // flags to vmar routines
+ const ZX_VM_FLAG_PERM_READ = 1 << 0,
+ const ZX_VM_FLAG_PERM_WRITE = 1 << 1,
+ const ZX_VM_FLAG_PERM_EXECUTE = 1 << 2,
+ const ZX_VM_FLAG_COMPACT = 1 << 3,
+ const ZX_VM_FLAG_SPECIFIC = 1 << 4,
+ const ZX_VM_FLAG_SPECIFIC_OVERWRITE = 1 << 5,
+ const ZX_VM_FLAG_CAN_MAP_SPECIFIC = 1 << 6,
+ const ZX_VM_FLAG_CAN_MAP_READ = 1 << 7,
+ const ZX_VM_FLAG_CAN_MAP_WRITE = 1 << 8,
+ const ZX_VM_FLAG_CAN_MAP_EXECUTE = 1 << 9,
+ }
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum zx_cache_policy_t {
+ ZX_CACHE_POLICY_CACHED = 0,
+ ZX_CACHE_POLICY_UNCACHED = 1,
+ ZX_CACHE_POLICY_UNCACHED_DEVICE = 2,
+ ZX_CACHE_POLICY_WRITE_COMBINING = 3,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_wait_item_t {
+ pub handle: zx_handle_t,
+ pub waitfor: zx_signals_t,
+ pub pending: zx_signals_t,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_waitset_result_t {
+ pub cookie: u64,
+ pub status: zx_status_t,
+ pub observed: zx_signals_t,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_channel_call_args_t {
+ pub wr_bytes: *const u8,
+ pub wr_handles: *const zx_handle_t,
+ pub rd_bytes: *mut u8,
+ pub rd_handles: *mut zx_handle_t,
+ pub wr_num_bytes: u32,
+ pub wr_num_handles: u32,
+ pub rd_num_bytes: u32,
+ pub rd_num_handles: u32,
+}
+
+pub type zx_pci_irq_swizzle_lut_t = [[[u32; 4]; 8]; 32];
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_pci_init_arg_t {
+ pub dev_pin_to_global_irq: zx_pci_irq_swizzle_lut_t,
+ pub num_irqs: u32,
+ pub irqs: [zx_irq_t; 32],
+ pub ecam_window_count: u32,
+ // Note: the ecam_windows field is actually a variable size array.
+ // We use a fixed size array to match the C repr.
+ pub ecam_windows: [zx_ecam_window_t; 1],
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_irq_t {
+ pub global_irq: u32,
+ pub level_triggered: bool,
+ pub active_high: bool,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_ecam_window_t {
+ pub base: u64,
+ pub size: usize,
+ pub bus_start: u8,
+ pub bus_end: u8,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_pcie_device_info_t {
+ pub vendor_id: u16,
+ pub device_id: u16,
+ pub base_class: u8,
+ pub sub_class: u8,
+ pub program_interface: u8,
+ pub revision_id: u8,
+ pub bus_id: u8,
+ pub dev_id: u8,
+ pub func_id: u8,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_pci_resource_t {
+ pub type_: u32,
+ pub size: usize,
+ // TODO: Actually a union
+ pub pio_addr: usize,
+}
+
+// TODO: Actually a union
+pub type zx_rrec_t = [u8; 64];
+
+// Ports V2
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum zx_packet_type_t {
+ ZX_PKT_TYPE_USER = 0,
+ ZX_PKT_TYPE_SIGNAL_ONE = 1,
+ ZX_PKT_TYPE_SIGNAL_REP = 2,
+}
+
+impl Default for zx_packet_type_t {
+ fn default() -> Self {
+ zx_packet_type_t::ZX_PKT_TYPE_USER
+ }
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct zx_packet_signal_t {
+ pub trigger: zx_signals_t,
+ pub observed: zx_signals_t,
+ pub count: u64,
+}
+
+pub const ZX_WAIT_ASYNC_ONCE: u32 = 0;
+pub const ZX_WAIT_ASYNC_REPEATING: u32 = 1;
+
+// Actually a union of different integer types, but this should be good enough.
+pub type zx_packet_user_t = [u8; 32];
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
+pub struct zx_port_packet_t {
+ pub key: u64,
+ pub packet_type: zx_packet_type_t,
+ pub status: i32,
+ pub union: [u8; 32],
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_guest_io_t {
+ port: u16,
+ access_size: u8,
+ input: bool,
+ // TODO: Actually a union
+ data: [u8; 4],
+}
+
+#[cfg(target_arch="aarch64")]
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_guest_memory_t {
+ addr: zx_vaddr_t,
+ inst: u32,
+}
+
+pub const X86_MAX_INST_LEN: usize = 15;
+
+#[cfg(target_arch="x86_64")]
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_guest_memory_t {
+ addr: zx_vaddr_t,
+ inst_len: u8,
+ inst_buf: [u8; X86_MAX_INST_LEN],
+}
+
+#[repr(u8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum zx_guest_packet_t_type {
+ ZX_GUEST_PKT_MEMORY = 1,
+ ZX_GUEST_PKT_IO = 2,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union zx_guest_packet_t_union {
+ // ZX_GUEST_PKT_MEMORY
+ memory: zx_guest_memory_t,
+ // ZX_GUEST_PKT_IO
+ io: zx_guest_io_t,
+}
+
+// Note: values of this type must maintain the invariant that
+// `packet_type` correctly indicates the type of `contents`.
+// Failure to do so will result in unsafety.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct zx_guest_packet_t {
+ packet_type: zx_guest_packet_t_type,
+ contents: zx_guest_packet_t_union,
+}
+
+impl fmt::Debug for zx_guest_packet_t {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(f, "zx_guest_packet_t {{ packet_type: {:?}, contents: ", self.packet_type)?;
+ match self.packet_type {
+ zx_guest_packet_t_type::ZX_GUEST_PKT_MEMORY =>
+ write!(f, "zx_guest_packet_t_union {{ memory: {:?} }} }}",
+ unsafe { self.contents.memory }
+ ),
+ zx_guest_packet_t_type::ZX_GUEST_PKT_IO =>
+ write!(f, "zx_guest_packet_t_union {{ io: {:?} }} }}",
+ unsafe { self.contents.io }
+ ),
+ }
+ }
+}
+
+impl cmp::PartialEq for zx_guest_packet_t {
+ fn eq(&self, other: &Self) -> bool {
+ (self.packet_type == other.packet_type) &&
+ match self.packet_type {
+ zx_guest_packet_t_type::ZX_GUEST_PKT_MEMORY =>
+ unsafe { self.contents.memory == other.contents.memory },
+ zx_guest_packet_t_type::ZX_GUEST_PKT_IO =>
+ unsafe { self.contents.io == other.contents.io },
+ }
+ }
+}
+
+impl cmp::Eq for zx_guest_packet_t {}
+
+#[cfg(target_arch="x86_64")]
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_vcpu_create_args_t {
+ pub ip: zx_vaddr_t,
+ pub cr3: zx_vaddr_t,
+ pub apic_vmo: zx_handle_t,
+}
+
+#[cfg(not(target_arch="x86_64"))]
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct zx_vcpu_create_args_t {
+ pub ip: zx_vaddr_t,
+}
+
+include!("definitions.rs");
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","BUILD.gn":"1d49d75a432f5b4587b59a50a9b86a21e2a3faf1fff60876b4e486e43cffca35","Cargo.toml":"263dce41c44c34a70fb9803acbfb77c1801ff2b23f0fa46bb2c90f14f33f0ac9","LICENSE":"f82f9062a6dff28145c185f90f94c485eebdc2bb4c6f1c840513709e6d228453","README.md":"f4bff6efc5d888460e2d1eaf62fa0eaca8afe7b51df528ad7829340ec397b32c","examples/BUILD.gn":"fb7a491a26e5f3d48b8796db80d475be2d361bada7311213363dcce4efa9d4fc","src/channel.rs":"0b3c3761a831c9211e327f5332e58becc287cf2444b44164a4f680dc5bdded50","src/event.rs":"9b11c6c0c9fcdbe4e45c03f4a671ef66c31a1be540d3f50a5d0602314fdc1294","src/eventpair.rs":"aca1c6a15450badbfe71c33e287bab8aa05d6fff5968513b191436b853929ca8","src/fifo.rs":"ecc49463cc28713c1375ecafc8008b806767417da72fcc8685b42078ec0308df","src/job.rs":"827db2e4ea1bbf5ecabec9fb279f2721792032e4223b6bd15b56922d80c7ac01","src/lib.rs":"5bc01f9c7d1f3316826bf86cc5c8488523ca7f2ad2a58a8b539c3b49aed3f1a2","src/port.rs":"695aa7114d88d476954fde689180502f22ea6b70339855ebff89dce6694abb9e","src/process.rs":"0b5e42c4eb79b2a7fff9c70f0d99c8b805cefab99285e94fabf2542290b4b990","src/socket.rs":"6e8b799a8f605d42681660129989c9c6427b9039b83de9954c61aa351596218f","src/thread.rs":"d703414c440b5fa597dbafe7b8be925a94d1fe0cf8b47366c786b45eaaec4c60","src/timer.rs":"8fc50736e6a928cabccf78b18aec3e57ac7e5a57c1c519a1cd34158f59e1ff65","src/vmo.rs":"0f219777d5abffcfbc49a43f7eff3ef92b854d1d964579dc9a01d33ba57341c1","tools/BUILD.gn":"f4ce07b2906e6cde15a9d2ec253c58fbfe88ea1819083f864c154a0f1c50c14f","tools/README.md":"0217d58913c32b7e8aa231da852d96307d8387f99e2352a026196150cb180d07","tools/clang_wrapper.cc":"c62dcc1f71cab03f7e215c8800d798bd05af56fa7510ea8d59d6b15dce2b6a6f","tools/gen_status.py":"a2330db86564e12412af2dce60d4c605c0ab203fcdea8039d5c6a8e7f218a3c3"},"package":"f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/rust/rust_library.gni")
+
+rust_library("fuchsia-zircon") {
+ deps = [
+ "//garnet/public/rust/crates/fuchsia-zircon/fuchsia-zircon-sys",
+ ]
+
+ with_tests = true
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/Cargo.toml
@@ -0,0 +1,21 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "fuchsia-zircon"
+version = "0.2.1"
+authors = ["Raph Levien <raph@google.com>"]
+description = "Rust bindings for the Zircon kernel"
+license = "BSD-3-Clause"
+repository = "https://fuchsia.googlesource.com/garnet/"
+[dependencies.fuchsia-zircon-sys]
+version = "0.2.0"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/README.md
@@ -0,0 +1,12 @@
+Rust bindings for Zircon kernel
+================================
+
+This repository contains Rust language bindings for Zircon kernel syscalls. The
+main crate contains type-safe wrappers, while the inner "sys" crate contains the
+raw types and FFI declarations.
+
+There are two ways to build Rust artifacts targeting Fuchsia; using the
+[Fargo](https://fuchsia.googlesource.com/fargo/) cross compiling tool or
+including your [artifact in the GN
+build](https://fuchsia.googlesource.com/docs/+/master/rust.md). Of the two,
+Fargo is likely better for exploration and experimentation.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/examples/BUILD.gn
@@ -0,0 +1,9 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+group("examples") {
+ deps = [
+ "//garnet/public/rust/crates/fuchsia-zircon/examples/zx_toy",
+ ]
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/channel.rs
@@ -0,0 +1,380 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon channel objects.
+
+use {AsHandleRef, HandleBased, Handle, HandleRef, INVALID_HANDLE, Peered, Status, Time, usize_into_u32, size_to_u32_sat};
+use {sys, handle_drop, into_result};
+use std::mem;
+
+/// An object representing a Zircon
+/// [channel](https://fuchsia.googlesource.com/zircon/+/master/docs/objects/channel.md).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Channel(Handle);
+impl_handle_based!(Channel);
+impl Peered for Channel {}
+
+impl Channel {
+ /// Create a channel, resulting an a pair of `Channel` objects representing both
+ /// sides of the channel. Messages written into one maybe read from the opposite.
+ ///
+ /// Wraps the
+ /// [zx_channel_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_create.md)
+ /// syscall.
+ pub fn create(opts: ChannelOpts) -> Result<(Channel, Channel), Status> {
+ unsafe {
+ let mut handle0 = 0;
+ let mut handle1 = 0;
+ let status = sys::zx_channel_create(opts as u32, &mut handle0, &mut handle1);
+ into_result(status, ||
+ (Self::from(Handle(handle0)),
+ Self::from(Handle(handle1))))
+ }
+ }
+
+ /// Read a message from a channel. Wraps the
+ /// [zx_channel_read](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_read.md)
+ /// syscall.
+ ///
+ /// If the `MessageBuf` lacks the capacity to hold the pending message,
+ /// returns an `Err` with the number of bytes and number of handles needed.
+ /// Otherwise returns an `Ok` with the result as usual.
+ pub fn read_raw(&self, opts: u32, buf: &mut MessageBuf)
+ -> Result<Result<(), Status>, (usize, usize)>
+ {
+ unsafe {
+ buf.reset_handles();
+ let raw_handle = self.raw_handle();
+ let mut num_bytes: u32 = size_to_u32_sat(buf.bytes.capacity());
+ let mut num_handles: u32 = size_to_u32_sat(buf.handles.capacity());
+ let status = sys::zx_channel_read(raw_handle, opts,
+ buf.bytes.as_mut_ptr(), buf.handles.as_mut_ptr(),
+ num_bytes, num_handles, &mut num_bytes, &mut num_handles);
+ if status == sys::ZX_ERR_BUFFER_TOO_SMALL {
+ Err((num_bytes as usize, num_handles as usize))
+ } else {
+ Ok(into_result(status, || {
+ buf.bytes.set_len(num_bytes as usize);
+ buf.handles.set_len(num_handles as usize);
+ }))
+ }
+ }
+ }
+
+ /// Read a message from a channel.
+ ///
+ /// Note that this method can cause internal reallocations in the `MessageBuf`
+ /// if it is lacks capacity to hold the full message. If such reallocations
+ /// are not desirable, use `read_raw` instead.
+ pub fn read(&self, opts: u32, buf: &mut MessageBuf) -> Result<(), Status> {
+ loop {
+ match self.read_raw(opts, buf) {
+ Ok(result) => return result,
+ Err((num_bytes, num_handles)) => {
+ buf.ensure_capacity_bytes(num_bytes);
+ buf.ensure_capacity_handles(num_handles);
+ }
+ }
+ }
+ }
+
+ /// Write a message to a channel. Wraps the
+ /// [zx_channel_write](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_write.md)
+ /// syscall.
+ pub fn write(&self, bytes: &[u8], handles: &mut Vec<Handle>, opts: u32)
+ -> Result<(), Status>
+ {
+ let n_bytes = try!(usize_into_u32(bytes.len()).map_err(|_| Status::ErrOutOfRange));
+ let n_handles = try!(usize_into_u32(handles.len()).map_err(|_| Status::ErrOutOfRange));
+ unsafe {
+ let status = sys::zx_channel_write(self.raw_handle(), opts, bytes.as_ptr(), n_bytes,
+ handles.as_ptr() as *const sys::zx_handle_t, n_handles);
+ into_result(status, || {
+ // Handles were successfully transferred, forget them on sender side
+ handles.set_len(0);
+ })
+ }
+ }
+
+ /// Send a message consisting of the given bytes and handles to a channel and await a reply. The
+ /// bytes should start with a four byte 'txid' which is used to identify the matching reply.
+ ///
+ /// Wraps the
+ /// [zx_channel_call](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_call.md)
+ /// syscall.
+ ///
+ /// Note that unlike [`read`][read], the caller must ensure that the MessageBuf has enough
+ /// capacity for the bytes and handles which will be received, as replies which are too large
+ /// are discarded.
+ ///
+ /// On failure returns the both the main and read status.
+ ///
+ /// [read]: struct.Channel.html#method.read
+ pub fn call(&self, options: u32, timeout: Time, bytes: &[u8], handles: &mut Vec<Handle>,
+ buf: &mut MessageBuf) -> Result<(), (Status, Status)>
+ {
+ let write_num_bytes = try!(usize_into_u32(bytes.len()).map_err(
+ |_| (Status::ErrOutOfRange, Status::NoError)));
+ let write_num_handles = try!(usize_into_u32(handles.len()).map_err(
+ |_| (Status::ErrOutOfRange, Status::NoError)));
+ buf.reset_handles();
+ let read_num_bytes: u32 = size_to_u32_sat(buf.bytes.capacity());
+ let read_num_handles: u32 = size_to_u32_sat(buf.handles.capacity());
+ let args = sys::zx_channel_call_args_t {
+ wr_bytes: bytes.as_ptr(),
+ wr_handles: handles.as_ptr() as *const sys::zx_handle_t,
+ rd_bytes: buf.bytes.as_mut_ptr(),
+ rd_handles: buf.handles.as_mut_ptr(),
+ wr_num_bytes: write_num_bytes,
+ wr_num_handles: write_num_handles,
+ rd_num_bytes: read_num_bytes,
+ rd_num_handles: read_num_handles,
+ };
+ let mut actual_read_bytes: u32 = 0;
+ let mut actual_read_handles: u32 = 0;
+ let mut read_status = sys::ZX_OK;
+ let status = unsafe {
+ sys::zx_channel_call(self.raw_handle(), options, timeout, &args, &mut actual_read_bytes,
+ &mut actual_read_handles, &mut read_status)
+ };
+ if status == sys::ZX_OK || status == sys::ZX_ERR_TIMED_OUT || status == sys::ZX_ERR_CALL_FAILED
+ {
+ // Handles were successfully transferred, even if we didn't get a response, so forget
+ // them on the sender side.
+ unsafe { handles.set_len(0); }
+ }
+ unsafe {
+ buf.bytes.set_len(actual_read_bytes as usize);
+ buf.handles.set_len(actual_read_handles as usize);
+ }
+ if status == sys::ZX_OK {
+ Ok(())
+ } else {
+ Err((Status::from_raw(status), Status::from_raw(read_status)))
+ }
+ }
+}
+
+/// Options for creating a channel.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum ChannelOpts {
+ /// A normal channel.
+ Normal = 0,
+}
+
+impl Default for ChannelOpts {
+ fn default() -> Self {
+ ChannelOpts::Normal
+ }
+}
+
+/// A buffer for _receiving_ messages from a channel.
+///
+/// A `MessageBuf` is essentially a byte buffer and a vector of
+/// handles, but move semantics for "taking" handles requires special handling.
+///
+/// Note that for sending messages to a channel, the caller manages the buffers,
+/// using a plain byte slice and `Vec<Handle>`.
+#[derive(Default)]
+#[derive(Debug)]
+pub struct MessageBuf {
+ bytes: Vec<u8>,
+ handles: Vec<sys::zx_handle_t>,
+}
+
+impl MessageBuf {
+ /// Create a new, empty, message buffer.
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ /// Ensure that the buffer has the capacity to hold at least `n_bytes` bytes.
+ pub fn ensure_capacity_bytes(&mut self, n_bytes: usize) {
+ ensure_capacity(&mut self.bytes, n_bytes);
+ }
+
+ /// Ensure that the buffer has the capacity to hold at least `n_handles` handles.
+ pub fn ensure_capacity_handles(&mut self, n_handles: usize) {
+ ensure_capacity(&mut self.handles, n_handles);
+ }
+
+ /// Get a reference to the bytes of the message buffer, as a `&[u8]` slice.
+ pub fn bytes(&self) -> &[u8] {
+ self.bytes.as_slice()
+ }
+
+ /// The number of handles in the message buffer. Note this counts the number
+ /// available when the message was received; `take_handle` does not affect
+ /// the count.
+ pub fn n_handles(&self) -> usize {
+ self.handles.len()
+ }
+
+ /// Take the handle at the specified index from the message buffer. If the
+ /// method is called again with the same index, it will return `None`, as
+ /// will happen if the index exceeds the number of handles available.
+ pub fn take_handle(&mut self, index: usize) -> Option<Handle> {
+ self.handles.get_mut(index).and_then(|handleref|
+ if *handleref == INVALID_HANDLE {
+ None
+ } else {
+ Some(Handle(mem::replace(handleref, INVALID_HANDLE)))
+ }
+ )
+ }
+
+ fn drop_handles(&mut self) {
+ for &handle in &self.handles {
+ if handle != 0 {
+ handle_drop(handle);
+ }
+ }
+ }
+
+ fn reset_handles(&mut self) {
+ self.drop_handles();
+ self.handles.clear();
+ }
+}
+
+impl Drop for MessageBuf {
+ fn drop(&mut self) {
+ self.drop_handles();
+ }
+}
+
+fn ensure_capacity<T>(vec: &mut Vec<T>, size: usize) {
+ let len = vec.len();
+ if size > len {
+ vec.reserve(size - len);
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use {Duration, ZX_CHANNEL_READABLE, ZX_CHANNEL_WRITABLE, ZX_RIGHT_SAME_RIGHTS, ZX_SIGNAL_LAST_HANDLE, Vmo, VmoOpts};
+ use deadline_after;
+ use std::thread;
+
+ #[test]
+ fn channel_basic() {
+ let (p1, p2) = Channel::create(ChannelOpts::Normal).unwrap();
+
+ let mut empty = vec![];
+ assert!(p1.write(b"hello", &mut empty, 0).is_ok());
+
+ let mut buf = MessageBuf::new();
+ assert!(p2.read(0, &mut buf).is_ok());
+ assert_eq!(buf.bytes(), b"hello");
+ }
+
+ #[test]
+ fn channel_read_raw_too_small() {
+ let (p1, p2) = Channel::create(ChannelOpts::Normal).unwrap();
+
+ let mut empty = vec![];
+ assert!(p1.write(b"hello", &mut empty, 0).is_ok());
+
+ let mut buf = MessageBuf::new();
+ let result = p2.read_raw(0, &mut buf);
+ assert_eq!(result, Err((5, 0)));
+ assert_eq!(buf.bytes(), b"");
+ }
+
+ #[test]
+ fn channel_send_handle() {
+ let hello_length: usize = 5;
+
+ // Create a pair of channels and a virtual memory object.
+ let (p1, p2) = Channel::create(ChannelOpts::Normal).unwrap();
+ let vmo = Vmo::create(hello_length as u64, VmoOpts::Default).unwrap();
+
+ // Duplicate VMO handle and send it down the channel.
+ let duplicate_vmo_handle = vmo.duplicate_handle(ZX_RIGHT_SAME_RIGHTS).unwrap().into();
+ let mut handles_to_send: Vec<Handle> = vec![duplicate_vmo_handle];
+ assert!(p1.write(b"", &mut handles_to_send, 0).is_ok());
+ // Handle should be removed from vector.
+ assert!(handles_to_send.is_empty());
+
+ // Read the handle from the receiving channel.
+ let mut buf = MessageBuf::new();
+ assert!(p2.read(0, &mut buf).is_ok());
+ assert_eq!(buf.n_handles(), 1);
+ // Take the handle from the buffer.
+ let received_handle = buf.take_handle(0).unwrap();
+ // Should not affect number of handles.
+ assert_eq!(buf.n_handles(), 1);
+ // Trying to take it again should fail.
+ assert!(buf.take_handle(0).is_none());
+
+ // Now to test that we got the right handle, try writing something to it...
+ let received_vmo = Vmo::from(received_handle);
+ assert_eq!(received_vmo.write(b"hello", 0).unwrap(), hello_length);
+
+ // ... and reading it back from the original VMO.
+ let mut read_vec = vec![0; hello_length];
+ assert_eq!(vmo.read(&mut read_vec, 0).unwrap(), hello_length);
+ assert_eq!(read_vec, b"hello");
+ }
+
+ #[test]
+ fn channel_call_timeout() {
+ let ten_ms: Duration = 10_000_000;
+
+ // Create a pair of channels and a virtual memory object.
+ let (p1, p2) = Channel::create(ChannelOpts::Normal).unwrap();
+ let vmo = Vmo::create(0 as u64, VmoOpts::Default).unwrap();
+
+ // Duplicate VMO handle and send it along with the call.
+ let duplicate_vmo_handle = vmo.duplicate_handle(ZX_RIGHT_SAME_RIGHTS).unwrap().into();
+ let mut handles_to_send: Vec<Handle> = vec![duplicate_vmo_handle];
+ let mut buf = MessageBuf::new();
+ assert_eq!(p1.call(0, deadline_after(ten_ms), b"call", &mut handles_to_send, &mut buf),
+ Err((Status::ErrTimedOut, Status::NoError)));
+ // Handle should be removed from vector even though we didn't get a response, as it was
+ // still sent over the channel.
+ assert!(handles_to_send.is_empty());
+
+ // Should be able to read call even though it timed out waiting for a response.
+ let mut buf = MessageBuf::new();
+ assert!(p2.read(0, &mut buf).is_ok());
+ assert_eq!(buf.bytes(), b"call");
+ assert_eq!(buf.n_handles(), 1);
+ }
+
+ #[test]
+ fn channel_call() {
+ let hundred_ms: Duration = 100_000_000;
+
+ // Create a pair of channels
+ let (p1, p2) = Channel::create(ChannelOpts::Normal).unwrap();
+
+ // Start a new thread to respond to the call.
+ let server = thread::spawn(move || {
+ assert_eq!(p2.wait_handle(ZX_CHANNEL_READABLE, deadline_after(hundred_ms)),
+ Ok(ZX_CHANNEL_READABLE | ZX_CHANNEL_WRITABLE | ZX_SIGNAL_LAST_HANDLE));
+ let mut buf = MessageBuf::new();
+ assert_eq!(p2.read(0, &mut buf), Ok(()));
+ assert_eq!(buf.bytes(), b"txidcall");
+ assert_eq!(buf.n_handles(), 0);
+ let mut empty = vec![];
+ assert_eq!(p2.write(b"txidresponse", &mut empty, 0), Ok(()));
+ });
+
+ // Make the call.
+ let mut empty = vec![];
+ let mut buf = MessageBuf::new();
+ buf.ensure_capacity_bytes(12);
+ assert_eq!(p1.call(0, deadline_after(hundred_ms), b"txidcall", &mut empty, &mut buf),
+ Ok(()));
+ assert_eq!(buf.bytes(), b"txidresponse");
+ assert_eq!(buf.n_handles(), 0);
+
+ assert!(server.join().is_ok());
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/event.rs
@@ -0,0 +1,42 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon event objects.
+
+use {AsHandleRef, Cookied, HandleBased, Handle, HandleRef, Status};
+use {sys, into_result};
+
+/// An object representing a Zircon
+/// [event object](https://fuchsia.googlesource.com/zircon/+/master/docs/objects/event.md).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Event(Handle);
+impl_handle_based!(Event);
+impl Cookied for Event {}
+
+impl Event {
+ /// Create an event object, an object which is signalable but nothing else. Wraps the
+ /// [zx_event_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/event_create.md)
+ /// syscall.
+ pub fn create(options: EventOpts) -> Result<Event, Status> {
+ let mut out = 0;
+ let status = unsafe { sys::zx_event_create(options as u32, &mut out) };
+ into_result(status, || Self::from(Handle(out)))
+ }
+}
+
+/// Options for creating an event object.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum EventOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for EventOpts {
+ fn default() -> Self {
+ EventOpts::Default
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/eventpair.rs
@@ -0,0 +1,75 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon event pairs.
+
+use {AsHandleRef, Cookied, HandleBased, Handle, HandleRef, Peered, Status};
+use {sys, into_result};
+
+/// An object representing a Zircon
+/// [event pair](https://fuchsia.googlesource.com/zircon/+/master/docs/concepts.md#Other-IPC_Events_Event-Pairs_and-User-Signals).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct EventPair(Handle);
+impl_handle_based!(EventPair);
+impl Peered for EventPair {}
+impl Cookied for EventPair {}
+
+impl EventPair {
+ /// Create an event pair, a pair of objects which can signal each other. Wraps the
+ /// [zx_eventpair_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/eventpair_create.md)
+ /// syscall.
+ pub fn create(options: EventPairOpts) -> Result<(EventPair, EventPair), Status> {
+ let mut out0 = 0;
+ let mut out1 = 0;
+ let status = unsafe { sys::zx_eventpair_create(options as u32, &mut out0, &mut out1) };
+ into_result(status, ||
+ (Self::from(Handle(out0)),
+ Self::from(Handle(out1))))
+ }
+}
+
+/// Options for creating an event pair.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum EventPairOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for EventPairOpts {
+ fn default() -> Self {
+ EventPairOpts::Default
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use {Duration, ZX_SIGNAL_LAST_HANDLE, ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0};
+ use deadline_after;
+
+ #[test]
+ fn wait_and_signal_peer() {
+ let (p1, p2) = EventPair::create(EventPairOpts::Default).unwrap();
+ let eighty_ms: Duration = 80_000_000;
+
+ // Waiting on one without setting any signal should time out.
+ assert_eq!(p2.wait_handle(ZX_USER_SIGNAL_0, deadline_after(eighty_ms)), Err(Status::ErrTimedOut));
+
+ // If we set a signal, we should be able to wait for it.
+ assert!(p1.signal_peer(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ assert_eq!(p2.wait_handle(ZX_USER_SIGNAL_0, deadline_after(eighty_ms)).unwrap(),
+ ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+
+ // Should still work, signals aren't automatically cleared.
+ assert_eq!(p2.wait_handle(ZX_USER_SIGNAL_0, deadline_after(eighty_ms)).unwrap(),
+ ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+
+ // Now clear it, and waiting should time out again.
+ assert!(p1.signal_peer(ZX_USER_SIGNAL_0, ZX_SIGNAL_NONE).is_ok());
+ assert_eq!(p2.wait_handle(ZX_USER_SIGNAL_0, deadline_after(eighty_ms)), Err(Status::ErrTimedOut));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/fifo.rs
@@ -0,0 +1,107 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon fifo objects.
+
+use {AsHandleRef, HandleBased, Handle, HandleRef, Status};
+use {sys, into_result};
+
+/// An object representing a Zircon fifo.
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Fifo(Handle);
+impl_handle_based!(Fifo);
+
+impl Fifo {
+ /// Create a pair of fifos and return their endpoints. Writing to one endpoint enqueues an
+ /// element into the fifo from which the opposing endpoint reads. Wraps the
+ /// [zx_fifo_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/fifo_create.md)
+ /// syscall.
+ pub fn create(elem_count: u32, elem_size: u32, options: FifoOpts)
+ -> Result<(Fifo, Fifo), Status>
+ {
+ let mut out0 = 0;
+ let mut out1 = 0;
+ let status = unsafe {
+ sys::zx_fifo_create(elem_count, elem_size, options as u32, &mut out0, &mut out1)
+ };
+ into_result(status, || (Self::from(Handle(out0)), Self::from(Handle(out1))))
+ }
+
+ /// Attempts to write some number of elements into the fifo. The number of bytes written will be
+ /// rounded down to a multiple of the fifo's element size.
+ /// Return value (on success) is number of elements actually written.
+ ///
+ /// Wraps
+ /// [zx_fifo_write](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/fifo_write.md).
+ pub fn write(&self, bytes: &[u8]) -> Result<u32, Status> {
+ let mut num_entries_written = 0;
+ let status = unsafe {
+ sys::zx_fifo_write(self.raw_handle(), bytes.as_ptr(), bytes.len(),
+ &mut num_entries_written)
+ };
+ into_result(status, || num_entries_written)
+ }
+
+ /// Attempts to read some number of elements out of the fifo. The number of bytes read will
+ /// always be a multiple of the fifo's element size.
+ /// Return value (on success) is number of elements actually read.
+ ///
+ /// Wraps
+ /// [zx_fifo_read](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/fifo_read.md).
+ pub fn read(&self, bytes: &mut [u8]) -> Result<u32, Status> {
+ let mut num_entries_read = 0;
+ let status = unsafe {
+ sys::zx_fifo_read(self.raw_handle(), bytes.as_mut_ptr(), bytes.len(),
+ &mut num_entries_read)
+ };
+ into_result(status, || num_entries_read)
+ }
+}
+
+/// Options for creating a fifo pair.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum FifoOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for FifoOpts {
+ fn default() -> Self {
+ FifoOpts::Default
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn fifo_basic() {
+ let (fifo1, fifo2) = Fifo::create(4, 2, FifoOpts::Default).unwrap();
+
+ // Trying to write less than one element should fail.
+ assert_eq!(fifo1.write(b""), Err(Status::ErrOutOfRange));
+ assert_eq!(fifo1.write(b"h"), Err(Status::ErrOutOfRange));
+
+ // Should write one element "he" and ignore the last half-element as it rounds down.
+ assert_eq!(fifo1.write(b"hex").unwrap(), 1);
+
+ // Should write three elements "ll" "o " "wo" and drop the rest as it is full.
+ assert_eq!(fifo1.write(b"llo worlds").unwrap(), 3);
+
+ // Now that the fifo is full any further attempts to write should fail.
+ assert_eq!(fifo1.write(b"blah blah"), Err(Status::ErrShouldWait));
+
+ // Read all 4 entries from the other end.
+ let mut read_vec = vec![0; 8];
+ assert_eq!(fifo2.read(&mut read_vec).unwrap(), 4);
+ assert_eq!(read_vec, b"hello wo");
+
+ // Reading again should fail as the fifo is empty.
+ assert_eq!(fifo2.read(&mut read_vec), Err(Status::ErrShouldWait));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/job.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon job.
+
+use {AsHandleRef, HandleBased, Handle, HandleRef};
+
+/// An object representing a Zircon job.
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Job(Handle);
+impl_handle_based!(Job);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/lib.rs
@@ -0,0 +1,911 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon kernel
+//! [syscalls](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls.md).
+
+extern crate fuchsia_zircon_sys as zircon_sys;
+
+use std::io;
+use std::marker::PhantomData;
+
+macro_rules! impl_handle_based {
+ ($type_name:path) => {
+ impl AsHandleRef for $type_name {
+ fn as_handle_ref(&self) -> HandleRef {
+ self.0.as_handle_ref()
+ }
+ }
+
+ impl From<Handle> for $type_name {
+ fn from(handle: Handle) -> Self {
+ $type_name(handle)
+ }
+ }
+
+ impl From<$type_name> for Handle {
+ fn from(x: $type_name) -> Handle {
+ x.0
+ }
+ }
+
+ impl HandleBased for $type_name {}
+ }
+}
+
+mod channel;
+mod event;
+mod eventpair;
+mod fifo;
+mod job;
+mod port;
+mod process;
+mod socket;
+mod timer;
+mod thread;
+mod vmo;
+
+pub use channel::{Channel, ChannelOpts, MessageBuf};
+pub use event::{Event, EventOpts};
+pub use eventpair::{EventPair, EventPairOpts};
+pub use fifo::{Fifo, FifoOpts};
+pub use job::Job;
+pub use port::{Packet, PacketContents, Port, PortOpts, SignalPacket, UserPacket, WaitAsyncOpts};
+pub use process::Process;
+pub use socket::{Socket, SocketOpts, SocketReadOpts, SocketWriteOpts};
+pub use timer::{Timer, TimerOpts};
+pub use thread::Thread;
+pub use vmo::{Vmo, VmoCloneOpts, VmoOp, VmoOpts};
+
+use zircon_sys as sys;
+
+type Duration = sys::zx_duration_t;
+type Time = sys::zx_time_t;
+pub use zircon_sys::ZX_TIME_INFINITE;
+
+// A placeholder value used for handles that have been taken from the message buf.
+// We rely on the kernel never to produce any actual handles with this value.
+const INVALID_HANDLE: sys::zx_handle_t = 0;
+
+/// A status code returned from the Zircon kernel.
+///
+/// See
+/// [errors.md](https://fuchsia.googlesource.com/zircon/+/master/docs/errors.md)
+/// in the Zircon documentation for more information about the meaning of these
+/// codes.
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[repr(i32)]
+// Auto-generated using tools/gen_status.py
+pub enum Status {
+ NoError = 0,
+ ErrInternal = -1,
+ ErrNotSupported = -2,
+ ErrNoResources = -3,
+ ErrNoMemory = -4,
+ ErrCallFailed = -5,
+ ErrInterruptedRetry = -6,
+ ErrInvalidArgs = -10,
+ ErrBadHandle = -11,
+ ErrWrongType = -12,
+ ErrBadSyscall = -13,
+ ErrOutOfRange = -14,
+ ErrBufferTooSmall = -15,
+ ErrBadState = -20,
+ ErrTimedOut = -21,
+ ErrShouldWait = -22,
+ ErrCanceled = -23,
+ ErrPeerClosed = -24,
+ ErrNotFound = -25,
+ ErrAlreadyExists = -26,
+ ErrAlreadyBound = -27,
+ ErrUnavailable = -28,
+ ErrAccessDenied = -30,
+ ErrIo = -40,
+ ErrIoRefused = -41,
+ ErrIoDataIntegrity = -42,
+ ErrIoDataLoss = -43,
+ ErrBadPath = -50,
+ ErrNotDir = -51,
+ ErrNotFile = -52,
+ ErrFileBig = -53,
+ ErrNoSpace = -54,
+ ErrStop = -60,
+ ErrNext = -61,
+
+ /// Any zx_status_t not in the set above will map to the following:
+ UnknownOther = -32768,
+
+ // used to prevent exhaustive matching
+ #[doc(hidden)]
+ __Nonexhaustive = -32787,
+}
+
+impl Status {
+ pub fn from_raw(raw: sys::zx_status_t) -> Self {
+ match raw {
+ // Auto-generated using tools/gen_status.py
+ sys::ZX_OK => Status::NoError,
+ sys::ZX_ERR_INTERNAL => Status::ErrInternal,
+ sys::ZX_ERR_NOT_SUPPORTED => Status::ErrNotSupported,
+ sys::ZX_ERR_NO_RESOURCES => Status::ErrNoResources,
+ sys::ZX_ERR_NO_MEMORY => Status::ErrNoMemory,
+ sys::ZX_ERR_CALL_FAILED => Status::ErrCallFailed,
+ sys::ZX_ERR_INTERRUPTED_RETRY => Status::ErrInterruptedRetry,
+ sys::ZX_ERR_INVALID_ARGS => Status::ErrInvalidArgs,
+ sys::ZX_ERR_BAD_HANDLE => Status::ErrBadHandle,
+ sys::ZX_ERR_WRONG_TYPE => Status::ErrWrongType,
+ sys::ZX_ERR_BAD_SYSCALL => Status::ErrBadSyscall,
+ sys::ZX_ERR_OUT_OF_RANGE => Status::ErrOutOfRange,
+ sys::ZX_ERR_BUFFER_TOO_SMALL => Status::ErrBufferTooSmall,
+ sys::ZX_ERR_BAD_STATE => Status::ErrBadState,
+ sys::ZX_ERR_TIMED_OUT => Status::ErrTimedOut,
+ sys::ZX_ERR_SHOULD_WAIT => Status::ErrShouldWait,
+ sys::ZX_ERR_CANCELED => Status::ErrCanceled,
+ sys::ZX_ERR_PEER_CLOSED => Status::ErrPeerClosed,
+ sys::ZX_ERR_NOT_FOUND => Status::ErrNotFound,
+ sys::ZX_ERR_ALREADY_EXISTS => Status::ErrAlreadyExists,
+ sys::ZX_ERR_ALREADY_BOUND => Status::ErrAlreadyBound,
+ sys::ZX_ERR_UNAVAILABLE => Status::ErrUnavailable,
+ sys::ZX_ERR_ACCESS_DENIED => Status::ErrAccessDenied,
+ sys::ZX_ERR_IO => Status::ErrIo,
+ sys::ZX_ERR_IO_REFUSED => Status::ErrIoRefused,
+ sys::ZX_ERR_IO_DATA_INTEGRITY => Status::ErrIoDataIntegrity,
+ sys::ZX_ERR_IO_DATA_LOSS => Status::ErrIoDataLoss,
+ sys::ZX_ERR_BAD_PATH => Status::ErrBadPath,
+ sys::ZX_ERR_NOT_DIR => Status::ErrNotDir,
+ sys::ZX_ERR_NOT_FILE => Status::ErrNotFile,
+ sys::ZX_ERR_FILE_BIG => Status::ErrFileBig,
+ sys::ZX_ERR_NO_SPACE => Status::ErrNoSpace,
+ sys::ZX_ERR_STOP => Status::ErrStop,
+ sys::ZX_ERR_NEXT => Status::ErrNext,
+ _ => Status::UnknownOther,
+ }
+ }
+
+ pub fn into_io_err(self) -> io::Error {
+ self.into()
+ }
+
+ // Note: no to_raw, even though it's easy to implement, partly because
+ // handling of UnknownOther would be tricky.
+}
+
+impl From<io::ErrorKind> for Status {
+ fn from(kind: io::ErrorKind) -> Self {
+ use io::ErrorKind::*;
+ use Status::*;
+
+ match kind {
+ NotFound => ErrNotFound,
+ PermissionDenied => ErrAccessDenied,
+ ConnectionRefused => ErrIoRefused,
+ ConnectionAborted => ErrPeerClosed,
+ AddrInUse => ErrAlreadyBound,
+ AddrNotAvailable => ErrUnavailable,
+ BrokenPipe => ErrPeerClosed,
+ AlreadyExists => ErrAlreadyExists,
+ WouldBlock => ErrShouldWait,
+ InvalidInput => ErrInvalidArgs,
+ TimedOut => ErrTimedOut,
+ Interrupted => ErrInterruptedRetry,
+
+ UnexpectedEof |
+ WriteZero |
+ ConnectionReset |
+ NotConnected |
+ Other | _ => ErrIo,
+ }
+ }
+}
+
+impl From<Status> for io::ErrorKind {
+ fn from(status: Status) -> io::ErrorKind {
+ use io::ErrorKind::*;
+ use Status::*;
+
+ match status {
+ ErrInterruptedRetry => Interrupted,
+ ErrBadHandle => BrokenPipe,
+ ErrTimedOut => TimedOut,
+ ErrShouldWait => WouldBlock,
+ ErrPeerClosed => ConnectionAborted,
+ ErrNotFound => NotFound,
+ ErrAlreadyExists => AlreadyExists,
+ ErrAlreadyBound => AlreadyExists,
+ ErrUnavailable => AddrNotAvailable,
+ ErrAccessDenied => PermissionDenied,
+ ErrIoRefused => ConnectionRefused,
+ ErrIoDataIntegrity => InvalidData,
+
+ ErrBadPath |
+ ErrInvalidArgs |
+ ErrOutOfRange |
+ ErrWrongType => InvalidInput,
+
+ Status::__Nonexhaustive |
+ UnknownOther |
+ NoError |
+ ErrNext |
+ ErrStop |
+ ErrNoSpace |
+ ErrFileBig |
+ ErrNotFile |
+ ErrNotDir |
+ ErrIoDataLoss |
+ ErrIo |
+ ErrCanceled |
+ ErrBadState |
+ ErrBufferTooSmall |
+ ErrBadSyscall |
+ ErrInternal |
+ ErrNotSupported |
+ ErrNoResources |
+ ErrNoMemory |
+ ErrCallFailed => Other,
+ }
+ }
+}
+
+impl From<io::Error> for Status {
+ fn from(err: io::Error) -> Status {
+ err.kind().into()
+ }
+}
+
+impl From<Status> for io::Error {
+ fn from(status: Status) -> io::Error {
+ io::Error::from(io::ErrorKind::from(status))
+ }
+}
+
+/// Rights associated with a handle.
+///
+/// See [rights.md](https://fuchsia.googlesource.com/zircon/+/master/docs/rights.md)
+/// for more information.
+pub type Rights = sys::zx_rights_t;
+pub use zircon_sys::{
+ ZX_RIGHT_NONE,
+ ZX_RIGHT_DUPLICATE,
+ ZX_RIGHT_TRANSFER,
+ ZX_RIGHT_READ,
+ ZX_RIGHT_WRITE,
+ ZX_RIGHT_EXECUTE,
+ ZX_RIGHT_MAP,
+ ZX_RIGHT_GET_PROPERTY,
+ ZX_RIGHT_SET_PROPERTY,
+ ZX_RIGHT_DEBUG,
+ ZX_RIGHT_SAME_RIGHTS,
+};
+
+/// Signals that can be waited upon.
+///
+/// See
+/// [Objects and signals](https://fuchsia.googlesource.com/zircon/+/master/docs/concepts.md#Objects-and-Signals)
+/// in the Zircon kernel documentation. Note: the names of signals are still in flux.
+pub type Signals = sys::zx_signals_t;
+
+pub use zircon_sys::{
+ ZX_SIGNAL_NONE,
+
+ ZX_SIGNAL_HANDLE_CLOSED,
+ ZX_SIGNAL_LAST_HANDLE,
+
+ ZX_USER_SIGNAL_0,
+ ZX_USER_SIGNAL_1,
+ ZX_USER_SIGNAL_2,
+ ZX_USER_SIGNAL_3,
+ ZX_USER_SIGNAL_4,
+ ZX_USER_SIGNAL_5,
+ ZX_USER_SIGNAL_6,
+ ZX_USER_SIGNAL_7,
+
+ // Event
+ ZX_EVENT_SIGNALED,
+
+ // EventPair
+ ZX_EPAIR_SIGNALED,
+ ZX_EPAIR_CLOSED,
+
+ // Task signals (process, thread, job)
+ ZX_TASK_TERMINATED,
+
+ // Channel
+ ZX_CHANNEL_READABLE,
+ ZX_CHANNEL_WRITABLE,
+ ZX_CHANNEL_PEER_CLOSED,
+
+ // Socket
+ ZX_SOCKET_READABLE,
+ ZX_SOCKET_WRITABLE,
+ ZX_SOCKET_PEER_CLOSED,
+
+ // Timer
+ ZX_TIMER_SIGNALED,
+};
+
+/// A "wait item" containing a handle reference and information about what signals
+/// to wait on, and, on return from `object_wait_many`, which are pending.
+#[repr(C)]
+#[derive(Debug)]
+pub struct WaitItem<'a> {
+ /// The handle to wait on.
+ pub handle: HandleRef<'a>,
+ /// A set of signals to wait for.
+ pub waitfor: Signals,
+ /// The set of signals pending, on return of `object_wait_many`.
+ pub pending: Signals,
+}
+
+
+/// An identifier to select a particular clock. See
+/// [zx_time_get](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/time_get.md)
+/// for more information about the possible values.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum ClockId {
+ /// The number of nanoseconds since the system was powered on. Corresponds to
+ /// `ZX_CLOCK_MONOTONIC`.
+ Monotonic = 0,
+ /// The number of wall clock nanoseconds since the Unix epoch (midnight on January 1 1970) in
+ /// UTC. Corresponds to ZX_CLOCK_UTC.
+ UTC = 1,
+ /// The number of nanoseconds the current thread has been running for. Corresponds to
+ /// ZX_CLOCK_THREAD.
+ Thread = 2,
+}
+
+/// Get the current time, from the specific clock id.
+///
+/// Wraps the
+/// [zx_time_get](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/time_get.md)
+/// syscall.
+pub fn time_get(clock_id: ClockId) -> Time {
+ unsafe { sys::zx_time_get(clock_id as u32) }
+}
+
+/// Read the number of high-precision timer ticks since boot. These ticks may be processor cycles,
+/// high speed timer, profiling timer, etc. They are not guaranteed to continue advancing when the
+/// system is asleep.
+///
+/// Wraps the
+/// [zx_ticks_get](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/ticks_get.md)
+/// syscall.
+pub fn ticks_get() -> u64 {
+ unsafe { sys::zx_ticks_get() }
+}
+
+/// Compute a deadline for the time in the future that is the given `Duration` away.
+///
+/// Wraps the
+/// [zx_deadline_after](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/deadline_after.md)
+/// syscall.
+pub fn deadline_after(nanos: Duration) -> Time {
+ unsafe { sys::zx_deadline_after(nanos) }
+}
+
+/// Sleep until the given deadline.
+///
+/// Wraps the
+/// [zx_nanosleep](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/nanosleep.md)
+/// syscall.
+pub fn nanosleep(deadline: Time) {
+ unsafe { sys::zx_nanosleep(deadline); }
+}
+
+/// Return the number of high-precision timer ticks in a second.
+///
+/// Wraps the
+/// [zx_ticks_per_second](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/ticks_per_second.md)
+/// syscall.
+pub fn ticks_per_second() -> u64 {
+ unsafe { sys::zx_ticks_per_second() }
+}
+
+pub use zircon_sys::{
+ ZX_CPRNG_DRAW_MAX_LEN,
+ ZX_CPRNG_ADD_ENTROPY_MAX_LEN,
+};
+
+/// Draw random bytes from the kernel's CPRNG to fill the given buffer. Returns the actual number of
+/// bytes drawn, which may sometimes be less than the size of the buffer provided.
+///
+/// The buffer must have length less than `ZX_CPRNG_DRAW_MAX_LEN`.
+///
+/// Wraps the
+/// [zx_cprng_draw](https://fuchsia.googlesource.com/zircon/+/HEAD/docs/syscalls/cprng_draw.md)
+/// syscall.
+pub fn cprng_draw(buffer: &mut [u8]) -> Result<usize, Status> {
+ let mut actual = 0;
+ let status = unsafe { sys::zx_cprng_draw(buffer.as_mut_ptr(), buffer.len(), &mut actual) };
+ into_result(status, || actual)
+}
+
+/// Mix the given entropy into the kernel CPRNG.
+///
+/// The buffer must have length less than `ZX_CPRNG_ADD_ENTROPY_MAX_LEN`.
+///
+/// Wraps the
+/// [zx_cprng_add_entropy](https://fuchsia.googlesource.com/zircon/+/HEAD/docs/syscalls/cprng_add_entropy.md)
+/// syscall.
+pub fn cprng_add_entropy(buffer: &[u8]) -> Result<(), Status> {
+ let status = unsafe { sys::zx_cprng_add_entropy(buffer.as_ptr(), buffer.len()) };
+ into_result(status, || ())
+}
+
+fn into_result<T, F>(status: sys::zx_status_t, f: F) -> Result<T, Status>
+ where F: FnOnce() -> T {
+ // All non-negative values are assumed successful. Note: calls that don't try
+ // to multiplex success values into status return could be more strict here.
+ if status >= 0 {
+ Ok(f())
+ } else {
+ Err(Status::from_raw(status))
+ }
+}
+
+// Handles
+
+/// A borrowed reference to a `Handle`.
+///
+/// Mostly useful as part of a `WaitItem`.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct HandleRef<'a> {
+ handle: sys::zx_handle_t,
+ phantom: PhantomData<&'a sys::zx_handle_t>,
+}
+
+impl<'a> HandleRef<'a> {
+ pub fn raw_handle(&self) -> sys::zx_handle_t {
+ self.handle
+ }
+
+ pub fn duplicate(&self, rights: Rights) -> Result<Handle, Status> {
+ let handle = self.handle;
+ let mut out = 0;
+ let status = unsafe { sys::zx_handle_duplicate(handle, rights, &mut out) };
+ into_result(status, || Handle(out))
+ }
+
+ pub fn signal(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
+ let handle = self.handle;
+ let status = unsafe { sys::zx_object_signal(handle, clear_mask.bits(), set_mask.bits()) };
+ into_result(status, || ())
+ }
+
+ pub fn wait(&self, signals: Signals, deadline: Time) -> Result<Signals, Status> {
+ let handle = self.handle;
+ let mut pending = sys::zx_signals_t::empty();
+ let status = unsafe {
+ sys::zx_object_wait_one(handle, signals, deadline, &mut pending)
+ };
+ into_result(status, || pending)
+ }
+
+ pub fn wait_async(&self, port: &Port, key: u64, signals: Signals, options: WaitAsyncOpts)
+ -> Result<(), Status>
+ {
+ let handle = self.handle;
+ let status = unsafe {
+ sys::zx_object_wait_async(handle, port.raw_handle(), key, signals, options as u32)
+ };
+ into_result(status, || ())
+ }
+}
+
+/// A trait to get a reference to the underlying handle of an object.
+pub trait AsHandleRef {
+ /// Get a reference to the handle. One important use of such a reference is
+ /// for `object_wait_many`.
+ fn as_handle_ref(&self) -> HandleRef;
+
+ /// Interpret the reference as a raw handle (an integer type). Two distinct
+ /// handles will have different raw values (so it can perhaps be used as a
+ /// key in a data structure).
+ fn raw_handle(&self) -> sys::zx_handle_t {
+ self.as_handle_ref().raw_handle()
+ }
+
+ /// Set and clear userspace-accessible signal bits on an object. Wraps the
+ /// [zx_object_signal](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/object_signal.md)
+ /// syscall.
+ fn signal_handle(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
+ self.as_handle_ref().signal(clear_mask, set_mask)
+ }
+
+ /// Waits on a handle. Wraps the
+ /// [zx_object_wait_one](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/object_wait_one.md)
+ /// syscall.
+ fn wait_handle(&self, signals: Signals, deadline: Time) -> Result<Signals, Status> {
+ self.as_handle_ref().wait(signals, deadline)
+ }
+
+ /// Causes packet delivery on the given port when the object changes state and matches signals.
+ /// [zx_object_wait_async](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/object_wait_async.md)
+ /// syscall.
+ fn wait_async_handle(&self, port: &Port, key: u64, signals: Signals, options: WaitAsyncOpts)
+ -> Result<(), Status>
+ {
+ self.as_handle_ref().wait_async(port, key, signals, options)
+ }
+}
+
+impl<'a> AsHandleRef for HandleRef<'a> {
+ fn as_handle_ref(&self) -> HandleRef { *self }
+}
+
+/// A trait implemented by all handle-based types.
+///
+/// Note: it is reasonable for user-defined objects wrapping a handle to implement
+/// this trait. For example, a specific interface in some protocol might be
+/// represented as a newtype of `Channel`, and implement the `as_handle_ref`
+/// method and the `From<Handle>` trait to facilitate conversion from and to the
+/// interface.
+pub trait HandleBased: AsHandleRef + From<Handle> + Into<Handle> {
+ /// Duplicate a handle, possibly reducing the rights available. Wraps the
+ /// [zx_handle_duplicate](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/handle_duplicate.md)
+ /// syscall.
+ fn duplicate_handle(&self, rights: Rights) -> Result<Self, Status> {
+ self.as_handle_ref().duplicate(rights).map(|handle| Self::from(handle))
+ }
+
+ /// Create a replacement for a handle, possibly reducing the rights available. This invalidates
+ /// the original handle. Wraps the
+ /// [zx_handle_replace](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/handle_replace.md)
+ /// syscall.
+ fn replace_handle(self, rights: Rights) -> Result<Self, Status> {
+ <Self as Into<Handle>>::into(self)
+ .replace(rights).map(|handle| Self::from(handle))
+ }
+
+ /// Converts the value into its inner handle.
+ ///
+ /// This is a convenience function which simply forwards to the `Into` trait.
+ fn into_handle(self) -> Handle {
+ self.into()
+ }
+
+ /// Creates an instance of this type from a handle.
+ ///
+ /// This is a convenience function which simply forwards to the `From` trait.
+ fn from_handle(handle: Handle) -> Self {
+ Self::from(handle)
+ }
+
+ /// Creates an instance of another handle-based type from this value's inner handle.
+ fn into_handle_based<H: HandleBased>(self) -> H {
+ H::from_handle(self.into_handle())
+ }
+
+ /// Creates an instance of this type from the inner handle of another
+ /// handle-based type.
+ fn from_handle_based<H: HandleBased>(h: H) -> Self {
+ Self::from_handle(h.into_handle())
+ }
+}
+
+/// A trait implemented by all handles for objects which have a peer.
+pub trait Peered: HandleBased {
+ /// Set and clear userspace-accessible signal bits on the object's peer. Wraps the
+ /// [zx_object_signal_peer](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/object_signal.md)
+ /// syscall.
+ fn signal_peer(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
+ let handle = self.as_handle_ref().handle;
+ let status = unsafe {
+ sys::zx_object_signal_peer(handle, clear_mask.bits(), set_mask.bits())
+ };
+ into_result(status, || ())
+ }
+}
+
+/// A trait implemented by all handles for objects which can have a cookie attached.
+pub trait Cookied: HandleBased {
+ /// Get the cookie attached to this object, if any. Wraps the
+ /// [zx_object_get_cookie](https://fuchsia.googlesource.com/zircon/+/HEAD/docs/syscalls/object_get_cookie.md)
+ /// syscall.
+ fn get_cookie(&self, scope: &HandleRef) -> Result<u64, Status> {
+ let handle = self.as_handle_ref().handle;
+ let mut cookie = 0;
+ let status = unsafe { sys::zx_object_get_cookie(handle, scope.handle, &mut cookie) };
+ into_result(status, || cookie)
+ }
+
+ /// Attach an opaque cookie to this object with the given scope. The cookie may be read or
+ /// changed in future only with the same scope. Wraps the
+ /// [zx_object_set_cookie](https://fuchsia.googlesource.com/zircon/+/HEAD/docs/syscalls/object_set_cookie.md)
+ /// syscall.
+ fn set_cookie(&self, scope: &HandleRef, cookie: u64) -> Result<(), Status> {
+ let handle = self.as_handle_ref().handle;
+ let status = unsafe { sys::zx_object_set_cookie(handle, scope.handle, cookie) };
+ into_result(status, || ())
+ }
+}
+
+fn handle_drop(handle: sys::zx_handle_t) {
+ let _ = unsafe { sys::zx_handle_close(handle) };
+}
+
+/// Wait on multiple handles.
+/// The success return value is a bool indicating whether one or more of the
+/// provided handle references was closed during the wait.
+///
+/// Wraps the
+/// [zx_object_wait_many](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/object_wait_many.md)
+/// syscall.
+pub fn object_wait_many(items: &mut [WaitItem], deadline: Time) -> Result<bool, Status>
+{
+ let len = try!(usize_into_u32(items.len()).map_err(|_| Status::ErrOutOfRange));
+ let items_ptr = items.as_mut_ptr() as *mut sys::zx_wait_item_t;
+ let status = unsafe { sys::zx_object_wait_many( items_ptr, len, deadline) };
+ if status == sys::ZX_ERR_CANCELED {
+ return Ok((true))
+ }
+ into_result(status, || false)
+}
+
+// An untyped handle
+
+/// An object representing a Zircon
+/// [handle](https://fuchsia.googlesource.com/zircon/+/master/docs/handles.md).
+///
+/// Internally, it is represented as a 32-bit integer, but this wrapper enforces
+/// strict ownership semantics. The `Drop` implementation closes the handle.
+///
+/// This type represents the most general reference to a kernel object, and can
+/// be interconverted to and from more specific types. Those conversions are not
+/// enforced in the type system; attempting to use them will result in errors
+/// returned by the kernel. These conversions don't change the underlying
+/// representation, but do change the type and thus what operations are available.
+#[derive(Debug, Eq, PartialEq, Hash)]
+pub struct Handle(sys::zx_handle_t);
+
+impl AsHandleRef for Handle {
+ fn as_handle_ref(&self) -> HandleRef {
+ HandleRef { handle: self.0, phantom: Default::default() }
+ }
+}
+
+impl HandleBased for Handle {}
+
+impl Drop for Handle {
+ fn drop(&mut self) {
+ handle_drop(self.0)
+ }
+}
+
+impl Handle {
+ /// If a raw handle is obtained from some other source, this method converts
+ /// it into a type-safe owned handle.
+ pub unsafe fn from_raw(raw: sys::zx_handle_t) -> Handle {
+ Handle(raw)
+ }
+
+ pub fn replace(self, rights: Rights) -> Result<Handle, Status> {
+ let handle = self.0;
+ let mut out = 0;
+ let status = unsafe { sys::zx_handle_replace(handle, rights, &mut out) };
+ into_result(status, || Handle(out))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn monotonic_time_increases() {
+ let time1 = time_get(ClockId::Monotonic);
+ nanosleep(deadline_after(1_000));
+ let time2 = time_get(ClockId::Monotonic);
+ assert!(time2 > time1);
+ }
+
+ #[test]
+ fn utc_time_increases() {
+ let time1 = time_get(ClockId::UTC);
+ nanosleep(deadline_after(1_000));
+ let time2 = time_get(ClockId::UTC);
+ assert!(time2 > time1);
+ }
+
+ #[test]
+ fn thread_time_increases() {
+ let time1 = time_get(ClockId::Thread);
+ nanosleep(deadline_after(1_000));
+ let time2 = time_get(ClockId::Thread);
+ assert!(time2 > time1);
+ }
+
+ #[test]
+ fn ticks_increases() {
+ let ticks1 = ticks_get();
+ nanosleep(deadline_after(1_000));
+ let ticks2 = ticks_get();
+ assert!(ticks2 > ticks1);
+ }
+
+ #[test]
+ fn tick_length() {
+ let sleep_ns = 1_000_000; // 1ms
+ let one_second_ns = 1_000_000_000; // 1 second in ns
+ let ticks1 = ticks_get();
+ nanosleep(deadline_after(sleep_ns));
+ let ticks2 = ticks_get();
+ // The number of ticks should have increased by at least 1 ms worth
+ assert!(ticks2 > ticks1 + sleep_ns * ticks_per_second() / one_second_ns);
+ }
+
+ #[test]
+ fn sleep() {
+ let sleep_ns = 1_000_000; // 1ms
+ let time1 = time_get(ClockId::Monotonic);
+ nanosleep(deadline_after(sleep_ns));
+ let time2 = time_get(ClockId::Monotonic);
+ assert!(time2 > time1 + sleep_ns);
+ }
+
+ /// Test duplication by means of a VMO
+ #[test]
+ fn duplicate() {
+ let hello_length: usize = 5;
+
+ // Create a VMO and write some data to it.
+ let vmo = Vmo::create(hello_length as u64, VmoOpts::Default).unwrap();
+ assert!(vmo.write(b"hello", 0).is_ok());
+
+ // Replace, reducing rights to read.
+ let readonly_vmo = vmo.duplicate_handle(ZX_RIGHT_READ).unwrap();
+ // Make sure we can read but not write.
+ let mut read_vec = vec![0; hello_length];
+ assert_eq!(readonly_vmo.read(&mut read_vec, 0).unwrap(), hello_length);
+ assert_eq!(read_vec, b"hello");
+ assert_eq!(readonly_vmo.write(b"", 0), Err(Status::ErrAccessDenied));
+
+ // Write new data to the original handle, and read it from the new handle
+ assert!(vmo.write(b"bye", 0).is_ok());
+ assert_eq!(readonly_vmo.read(&mut read_vec, 0).unwrap(), hello_length);
+ assert_eq!(read_vec, b"byelo");
+ }
+
+ // Test replace by means of a VMO
+ #[test]
+ fn replace() {
+ let hello_length: usize = 5;
+
+ // Create a VMO and write some data to it.
+ let vmo = Vmo::create(hello_length as u64, VmoOpts::Default).unwrap();
+ assert!(vmo.write(b"hello", 0).is_ok());
+
+ // Replace, reducing rights to read.
+ let readonly_vmo = vmo.replace_handle(ZX_RIGHT_READ).unwrap();
+ // Make sure we can read but not write.
+ let mut read_vec = vec![0; hello_length];
+ assert_eq!(readonly_vmo.read(&mut read_vec, 0).unwrap(), hello_length);
+ assert_eq!(read_vec, b"hello");
+ assert_eq!(readonly_vmo.write(b"", 0), Err(Status::ErrAccessDenied));
+ }
+
+ #[test]
+ fn wait_and_signal() {
+ let event = Event::create(EventOpts::Default).unwrap();
+ let ten_ms: Duration = 10_000_000;
+
+ // Waiting on it without setting any signal should time out.
+ assert_eq!(event.wait_handle(
+ ZX_USER_SIGNAL_0, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // If we set a signal, we should be able to wait for it.
+ assert!(event.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ assert_eq!(event.wait_handle(ZX_USER_SIGNAL_0, deadline_after(ten_ms)).unwrap(),
+ ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+
+ // Should still work, signals aren't automatically cleared.
+ assert_eq!(event.wait_handle(ZX_USER_SIGNAL_0, deadline_after(ten_ms)).unwrap(),
+ ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+
+ // Now clear it, and waiting should time out again.
+ assert!(event.signal_handle(ZX_USER_SIGNAL_0, ZX_SIGNAL_NONE).is_ok());
+ assert_eq!(event.wait_handle(
+ ZX_USER_SIGNAL_0, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ }
+
+ #[test]
+ fn wait_many_and_signal() {
+ let ten_ms: Duration = 10_000_000;
+ let e1 = Event::create(EventOpts::Default).unwrap();
+ let e2 = Event::create(EventOpts::Default).unwrap();
+
+ // Waiting on them now should time out.
+ let mut items = vec![
+ WaitItem { handle: e1.as_handle_ref(), waitfor: ZX_USER_SIGNAL_0, pending: ZX_SIGNAL_NONE },
+ WaitItem { handle: e2.as_handle_ref(), waitfor: ZX_USER_SIGNAL_1, pending: ZX_SIGNAL_NONE },
+ ];
+ assert_eq!(object_wait_many(&mut items, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ assert_eq!(items[0].pending, ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(items[1].pending, ZX_SIGNAL_LAST_HANDLE);
+
+ // Signal one object and it should return success.
+ assert!(e1.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ assert!(object_wait_many(&mut items, deadline_after(ten_ms)).is_ok());
+ assert_eq!(items[0].pending, ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(items[1].pending, ZX_SIGNAL_LAST_HANDLE);
+
+ // Signal the other and it should return both.
+ assert!(e2.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_1).is_ok());
+ assert!(object_wait_many(&mut items, deadline_after(ten_ms)).is_ok());
+ assert_eq!(items[0].pending, ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(items[1].pending, ZX_USER_SIGNAL_1 | ZX_SIGNAL_LAST_HANDLE);
+
+ // Clear signals on both; now it should time out again.
+ assert!(e1.signal_handle(ZX_USER_SIGNAL_0, ZX_SIGNAL_NONE).is_ok());
+ assert!(e2.signal_handle(ZX_USER_SIGNAL_1, ZX_SIGNAL_NONE).is_ok());
+ assert_eq!(object_wait_many(&mut items, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ assert_eq!(items[0].pending, ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(items[1].pending, ZX_SIGNAL_LAST_HANDLE);
+ }
+
+ #[test]
+ fn cookies() {
+ let event = Event::create(EventOpts::Default).unwrap();
+ let scope = Event::create(EventOpts::Default).unwrap();
+
+ // Getting a cookie when none has been set should fail.
+ assert_eq!(event.get_cookie(&scope.as_handle_ref()), Err(Status::ErrAccessDenied));
+
+ // Set a cookie.
+ assert_eq!(event.set_cookie(&scope.as_handle_ref(), 42), Ok(()));
+
+ // Should get it back....
+ assert_eq!(event.get_cookie(&scope.as_handle_ref()), Ok(42));
+
+ // but not with the wrong scope!
+ assert_eq!(event.get_cookie(&event.as_handle_ref()), Err(Status::ErrAccessDenied));
+
+ // Can change it, with the same scope...
+ assert_eq!(event.set_cookie(&scope.as_handle_ref(), 123), Ok(()));
+
+ // but not with a different scope.
+ assert_eq!(event.set_cookie(&event.as_handle_ref(), 123), Err(Status::ErrAccessDenied));
+ }
+
+ #[test]
+ fn cprng() {
+ let mut buffer = [0; 20];
+ assert_eq!(cprng_draw(&mut buffer), Ok(20));
+ assert_ne!(buffer[0], 0);
+ assert_ne!(buffer[19], 0);
+ }
+
+ #[test]
+ fn cprng_too_large() {
+ let mut buffer = [0; ZX_CPRNG_DRAW_MAX_LEN + 1];
+ assert_eq!(cprng_draw(&mut buffer), Err(Status::ErrInvalidArgs));
+
+ for mut s in buffer.chunks_mut(ZX_CPRNG_DRAW_MAX_LEN) {
+ assert_eq!(cprng_draw(&mut s), Ok(s.len()));
+ }
+ }
+
+ #[test]
+ fn cprng_add() {
+ let buffer = [0, 1, 2];
+ assert_eq!(cprng_add_entropy(&buffer), Ok(()));
+ }
+}
+
+pub fn usize_into_u32(n: usize) -> Result<u32, ()> {
+ if n > ::std::u32::MAX as usize || n < ::std::u32::MIN as usize {
+ return Err(())
+ }
+ Ok(n as u32)
+}
+
+pub fn size_to_u32_sat(n: usize) -> u32 {
+ if n > ::std::u32::MAX as usize {
+ return ::std::u32::MAX;
+ }
+ if n < ::std::u32::MIN as usize {
+ return ::std::u32::MIN;
+ }
+ n as u32
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/port.rs
@@ -0,0 +1,354 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon port objects.
+
+use std::mem;
+
+use {AsHandleRef, HandleBased, Handle, HandleRef, Signals, Status, Time};
+use {sys, into_result};
+
+/// An object representing a Zircon
+/// [port](https://fuchsia.googlesource.com/zircon/+/master/docs/objects/port.md).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Port(Handle);
+impl_handle_based!(Port);
+
+/// A packet sent through a port. This is a type-safe wrapper for
+/// [zx_port_packet_t](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/port_wait2.md).
+#[derive(PartialEq, Eq, Debug)]
+pub struct Packet(sys::zx_port_packet_t);
+
+/// The contents of a `Packet`.
+#[derive(Debug, Copy, Clone)]
+pub enum PacketContents {
+ /// A user-generated packet.
+ User(UserPacket),
+ /// A one-shot signal packet generated via `object_wait_async`.
+ SignalOne(SignalPacket),
+ /// A repeating signal packet generated via `object_wait_async`.
+ SignalRep(SignalPacket),
+}
+
+/// Contents of a user packet (one sent by `port_queue`). This is a type-safe wrapper for
+/// [zx_packet_user_t](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/port_wait2.md).
+#[derive(Debug, Copy, Clone)]
+pub struct UserPacket(sys::zx_packet_user_t);
+
+/// Contents of a signal packet (one generated by the kernel). This is a type-safe wrapper for
+/// [zx_packet_signal_t](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/port_wait2.md).
+#[derive(Debug, Copy, Clone)]
+pub struct SignalPacket(sys::zx_packet_signal_t);
+
+impl Packet {
+ /// Creates a new packet with `UserPacket` data.
+ pub fn from_user_packet(key: u64, status: i32, user: UserPacket) -> Packet {
+ Packet(
+ sys::zx_port_packet_t {
+ key: key,
+ packet_type: sys::zx_packet_type_t::ZX_PKT_TYPE_USER,
+ status: status,
+ union: user.0,
+ }
+ )
+ }
+
+ /// The packet's key.
+ pub fn key(&self) -> u64 {
+ self.0.key
+ }
+
+ /// The packet's status.
+ // TODO: should this type be wrapped?
+ pub fn status(&self) -> i32 {
+ self.0.status
+ }
+
+ /// The contents of the packet.
+ pub fn contents(&self) -> PacketContents {
+ if self.0.packet_type == sys::zx_packet_type_t::ZX_PKT_TYPE_USER {
+ PacketContents::User(UserPacket(self.0.union))
+ } else if self.0.packet_type == sys::zx_packet_type_t::ZX_PKT_TYPE_SIGNAL_ONE {
+ PacketContents::SignalOne(SignalPacket(unsafe { mem::transmute_copy(&self.0.union) }))
+ } else if self.0.packet_type == sys::zx_packet_type_t::ZX_PKT_TYPE_SIGNAL_REP {
+ PacketContents::SignalRep(SignalPacket(unsafe { mem::transmute_copy(&self.0.union) }))
+ } else {
+ panic!("unexpected packet type");
+ }
+ }
+}
+
+impl UserPacket {
+ pub fn from_u8_array(val: [u8; 32]) -> UserPacket {
+ UserPacket(val)
+ }
+
+ pub fn as_u8_array(&self) -> &[u8; 32] {
+ &self.0
+ }
+
+ pub fn as_mut_u8_array(&mut self) -> &mut [u8; 32] {
+ &mut self.0
+ }
+}
+
+impl SignalPacket {
+ /// The signals used in the call to `object_wait_async`.
+ pub fn trigger(&self) -> Signals {
+ self.0.trigger
+ }
+
+ /// The observed signals.
+ pub fn observed(&self) -> Signals {
+ self.0.observed
+ }
+
+ /// A per object count of pending operations.
+ pub fn count(&self) -> u64 {
+ self.0.count
+ }
+}
+
+impl Port {
+ /// Create an IO port, allowing IO packets to be read and enqueued.
+ ///
+ /// Wraps the
+ /// [zx_port_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/port_create.md)
+ /// syscall.
+ pub fn create(opts: PortOpts) -> Result<Port, Status> {
+ unsafe {
+ let mut handle = 0;
+ let status = sys::zx_port_create(opts as u32, &mut handle);
+ into_result(status, || Self::from(Handle(handle)))
+ }
+ }
+
+ /// Attempt to queue a user packet to the IO port.
+ ///
+ /// Wraps the
+ /// [zx_port_queue](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/port_queue.md)
+ /// syscall.
+ pub fn queue(&self, packet: &Packet) -> Result<(), Status> {
+ let status = unsafe {
+ sys::zx_port_queue(self.raw_handle(),
+ &packet.0 as *const sys::zx_port_packet_t as *const u8, 0)
+ };
+ into_result(status, || ())
+ }
+
+ /// Wait for a packet to arrive on a (V2) port.
+ ///
+ /// Wraps the
+ /// [zx_port_wait](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/port_wait2.md)
+ /// syscall.
+ pub fn wait(&self, deadline: Time) -> Result<Packet, Status> {
+ let mut packet = Default::default();
+ let status = unsafe {
+ sys::zx_port_wait(self.raw_handle(), deadline,
+ &mut packet as *mut sys::zx_port_packet_t as *mut u8, 0)
+ };
+ into_result(status, || Packet(packet))
+ }
+
+ /// Cancel pending wait_async calls for an object with the given key.
+ ///
+ /// Wraps the
+ /// [zx_port_cancel](https://fuchsia.googlesource.com/zircon/+/HEAD/docs/syscalls/port_cancel.md)
+ /// syscall.
+ pub fn cancel<H>(&self, source: &H, key: u64) -> Result<(), Status> where H: HandleBased {
+ let status = unsafe {
+ sys::zx_port_cancel(self.raw_handle(), source.raw_handle(), key)
+ };
+ into_result(status, || ())
+ }
+}
+
+/// Options for creating a port.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum PortOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for PortOpts {
+ fn default() -> Self {
+ PortOpts::Default
+ }
+}
+
+/// Options for wait_async.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum WaitAsyncOpts {
+ Once = sys::ZX_WAIT_ASYNC_ONCE,
+ Repeating = sys::ZX_WAIT_ASYNC_REPEATING,
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use {Duration, Event, EventOpts};
+ use {ZX_SIGNAL_LAST_HANDLE, ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0, ZX_USER_SIGNAL_1};
+ use deadline_after;
+
+ #[test]
+ fn port_basic() {
+ let ten_ms: Duration = 10_000_000;
+
+ let port = Port::create(PortOpts::Default).unwrap();
+
+ // Waiting now should time out.
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // Send a valid packet.
+ let packet = Packet::from_user_packet(
+ 42,
+ 123,
+ UserPacket::from_u8_array([13; 32]),
+ );
+ assert!(port.queue(&packet).is_ok());
+
+ // Waiting should succeed this time. We should get back the packet we sent.
+ let read_packet = port.wait(deadline_after(ten_ms)).unwrap();
+ assert_eq!(read_packet, packet);
+ }
+
+ #[test]
+ fn wait_async_once() {
+ let ten_ms: Duration = 10_000_000;
+ let key = 42;
+
+ let port = Port::create(PortOpts::Default).unwrap();
+ let event = Event::create(EventOpts::Default).unwrap();
+
+ assert!(event.wait_async_handle(&port, key, ZX_USER_SIGNAL_0 | ZX_USER_SIGNAL_1,
+ WaitAsyncOpts::Once).is_ok());
+
+ // Waiting without setting any signal should time out.
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // If we set a signal, we should be able to wait for it.
+ assert!(event.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ let read_packet = port.wait(deadline_after(ten_ms)).unwrap();
+ assert_eq!(read_packet.key(), key);
+ assert_eq!(read_packet.status(), 0);
+ match read_packet.contents() {
+ PacketContents::SignalOne(sig) => {
+ assert_eq!(sig.trigger(), ZX_USER_SIGNAL_0 | ZX_USER_SIGNAL_1);
+ assert_eq!(sig.observed(), ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(sig.count(), 1);
+ }
+ _ => panic!("wrong packet type"),
+ }
+
+ // Shouldn't get any more packets.
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // Calling wait_async again should result in another packet.
+ assert!(event.wait_async_handle(&port, key, ZX_USER_SIGNAL_0, WaitAsyncOpts::Once).is_ok());
+ let read_packet = port.wait(deadline_after(ten_ms)).unwrap();
+ assert_eq!(read_packet.key(), key);
+ assert_eq!(read_packet.status(), 0);
+ match read_packet.contents() {
+ PacketContents::SignalOne(sig) => {
+ assert_eq!(sig.trigger(), ZX_USER_SIGNAL_0);
+ assert_eq!(sig.observed(), ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(sig.count(), 1);
+ }
+ _ => panic!("wrong packet type"),
+ }
+
+ // Calling wait_async_handle then cancel, we should not get a packet as cancel will
+ // remove it from the queue.
+ assert!(event.wait_async_handle(&port, key, ZX_USER_SIGNAL_0, WaitAsyncOpts::Once).is_ok());
+ assert!(port.cancel(&event, key).is_ok());
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // If the event is signalled after the cancel, we also shouldn't get a packet.
+ assert!(event.signal_handle(ZX_USER_SIGNAL_0, ZX_SIGNAL_NONE).is_ok()); // clear signal
+ assert!(event.wait_async_handle(&port, key, ZX_USER_SIGNAL_0, WaitAsyncOpts::Once).is_ok());
+ assert!(port.cancel(&event, key).is_ok());
+ assert!(event.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ }
+
+ #[test]
+ fn wait_async_repeating() {
+ let ten_ms: Duration = 10_000_000;
+ let key = 42;
+
+ let port = Port::create(PortOpts::Default).unwrap();
+ let event = Event::create(EventOpts::Default).unwrap();
+
+ assert!(event.wait_async_handle(&port, key, ZX_USER_SIGNAL_0 | ZX_USER_SIGNAL_1,
+ WaitAsyncOpts::Repeating).is_ok());
+
+ // Waiting without setting any signal should time out.
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // If we set a signal, we should be able to wait for it.
+ assert!(event.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ let read_packet = port.wait(deadline_after(ten_ms)).unwrap();
+ assert_eq!(read_packet.key(), key);
+ assert_eq!(read_packet.status(), 0);
+ match read_packet.contents() {
+ PacketContents::SignalRep(sig) => {
+ assert_eq!(sig.trigger(), ZX_USER_SIGNAL_0 | ZX_USER_SIGNAL_1);
+ assert_eq!(sig.observed(), ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(sig.count(), 1);
+ }
+ _ => panic!("wrong packet type"),
+ }
+
+ // Should not get any more packets, as ZX_WAIT_ASYNC_REPEATING is edge triggered rather than
+ // level triggered.
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // If we clear and resignal, we should get the same packet again,
+ // even though we didn't call event.wait_async again.
+ assert!(event.signal_handle(ZX_USER_SIGNAL_0, ZX_SIGNAL_NONE).is_ok()); // clear signal
+ assert!(event.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ let read_packet = port.wait(deadline_after(ten_ms)).unwrap();
+ assert_eq!(read_packet.key(), key);
+ assert_eq!(read_packet.status(), 0);
+ match read_packet.contents() {
+ PacketContents::SignalRep(sig) => {
+ assert_eq!(sig.trigger(), ZX_USER_SIGNAL_0 | ZX_USER_SIGNAL_1);
+ assert_eq!(sig.observed(), ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(sig.count(), 1);
+ }
+ _ => panic!("wrong packet type"),
+ }
+
+ // Cancelling the wait should stop us getting packets...
+ assert!(port.cancel(&event, key).is_ok());
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ // ... even if we clear and resignal
+ assert!(event.signal_handle(ZX_USER_SIGNAL_0, ZX_SIGNAL_NONE).is_ok()); // clear signal
+ assert!(event.signal_handle(ZX_SIGNAL_NONE, ZX_USER_SIGNAL_0).is_ok());
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // Calling wait_async again should result in another packet.
+ assert!(event.wait_async_handle(
+ &port, key, ZX_USER_SIGNAL_0, WaitAsyncOpts::Repeating).is_ok());
+ let read_packet = port.wait(deadline_after(ten_ms)).unwrap();
+ assert_eq!(read_packet.key(), key);
+ assert_eq!(read_packet.status(), 0);
+ match read_packet.contents() {
+ PacketContents::SignalRep(sig) => {
+ assert_eq!(sig.trigger(), ZX_USER_SIGNAL_0);
+ assert_eq!(sig.observed(), ZX_USER_SIGNAL_0 | ZX_SIGNAL_LAST_HANDLE);
+ assert_eq!(sig.count(), 1);
+ }
+ _ => panic!("wrong packet type"),
+ }
+
+ // Closing the handle should stop us getting packets.
+ drop(event);
+ assert_eq!(port.wait(deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/process.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon process.
+
+use {AsHandleRef, HandleBased, Handle, HandleRef};
+
+/// An object representing a Zircon process.
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Process(Handle);
+impl_handle_based!(Process);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/socket.rs
@@ -0,0 +1,162 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon sockets.
+
+use {AsHandleRef, HandleBased, Handle, HandleRef, Peered};
+use {sys, Status, into_result};
+
+use std::ptr;
+
+/// An object representing a Zircon
+/// [socket](https://fuchsia.googlesource.com/zircon/+/master/docs/concepts.md#Message-Passing_Sockets-and-Channels).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Socket(Handle);
+impl_handle_based!(Socket);
+impl Peered for Socket {}
+
+/// Options for creating a socket pair.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum SocketOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for SocketOpts {
+ fn default() -> Self {
+ SocketOpts::Default
+ }
+}
+
+/// Options for writing into a socket.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum SocketWriteOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for SocketWriteOpts {
+ fn default() -> Self {
+ SocketWriteOpts::Default
+ }
+}
+
+/// Options for reading from a socket.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum SocketReadOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for SocketReadOpts {
+ fn default() -> Self {
+ SocketReadOpts::Default
+ }
+}
+
+
+impl Socket {
+ /// Create a socket, accessed through a pair of endpoints. Data written
+ /// into one may be read from the other.
+ ///
+ /// Wraps
+ /// [zx_socket_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/socket_create.md).
+ pub fn create(opts: SocketOpts) -> Result<(Socket, Socket), Status> {
+ unsafe {
+ let mut out0 = 0;
+ let mut out1 = 0;
+ let status = sys::zx_socket_create(opts as u32, &mut out0, &mut out1);
+ into_result(status, ||
+ (Self::from(Handle(out0)),
+ Self::from(Handle(out1))))
+ }
+ }
+
+ /// Write the given bytes into the socket.
+ /// Return value (on success) is number of bytes actually written.
+ ///
+ /// Wraps
+ /// [zx_socket_write](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/socket_write.md).
+ pub fn write(&self, opts: SocketWriteOpts, bytes: &[u8]) -> Result<usize, Status> {
+ let mut actual = 0;
+ let status = unsafe {
+ sys::zx_socket_write(self.raw_handle(), opts as u32, bytes.as_ptr(), bytes.len(),
+ &mut actual)
+ };
+ into_result(status, || actual)
+ }
+
+ /// Read the given bytes from the socket.
+ /// Return value (on success) is number of bytes actually read.
+ ///
+ /// Wraps
+ /// [zx_socket_read](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/socket_read.md).
+ pub fn read(&self, opts: SocketReadOpts, bytes: &mut [u8]) -> Result<usize, Status> {
+ let mut actual = 0;
+ let status = unsafe {
+ sys::zx_socket_read(self.raw_handle(), opts as u32, bytes.as_mut_ptr(),
+ bytes.len(), &mut actual)
+ };
+ if status != sys::ZX_OK {
+ // If an error is returned then actual is undefined, so to be safe we set it to 0 and
+ // ignore any data that is set in bytes.
+ actual = 0;
+ }
+ into_result(status, || actual)
+ }
+
+ /// Close half of the socket, so attempts by the other side to write will fail.
+ ///
+ /// Implements the `ZX_SOCKET_HALF_CLOSE` option of
+ /// [zx_socket_write](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/socket_write.md).
+ pub fn half_close(&self) -> Result<(), Status> {
+ let status = unsafe { sys::zx_socket_write(self.raw_handle(), sys::ZX_SOCKET_HALF_CLOSE,
+ ptr::null(), 0, ptr::null_mut()) };
+ into_result(status, || ())
+ }
+
+ pub fn outstanding_read_bytes(&self) -> Result<usize, Status> {
+ let mut outstanding = 0;
+ let status = unsafe {
+ sys::zx_socket_read(self.raw_handle(), 0, ptr::null_mut(), 0, &mut outstanding)
+ };
+ into_result(status, || outstanding)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn socket_basic() {
+ let (s1, s2) = Socket::create(SocketOpts::Default).unwrap();
+
+ // Write in one end and read it back out the other.
+ assert_eq!(s1.write(SocketWriteOpts::Default, b"hello").unwrap(), 5);
+
+ let mut read_vec = vec![0; 8];
+ assert_eq!(s2.read(SocketReadOpts::Default, &mut read_vec).unwrap(), 5);
+ assert_eq!(&read_vec[0..5], b"hello");
+
+ // Try reading when there is nothing to read.
+ assert_eq!(s2.read(SocketReadOpts::Default, &mut read_vec), Err(Status::ErrShouldWait));
+
+ // Close the socket from one end.
+ assert!(s1.half_close().is_ok());
+ assert_eq!(s2.read(SocketReadOpts::Default, &mut read_vec), Err(Status::ErrBadState));
+ assert_eq!(s1.write(SocketWriteOpts::Default, b"fail"), Err(Status::ErrBadState));
+
+ // Writing in the other direction should still work.
+ assert_eq!(s1.read(SocketReadOpts::Default, &mut read_vec), Err(Status::ErrShouldWait));
+ assert_eq!(s2.write(SocketWriteOpts::Default, b"back").unwrap(), 4);
+ assert_eq!(s1.read(SocketReadOpts::Default, &mut read_vec).unwrap(), 4);
+ assert_eq!(&read_vec[0..4], b"back");
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/thread.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon thread.
+
+use {AsHandleRef, HandleBased, Handle, HandleRef};
+
+/// An object representing a Zircon thread.
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Thread(Handle);
+impl_handle_based!(Thread);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/timer.rs
@@ -0,0 +1,92 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon timer objects.
+
+use {AsHandleRef, ClockId, Duration, HandleBased, Handle, HandleRef, Status, Time};
+use {sys, into_result};
+
+/// An object representing a Zircon
+/// [event pair](https://fuchsia.googlesource.com/zircon/+/master/docs/concepts.md#Other-IPC_Events_Event-Pairs_and-User-Signals).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Timer(Handle);
+impl_handle_based!(Timer);
+
+impl Timer {
+ /// Create a timer, an object that can signal when a specified point in time has been reached.
+ /// Wraps the
+ /// [zx_timer_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/timer_create.md)
+ /// syscall.
+ pub fn create(options: TimerOpts, clock_id: ClockId) -> Result<Timer, Status> {
+ let mut out = 0;
+ let status = unsafe { sys::zx_timer_create(options as u32, clock_id as u32, &mut out) };
+ into_result(status, || Self::from(Handle(out)))
+ }
+
+ /// Start a one-shot timer that will fire when `deadline` passes. Wraps the
+ /// [zx_timer_set](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/timer_set.md)
+ /// syscall.
+ pub fn set(&self, deadline: Time, slack: Duration) -> Result<(), Status> {
+ let status = unsafe { sys::zx_timer_set(self.raw_handle(), deadline, slack) };
+ into_result(status, || ())
+ }
+
+ /// Cancels a pending timer that was started with start(). Wraps the
+ /// [zx_timer_cancel](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/timer_cancel.md)
+ /// syscall.
+ pub fn cancel(&self) -> Result<(), Status> {
+ let status = unsafe { sys::zx_timer_cancel(self.raw_handle()) };
+ into_result(status, || ())
+ }
+}
+
+/// Options for creating a timer.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum TimerOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for TimerOpts {
+ fn default() -> Self {
+ TimerOpts::Default
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use {Duration, ZX_SIGNAL_LAST_HANDLE, ZX_TIMER_SIGNALED};
+ use deadline_after;
+
+ #[test]
+ fn create_timer_invalid_clock() {
+ assert_eq!(Timer::create(TimerOpts::Default, ClockId::UTC).unwrap_err(), Status::ErrInvalidArgs);
+ assert_eq!(Timer::create(TimerOpts::Default, ClockId::Thread), Err(Status::ErrInvalidArgs));
+ }
+
+ #[test]
+ fn timer_basic() {
+ let ten_ms: Duration = 10_000_000;
+ let twenty_ms: Duration = 20_000_000;
+
+ // Create a timer
+ let timer = Timer::create(TimerOpts::Default, ClockId::Monotonic).unwrap();
+
+ // Should not signal yet.
+ assert_eq!(timer.wait_handle(ZX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+
+ // Set it, and soon it should signal.
+ assert_eq!(timer.set(ten_ms, 0), Ok(()));
+ assert_eq!(timer.wait_handle(ZX_TIMER_SIGNALED, deadline_after(twenty_ms)).unwrap(),
+ ZX_TIMER_SIGNALED | ZX_SIGNAL_LAST_HANDLE);
+
+ // Cancel it, and it should stop signalling.
+ assert_eq!(timer.cancel(), Ok(()));
+ assert_eq!(timer.wait_handle(ZX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/vmo.rs
@@ -0,0 +1,273 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon vmo objects.
+
+use {AsHandleRef, Cookied, HandleBased, Handle, HandleRef, Status};
+use {sys, into_result};
+use std::{mem, ptr};
+
+/// An object representing a Zircon
+/// [virtual memory object](https://fuchsia.googlesource.com/zircon/+/master/docs/objects/vm_object.md).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Vmo(Handle);
+impl_handle_based!(Vmo);
+impl Cookied for Vmo {}
+
+impl Vmo {
+ /// Create a virtual memory object.
+ ///
+ /// Wraps the
+ /// `zx_vmo_create`
+ /// syscall. See the
+ /// [Shared Memory: Virtual Memory Objects (VMOs)](https://fuchsia.googlesource.com/zircon/+/master/docs/concepts.md#Shared-Memory_Virtual-Memory-Objects-VMOs)
+ /// for more information.
+ pub fn create(size: u64, options: VmoOpts) -> Result<Vmo, Status> {
+ let mut handle = 0;
+ let status = unsafe { sys::zx_vmo_create(size, options as u32, &mut handle) };
+ into_result(status, ||
+ Vmo::from(Handle(handle)))
+ }
+
+ /// Read from a virtual memory object.
+ ///
+ /// Wraps the `zx_vmo_read` syscall.
+ pub fn read(&self, data: &mut [u8], offset: u64) -> Result<usize, Status> {
+ unsafe {
+ let mut actual = 0;
+ let status = sys::zx_vmo_read(self.raw_handle(), data.as_mut_ptr(),
+ offset, data.len(), &mut actual);
+ into_result(status, || actual)
+ }
+ }
+
+ /// Write to a virtual memory object.
+ ///
+ /// Wraps the `zx_vmo_write` syscall.
+ pub fn write(&self, data: &[u8], offset: u64) -> Result<usize, Status> {
+ unsafe {
+ let mut actual = 0;
+ let status = sys::zx_vmo_write(self.raw_handle(), data.as_ptr(),
+ offset, data.len(), &mut actual);
+ into_result(status, || actual)
+ }
+ }
+
+ /// Get the size of a virtual memory object.
+ ///
+ /// Wraps the `zx_vmo_get_size` syscall.
+ pub fn get_size(&self) -> Result<u64, Status> {
+ let mut size = 0;
+ let status = unsafe { sys::zx_vmo_get_size(self.raw_handle(), &mut size) };
+ into_result(status, || size)
+ }
+
+ /// Attempt to change the size of a virtual memory object.
+ ///
+ /// Wraps the `zx_vmo_set_size` syscall.
+ pub fn set_size(&self, size: u64) -> Result<(), Status> {
+ let status = unsafe { sys::zx_vmo_set_size(self.raw_handle(), size) };
+ into_result(status, || ())
+ }
+
+ /// Perform an operation on a range of a virtual memory object.
+ ///
+ /// Wraps the
+ /// [zx_vmo_op_range](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/vmo_op_range.md)
+ /// syscall.
+ pub fn op_range(&self, op: VmoOp, offset: u64, size: u64) -> Result<(), Status> {
+ let status = unsafe {
+ sys::zx_vmo_op_range(self.raw_handle(), op as u32, offset, size, ptr::null_mut(), 0)
+ };
+ into_result(status, || ())
+ }
+
+ /// Look up a list of physical addresses corresponding to the pages held by the VMO from
+ /// `offset` to `offset`+`size`, and store them in `buffer`.
+ ///
+ /// Wraps the
+ /// [zx_vmo_op_range](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/vmo_op_range.md)
+ /// syscall with ZX_VMO_OP_LOOKUP.
+ pub fn lookup(&self, offset: u64, size: u64, buffer: &mut [sys::zx_paddr_t])
+ -> Result<(), Status>
+ {
+ let status = unsafe {
+ sys::zx_vmo_op_range(self.raw_handle(), sys::ZX_VMO_OP_LOOKUP, offset, size,
+ buffer.as_mut_ptr() as *mut u8, buffer.len() * mem::size_of::<sys::zx_paddr_t>())
+ };
+ into_result(status, || ())
+ }
+
+ /// Create a new virtual memory object that clones a range of this one.
+ ///
+ /// Wraps the
+ /// [zx_vmo_clone](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/vmo_clone.md)
+ /// syscall.
+ pub fn clone(&self, options: VmoCloneOpts, offset: u64, size: u64) -> Result<Vmo, Status> {
+ let mut out = 0;
+ let status = unsafe {
+ sys::zx_vmo_clone(self.raw_handle(), options as u32, offset, size, &mut out)
+ };
+ into_result(status, || Vmo::from(Handle(out)))
+ }
+}
+
+/// Options for creating virtual memory objects. None supported yet.
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum VmoOpts {
+ /// Default options.
+ Default = 0,
+}
+
+impl Default for VmoOpts {
+ fn default() -> Self {
+ VmoOpts::Default
+ }
+}
+
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum VmoOp {
+ /// Commit `size` bytes worth of pages starting at byte `offset` for the VMO.
+ Commit = sys::ZX_VMO_OP_COMMIT,
+ /// Release a range of pages previously committed to the VMO from `offset` to `offset`+`size`.
+ Decommit = sys::ZX_VMO_OP_DECOMMIT,
+ // Presently unsupported.
+ Lock = sys::ZX_VMO_OP_LOCK,
+ // Presently unsupported.
+ Unlock = sys::ZX_VMO_OP_UNLOCK,
+ /// Perform a cache sync operation.
+ CacheSync = sys::ZX_VMO_OP_CACHE_SYNC,
+ /// Perform a cache invalidation operation.
+ CacheInvalidate = sys::ZX_VMO_OP_CACHE_INVALIDATE,
+ /// Perform a cache clean operation.
+ CacheClean = sys::ZX_VMO_OP_CACHE_CLEAN,
+ /// Perform cache clean and invalidation operations together.
+ CacheCleanInvalidate = sys::ZX_VMO_OP_CACHE_CLEAN_INVALIDATE,
+}
+
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum VmoCloneOpts {
+ /// Create a copy-on-write clone.
+ CopyOnWrite = sys::ZX_VMO_CLONE_COPY_ON_WRITE,
+}
+
+impl Default for VmoCloneOpts {
+ fn default() -> Self {
+ VmoCloneOpts::CopyOnWrite
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn vmo_get_size() {
+ let size = 16 * 1024 * 1024;
+ let vmo = Vmo::create(size, VmoOpts::Default).unwrap();
+ assert_eq!(size, vmo.get_size().unwrap());
+ }
+
+ #[test]
+ fn vmo_set_size() {
+ let start_size = 12;
+ let vmo = Vmo::create(start_size, VmoOpts::Default).unwrap();
+ assert_eq!(start_size, vmo.get_size().unwrap());
+
+ // Change the size and make sure the new size is reported
+ let new_size = 23;
+ assert!(vmo.set_size(new_size).is_ok());
+ assert_eq!(new_size, vmo.get_size().unwrap());
+ }
+
+ #[test]
+ fn vmo_read_write() {
+ let mut vec1 = vec![0; 16];
+ let vmo = Vmo::create(vec1.len() as u64, VmoOpts::Default).unwrap();
+ assert_eq!(vmo.write(b"abcdef", 0), Ok(6));
+ assert_eq!(16, vmo.read(&mut vec1, 0).unwrap());
+ assert_eq!(b"abcdef", &vec1[0..6]);
+ assert_eq!(vmo.write(b"123", 2), Ok(3));
+ assert_eq!(16, vmo.read(&mut vec1, 0).unwrap());
+ assert_eq!(b"ab123f", &vec1[0..6]);
+ assert_eq!(15, vmo.read(&mut vec1, 1).unwrap());
+ assert_eq!(b"b123f", &vec1[0..5]);
+ }
+
+ #[test]
+ fn vmo_op_range_unsupported() {
+ let vmo = Vmo::create(12, VmoOpts::Default).unwrap();
+ assert_eq!(vmo.op_range(VmoOp::Lock, 0, 1), Err(Status::ErrNotSupported));
+ assert_eq!(vmo.op_range(VmoOp::Unlock, 0, 1), Err(Status::ErrNotSupported));
+ }
+
+ #[test]
+ fn vmo_lookup() {
+ let vmo = Vmo::create(12, VmoOpts::Default).unwrap();
+ let mut buffer = vec![0; 2];
+
+ // Lookup will fail as it is not committed yet.
+ assert_eq!(vmo.lookup(0, 12, &mut buffer), Err(Status::ErrNoMemory));
+
+ // Commit and try again.
+ assert_eq!(vmo.op_range(VmoOp::Commit, 0, 12), Ok(()));
+ assert_eq!(vmo.lookup(0, 12, &mut buffer), Ok(()));
+ assert_ne!(buffer[0], 0);
+ assert_eq!(buffer[1], 0);
+
+ // If we decommit then lookup should go back to failing.
+ assert_eq!(vmo.op_range(VmoOp::Decommit, 0, 12), Ok(()));
+ assert_eq!(vmo.lookup(0, 12, &mut buffer), Err(Status::ErrNoMemory));
+ }
+
+ #[test]
+ fn vmo_cache() {
+ let vmo = Vmo::create(12, VmoOpts::Default).unwrap();
+
+ // Cache operations should all succeed.
+ assert_eq!(vmo.op_range(VmoOp::CacheSync, 0, 12), Ok(()));
+ assert_eq!(vmo.op_range(VmoOp::CacheInvalidate, 0, 12), Ok(()));
+ assert_eq!(vmo.op_range(VmoOp::CacheClean, 0, 12), Ok(()));
+ assert_eq!(vmo.op_range(VmoOp::CacheCleanInvalidate, 0, 12), Ok(()));
+ }
+
+ #[test]
+ fn vmo_clone() {
+ let original = Vmo::create(12, VmoOpts::Default).unwrap();
+ assert_eq!(original.write(b"one", 0), Ok(3));
+
+ // Clone the VMO, and make sure it contains what we expect.
+ let clone = original.clone(VmoCloneOpts::CopyOnWrite, 0, 10).unwrap();
+ let mut read_buffer = vec![0; 16];
+ assert_eq!(clone.read(&mut read_buffer, 0), Ok(10));
+ assert_eq!(&read_buffer[0..3], b"one");
+
+ // Writing to the original will affect the clone too, surprisingly.
+ assert_eq!(original.write(b"two", 0), Ok(3));
+ assert_eq!(original.read(&mut read_buffer, 0), Ok(12));
+ assert_eq!(&read_buffer[0..3], b"two");
+ assert_eq!(clone.read(&mut read_buffer, 0), Ok(10));
+ assert_eq!(&read_buffer[0..3], b"two");
+
+ // However, writing to the clone will not affect the original
+ assert_eq!(clone.write(b"three", 0), Ok(5));
+ assert_eq!(original.read(&mut read_buffer, 0), Ok(12));
+ assert_eq!(&read_buffer[0..3], b"two");
+ assert_eq!(clone.read(&mut read_buffer, 0), Ok(10));
+ assert_eq!(&read_buffer[0..5], b"three");
+
+ // And now that the copy-on-write has happened, writing to the original will not affect the
+ // clone. How bizarre.
+ assert_eq!(original.write(b"four", 0), Ok(4));
+ assert_eq!(original.read(&mut read_buffer, 0), Ok(12));
+ assert_eq!(&read_buffer[0..4], b"four");
+ assert_eq!(clone.read(&mut read_buffer, 0), Ok(10));
+ assert_eq!(&read_buffer[0..5], b"three");
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/tools/BUILD.gn
@@ -0,0 +1,51 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+group("clang_wrapper") {
+ deps = [
+ ":arm64_wrapper",
+ ":x64_wrapper",
+ ]
+}
+
+executable("clang_wrapper_bin") {
+ output_name = "rust_clang_wrapper"
+
+ sources = [
+ "clang_wrapper.cc",
+ ]
+
+ if (is_linux) {
+ ldflags = [
+ "-pthread",
+ ]
+ }
+}
+
+template("copy_wrapper") {
+
+ arch = invoker.arch
+
+ copy(target_name) {
+ sources = [
+ "$root_out_dir/rust_clang_wrapper",
+ ]
+
+ outputs = [
+ "$root_out_dir/$arch-unknown-fuchsia-cc",
+ ]
+
+ deps = [
+ ":clang_wrapper_bin",
+ ]
+ }
+}
+
+copy_wrapper("arm64_wrapper") {
+ arch = "aarch64"
+}
+
+copy_wrapper("x64_wrapper") {
+ arch = "x86_64"
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/tools/README.md
@@ -0,0 +1,26 @@
+Build tools for Rust on Fuchsia
+===============================
+
+This directory contains a wrapper so that clang can be invoked using a
+target-specific command line (as is typically done using Gnu tools for
+cross-compiling).
+
+To compile standalone (not part of a build system):
+
+```
+clang++ -O --std=c++11 clang_wrapper.cc -o clang_wrapper
+ln -s clang_wrapper x86-64-unknown-fuchsia-ar
+ln -s clang_wrapper x86-64-unknown-fuchsia-cc
+ln -s clang_wrapper aarch64-unknown-fuchsia-ar
+ln -s clang_wrapper aarch64-unknown-fuchsia-cc
+```
+
+The resulting binaries (`x86-64-unknown-fuchsia-cc` and the like) must be
+placed somewhere under the root of the fuchsia tree.
+
+The wrapper sets the target triple appropriately, and also finds the
+appropriate sysroot for the given target (necessary for linking).
+
+Note: this wrapper is provisional, hopefully to be supplanted by a more
+general config mechanism in LLVM
+(see [relevant LLVM patch](https://reviews.llvm.org/D24933)).
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/tools/clang_wrapper.cc
@@ -0,0 +1,205 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Wrap the clang toolchain to supply triple-specific configuration parameters
+// as arguments.
+
+// Gnu-style toolchains encode the target triple in the executable name (each
+// executable is specialized to a single triple), and each toolchain also knows
+// how to find the corresponding sysroot. By contrast, clang uses a single
+// binary, and the target is specified as a command line argument. In addition,
+// in the Fuchsia world, the sysroot is not bundled with the compiler.
+//
+// This wrapper infers the relevant configuration parameters from the command
+// name used to invoke the wrapper, and also finds the sysroot at a known
+// location relative to the jiri root, then invokes clang with the additional
+// arguments.
+
+#include <map>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <string.h>
+#include <algorithm>
+
+using std::map;
+using std::string;
+using std::vector;
+
+// Get the real path of this executable, resolving symbolic links.
+string GetPath(const char* argv0) {
+ char* path_c = realpath(argv0, nullptr);
+ string path = string(path_c);
+ free(path_c);
+ return path;
+}
+
+// Return path of Jiri root, or empty string if not found.
+string FindJiriRoot(const string& self_path) {
+ string path = self_path;
+ while (true) {
+ size_t pos = path.rfind('/');
+ if (pos == string::npos) {
+ return "";
+ }
+ string basedir = path.substr(0, pos + 1);
+ string trial = basedir + ".jiri_root";
+ struct stat stat_buf;
+ int status = stat(trial.c_str(), &stat_buf);
+ if (status == 0) {
+ return basedir;
+ }
+ path = path.substr(0, pos);
+ }
+}
+
+// Get the basename of the command used to invoke this wrapper.
+// Typical return value: "x86-64-unknown-fuchsia-cc"
+string GetCmd(const char* argv0) {
+ string cmd = argv0;
+ size_t pos = cmd.rfind('/');
+ if (pos != string::npos) {
+ cmd = cmd.substr(pos + 1);
+ }
+ return cmd;
+}
+
+// Given the command basename, get the llvm target triple. Empty string on failure.
+// Typical return value: "x86_64-unknown-fuchsia"
+string TargetTriple(const string& cmd) {
+ size_t pos = cmd.rfind('-');
+ if (pos == string::npos) {
+ return "";
+ }
+ string triple = cmd.substr(0, pos);
+ if (triple.find("x86-64") == 0) {
+ triple[3] = '_';
+ }
+ return triple;
+}
+
+// Given the path to the command, calculate the matching sysroot
+string SysrootPath(const string& triple, const string& self_path) {
+ const string out_dir_name = "out/";
+ size_t pos = self_path.find(out_dir_name);
+ if (pos != string::npos) {
+ string out_path = self_path.substr(0, pos + out_dir_name.length());
+ string zircon_name = triple == "x86_64-unknown-fuchsia" ?
+ "build-zircon-pc-x86-64" : "build-zircon-qemu-arm64";
+ string sysroot_path = out_path + "build-zircon/" + zircon_name + "/sysroot";
+ struct stat stat_buf;
+ int status = stat(sysroot_path.c_str(), &stat_buf);
+ if (status == 0) {
+ return sysroot_path;
+ }
+ }
+ return "";
+}
+
+// Detect the host, get the host identifier (used to select a prebuilt toolchain).
+// Empty string on failure.
+// Typical return value: "mac-x64"
+string HostDouble() {
+ struct utsname name;
+ int status = uname(&name);
+ if (status != 0) {
+ return "";
+ }
+ map<string, string> cpumap = {
+ {"aarch64", "arm64"},
+ {"x86_64", "x64"}
+ };
+ map<string, string> osmap = {
+ {"Linux", "linux"},
+ {"Darwin", "mac"}
+ };
+ return osmap[name.sysname] + "-" + cpumap[name.machine];
+}
+
+// Given the command baseline, get the llvm binary to invoke.
+// Note: the "llvm-ar" special case should probably go away, as Rust no longer
+// invokes an external "ar" tool, and the llvm-ar one probably wouldn't work.
+// Typical return value: "clang"
+string InferTool(const string& cmd) {
+ size_t pos = cmd.rfind('-');
+ string base;
+ if (pos != string::npos) {
+ base = cmd.substr(pos + 1);
+ } else {
+ base = cmd;
+ }
+ if (base == "cc" || base == "gcc") {
+ return "clang";
+ } else if (base == "ar") {
+ return "llvm-ar";
+ }
+ return base;
+}
+
+// Collect C-style argc/argv into a vector of strings.
+vector<string> CollectArgs(int argc, char** argv) {
+ vector<string> result;
+ for (int i = 0; i < argc; i++) {
+ result.push_back(argv[i]);
+ }
+ return result;
+}
+
+// Do "execv" given command path as a string and args as a vector of strings.
+int DoExecv(const string& cmd, vector<string>& args) {
+ vector<const char*> argvec;
+ for (auto& it : args) {
+ argvec.push_back(it.c_str());
+ }
+ argvec.push_back(nullptr);
+ char* const* argv = const_cast<char* const*>(argvec.data());
+ return execv(cmd.c_str(), argv);
+}
+
+void Die(const string& message) {
+ std::cerr << message << std::endl;
+ exit(1);
+}
+
+int main(int argc, char** argv) {
+ string self_path = GetPath(argv[0]);
+ string root = FindJiriRoot(self_path);
+ if (root.empty()) {
+ Die("Can't find .jiri_root in any parent of " + self_path);
+ }
+ string host = HostDouble();
+ if (host.empty()) {
+ Die("Can't detect host (uname failed)");
+ }
+ string cmd = GetCmd(argv[0]);
+ string tool = InferTool(cmd);
+ string triple = TargetTriple(cmd);
+ vector<string> args = CollectArgs(argc, argv);
+
+ string newcmd = root + "buildtools/" + host + "/clang/bin/" + tool;
+ string sysroot = SysrootPath(triple, self_path);
+ if (sysroot.empty()) {
+ Die("Can't find sysroot from wrapper path");
+ }
+ vector<string> newargs;
+ newargs.push_back(newcmd);
+ if (tool != "llvm-ar") {
+ newargs.push_back("-target");
+ newargs.push_back(triple);
+ newargs.push_back("--sysroot=" + sysroot);
+ }
+ for (auto it = args.begin() + 1; it != args.end(); ++it) {
+ newargs.push_back(*it);
+ }
+ int status = DoExecv(newcmd, newargs);
+ if (status != 0) {
+ Die("error invoking " + newcmd + ": " + strerror(errno));
+ }
+ return 0;
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/tools/gen_status.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+# Copyright 2016 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# A tool for autogenerating the mapping between Status and zx_status_t
+# Usage: python gen_status.py zircon/system/public/zircon/errors.h {sys,enum,match}
+import re
+import sys
+
+status_re = re.compile('#define\s+(ZX_\w+)\s+\((\-?\d+)\)$')
+
+def parse(in_filename):
+ result = []
+ for line in file(in_filename):
+ m = status_re.match(line)
+ if m:
+ result.append((m.group(1), int(m.group(2))))
+ return result
+
+def to_snake_case(name):
+ result = []
+ for element in name.split('_'):
+ result.append(element[0] + element[1:].lower())
+ return ''.join(result)
+
+def out(style, l):
+ print('// Auto-generated using tools/gen_status.py')
+ longest = max(len(name) for (name, num) in l)
+ if style == 'sys':
+ for (name, num) in l:
+ print('pub const %s : zx_status_t = %d;' % (name.ljust(longest), num))
+ if style == 'enum':
+ print('pub enum Status {')
+ for (name, num) in l:
+ print(' %s = %d,' % (to_snake_case(name[3:]), num))
+ print('');
+ print(' /// Any zx_status_t not in the set above will map to the following:')
+ print(' UnknownOther = -32768,')
+ print('}')
+ if style == 'match':
+ for (name, num) in l:
+ print(' sys::%s => Status::%s,' % (name, to_snake_case(name[3:])))
+ print(' _ => Status::UnknownOther,')
+
+
+l = parse(sys.argv[1])
+out(sys.argv[2], l)
--- a/third_party/rust/rand/.cargo-checksum.json
+++ b/third_party/rust/rand/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"977ae778ea9d60b5abec3674cec33720b9db33c1e3da255ccaa58ad6a70b4c7f","Cargo.toml":"f000bcadb1b0f90fea9defd4d650a5d7bb3f15fb2705be5e96788fa59eedf6cc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"969ef4c906eb704377d99bb69125f3aa3c523daa5b410d426ac5dcdd107b008d","appveyor.yml":"3a74394c3e3ef3b2c7d9458f526e47587977e98d026b63f00be29479075ff597","benches/bench.rs":"e6adfb15146d3176164a345a6d978071cb71aa3f9761000702e798cb53fde2b5","benches/distributions/exponential.rs":"99cb59c013a0b6bb390d34c5649b341fc3b88ea7df0caf2470bdda8798f9fe3d","benches/distributions/gamma.rs":"3533f311e4b55d743c5b01a7eb6529c94fd97726ef6702a6372f914f5f33666b","benches/distributions/mod.rs":"0028f1cb96f61152ed5b49a4fe91227d809ef6d19035592c36032a538af7f95e","benches/distributions/normal.rs":"4e10c18cb583ccb96301ea953c8e0aa9ee3b6662060271d1b8d19ca23364dc6b","src/chacha.rs":"ed43d7966192f265a22fe6913b799e081703b42c1ba7b1214128f42b70aaab3a","src/distributions/exponential.rs":"a63bfb1ec564408697ab587da3bd85417983405b2af4fd14a185e6f21cfe2723","src/distributions/gamma.rs":"26edf7055f31c12d31fc89d2da9357723693c1358cd343089df2cf6f58355d5c","src/distributions/mod.rs":"696f4f2edd0d1a26916fbe6ab330971d810d60bbcb2c06cf6f179a5c27038bbd","src/distributions/normal.rs":"414806b102d77707c9a4e03df65e059f487c463a85db80c33ef8f5ef7c40ca8c","src/distributions/range.rs":"9fac31b9d8dfc258be725a83c60f97e71efbbca725830e053d8f53c508b3e288","src/distributions/ziggurat_tables.rs":"4eacf94fc352c91c455a6623de6a721e53842e1690f13a5662b6a79c7fbb73de","src/isaac.rs":"8426fa913a163c13c1c81d166204c9748f79d3e47d83fd14319c3499eac4fcb3","src/lib.rs":"d4ad3ceb63b735ab41e0cc5f500363196918a553a53af493de3173246a49dc98","src/os.rs":"355f0cee9643442d521851460af6bb593d690f29f1cb9144dc6e7b484edb3fd9","src/rand_impls.rs":"6bafe095c291c1718cc880a830beca46eb26a257a4fe44e4087245bbdca0656b","src/read.rs":"bdad8df5687fd90180bc602967d66248d3f051a11b4459aedcd3f21dbfa93f9b","src/reseeding.rs":"9f0d154e4d0fcc3024622adc386ead8ce222dac56761e9a6d92c4fb3c6e0d47b"},"package":"022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"c5edd03cb5679918a6d85f64c0a634ed83022ff85ea78f440f39fd281bd29c02","Cargo.toml":"e7efa66cdfb551389cc7485818a776cb289f248079df2247eece7f57b30c3abe","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"51831128477b9c9db0ec632ed6b6164f4e70e2d5f21eb5b3a391ecb9ab35e727","appveyor.yml":"6bf2f0c8f17d2dc4957dd39aba9a88ced3130200cf847a76d47b6c8fdcc2cbd8","benches/bench.rs":"2d3481c524841c532b9b9705073b223fd4b308c86ed7c9188b7fcd8e595ad459","benches/distributions/exponential.rs":"99cb59c013a0b6bb390d34c5649b341fc3b88ea7df0caf2470bdda8798f9fe3d","benches/distributions/gamma.rs":"3533f311e4b55d743c5b01a7eb6529c94fd97726ef6702a6372f914f5f33666b","benches/distributions/mod.rs":"0028f1cb96f61152ed5b49a4fe91227d809ef6d19035592c36032a538af7f95e","benches/distributions/normal.rs":"4e10c18cb583ccb96301ea953c8e0aa9ee3b6662060271d1b8d19ca23364dc6b","src/chacha.rs":"529c20ca1eff845da4cdca9ac995bcb8e698e48a61fbae91f09e3b4600ac57c3","src/distributions/exponential.rs":"103c8412c8a581b71835f1c00e40f6370e7702adf9d499243933a793d132d4e7","src/distributions/gamma.rs":"8403bce8e78a42eda20578329d4f5e7ccbb86139a39d6efbd2d37b698d36e946","src/distributions/mod.rs":"2c042ad7d0d53f9c54c02d11e1e623bca8906785cf4264ad708fa05420724f52","src/distributions/normal.rs":"1562b43f80e4d5f83a8deb5af18de5a18dfeeeeda11fefc577da26672b14c949","src/distributions/range.rs":"c0ac6858d6a3979de7996feca22d190fde0bfb6f758d43030efa04a1a0fdcc17","src/distributions/ziggurat_tables.rs":"4eacf94fc352c91c455a6623de6a721e53842e1690f13a5662b6a79c7fbb73de","src/isaac.rs":"1725114b2d63c6fe4c0f4f7e0c36fc993a47f0322350d13abc631b0806bb71ed","src/lib.rs":"e3470f49b8ba85b590bd4375ff0d90874916cf0296637a6639a22c2a4301c3bf","src/os.rs":"ea6c5eb1a2ac8f41269d45b55655704a0ec1b8dd49d3a0a6644263c0acbad0fe","src/rand_impls.rs":"cf411028341f67fd196ccde6200eea563c993f59d360a030b3d7d3ee15447a7d","src/read.rs":"bd0eb508a6b659dc578d546fc2f231484aed80c73cfe8c475e0d65c8d699a769","src/reseeding.rs":"73b2539b86b4cb8068e54716c7fd53e0d70b6c0de787a0749431b17019c9d826"},"package":"61efcbcd9fa8d8fbb07c84e34a8af18a1ff177b449689ad38a6e9457ecc7b2ae"}
\ No newline at end of file
--- a/third_party/rust/rand/.travis.yml
+++ b/third_party/rust/rand/.travis.yml
@@ -1,24 +1,30 @@
language: rust
-rust:
- - 1.0.0
- - stable
- - beta
- - nightly
sudo: false
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
+
+matrix:
+ include:
+ - rust: 1.15.0
+ - rust: stable
+ - rust: stable
+ os: osx
+ - rust: beta
+ - rust: nightly
+ script:
+ - cargo test
+ - cargo test --features nightly
+ - cargo test --manifest-path rand-derive/Cargo.toml
+ - cargo doc --no-deps --features nightly
script:
- - cargo build --verbose
- - cargo test --verbose
- - cargo doc --no-deps
+ - cargo test
+ - cargo test --manifest-path rand-derive/Cargo.toml
after_success:
- travis-cargo --only nightly doc-upload
env:
global:
secure: "BdDntVHSompN+Qxz5Rz45VI4ZqhD72r6aPl166FADlnkIwS6N6FLWdqs51O7G5CpoMXEDvyYrjmRMZe/GYLIG9cmqmn/wUrWPO+PauGiIuG/D2dmfuUNvSTRcIe7UQLXrfP3yyfZPgqsH6pSnNEVopquQKy3KjzqepgriOJtbyY="
-
-
notifications:
email:
on_success: never
--- a/third_party/rust/rand/Cargo.toml
+++ b/third_party/rust/rand/Cargo.toml
@@ -1,20 +1,34 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
[package]
-
name = "rand"
-version = "0.3.15"
+version = "0.3.17"
authors = ["The Rust Project Developers"]
-license = "MIT/Apache-2.0"
+description = "Random number generators and other randomness functionality.\n"
+homepage = "https://github.com/rust-lang-nursery/rand"
+documentation = "https://docs.rs/rand"
readme = "README.md"
-repository = "https://github.com/rust-lang/rand"
-documentation = "https://doc.rust-lang.org/rand"
-homepage = "https://github.com/rust-lang/rand"
-description = """
-Random number generators and other randomness functionality.
-"""
keywords = ["random", "rng"]
+categories = ["algorithms"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-lang-nursery/rand"
+[dependencies.libc]
+version = "0.2"
+[dev-dependencies.log]
+version = "0.3.0"
-[dependencies]
-libc = "0.2"
-
-[dev-dependencies]
-log = "0.3.0"
+[features]
+nightly = ["i128_support"]
+i128_support = []
+[target."cfg(target_os = \"fuchsia\")".dependencies.fuchsia-zircon]
+version = "^0.2.1"
--- a/third_party/rust/rand/README.md
+++ b/third_party/rust/rand/README.md
@@ -1,17 +1,17 @@
rand
====
A Rust library for random number generators and other randomness functionality.
[![Build Status](https://travis-ci.org/rust-lang-nursery/rand.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/rand)
[![Build status](https://ci.appveyor.com/api/projects/status/rm5c9o33k3jhchbw?svg=true)](https://ci.appveyor.com/project/alexcrichton/rand)
-[Documentation](https://doc.rust-lang.org/rand)
+[Documentation](https://docs.rs/rand)
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
rand = "0.3"
@@ -45,8 +45,43 @@ It is also possible to use other RNG typ
```rust
use rand::{Rng, ChaChaRng};
let mut rng = rand::ChaChaRng::new_unseeded();
println!("i32: {}, u32: {}", rng.gen::<i32>(), rng.gen::<u32>())
```
+# `derive(Rand)`
+
+You can derive the `Rand` trait for your custom type via the `#[derive(Rand)]`
+directive. To use this first add this to your Cargo.toml:
+
+```toml
+rand = "0.3"
+rand_derive = "0.3"
+```
+
+Next in your crate:
+
+```rust
+extern crate rand;
+#[macro_use]
+extern crate rand_derive;
+
+#[derive(Rand, Debug)]
+struct MyStruct {
+ a: i32,
+ b: u32,
+}
+
+fn main() {
+ println!("{:?}", rand::random::<MyStruct>());
+}
+```
+
+
+# License
+
+`rand` is primarily distributed under the terms of both the MIT
+license and the Apache License (Version 2.0).
+
+See LICENSE-APACHE, and LICENSE-MIT for details.
--- a/third_party/rust/rand/appveyor.yml
+++ b/third_party/rust/rand/appveyor.yml
@@ -1,17 +1,37 @@
environment:
+
+ # At the time this was added AppVeyor was having troubles with checking
+ # revocation of SSL certificates of sites like static.rust-lang.org and what
+ # we think is crates.io. The libcurl HTTP client by default checks for
+ # revocation on Windows and according to a mailing list [1] this can be
+ # disabled.
+ #
+ # The `CARGO_HTTP_CHECK_REVOKE` env var here tells cargo to disable SSL
+ # revocation checking on Windows in libcurl. Note, though, that rustup, which
+ # we're using to download Rust here, also uses libcurl as the default backend.
+ # Unlike Cargo, however, rustup doesn't have a mechanism to disable revocation
+ # checking. To get rustup working we set `RUSTUP_USE_HYPER` which forces it to
+ # use the Hyper instead of libcurl backend. Both Hyper and libcurl use
+ # schannel on Windows but it appears that Hyper configures it slightly
+ # differently such that revocation checking isn't turned on by default.
+ #
+ # [1]: https://curl.haxx.se/mail/lib-2016-03/0202.html
+ RUSTUP_USE_HYPER: 1
+ CARGO_HTTP_CHECK_REVOKE: false
+
matrix:
- TARGET: x86_64-pc-windows-msvc
- TARGET: i686-pc-windows-msvc
- - TARGET: i686-pc-windows-gnu
install:
- - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
- - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
- - SET PATH=%PATH%;C:\MinGW\bin
+ - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
+ - rustup-init.exe -y --default-host %TARGET% --default-toolchain nightly
+ - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -V
- cargo -V
build: false
test_script:
- - cargo test --verbose --target %TARGET%
+ - cargo test
+ - cargo test --features nightly
+ - cargo test --manifest-path rand-derive/Cargo.toml
--- a/third_party/rust/rand/benches/bench.rs
+++ b/third_party/rust/rand/benches/bench.rs
@@ -5,17 +5,17 @@ extern crate rand;
const RAND_BENCH_N: u64 = 1000;
mod distributions;
use std::mem::size_of;
use test::{black_box, Bencher};
use rand::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng};
-use rand::{OsRng, weak_rng};
+use rand::{OsRng, sample, weak_rng};
#[bench]
fn rand_xorshift(b: &mut Bencher) {
let mut rng: XorShiftRng = OsRng::new().unwrap().gen();
b.iter(|| {
for _ in 0..RAND_BENCH_N {
black_box(rng.gen::<usize>());
}
@@ -81,8 +81,17 @@ fn rand_f64(b: &mut Bencher) {
#[bench]
fn rand_shuffle_100(b: &mut Bencher) {
let mut rng = weak_rng();
let x : &mut [usize] = &mut [1; 100];
b.iter(|| {
rng.shuffle(x);
})
}
+
+#[bench]
+fn rand_sample_10_of_100(b: &mut Bencher) {
+ let mut rng = weak_rng();
+ let x : &[usize] = &[1; 100];
+ b.iter(|| {
+ sample(&mut rng, x, 10);
+ })
+}
--- a/third_party/rust/rand/src/chacha.rs
+++ b/third_party/rust/rand/src/chacha.rs
@@ -21,17 +21,17 @@ const CHACHA_ROUNDS: u32 = 20; // Crypto
///
/// The ChaCha algorithm is widely accepted as suitable for
/// cryptographic purposes, but this implementation has not been
/// verified as such. Prefer a generator like `OsRng` that defers to
/// the operating system for cases that need high security.
///
/// [1]: D. J. Bernstein, [*ChaCha, a variant of
/// Salsa20*](http://cr.yp.to/chacha.html)
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct ChaChaRng {
buffer: [w32; STATE_WORDS], // Internal buffer of output
state: [w32; STATE_WORDS], // Initial state
index: usize, // Index into state
}
static EMPTY: ChaChaRng = ChaChaRng {
buffer: [w(0); STATE_WORDS],
--- a/third_party/rust/rand/src/distributions/exponential.rs
+++ b/third_party/rust/rand/src/distributions/exponential.rs
@@ -29,17 +29,17 @@ use distributions::{ziggurat, ziggurat_t
/// # Example
///
/// ```rust
/// use rand::distributions::exponential::Exp1;
///
/// let Exp1(x) = rand::random();
/// println!("{}", x);
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Exp1(pub f64);
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
impl Rand for Exp1 {
#[inline]
fn rand<R:Rng>(rng: &mut R) -> Exp1 {
#[inline]
fn pdf(x: f64) -> f64 {
@@ -66,17 +66,17 @@ impl Rand for Exp1 {
///
/// ```rust
/// use rand::distributions::{Exp, IndependentSample};
///
/// let exp = Exp::new(2.0);
/// let v = exp.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a Exp(2) distribution", v);
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Exp {
/// `lambda` stored as `1/lambda`, since this is what we scale by.
lambda_inverse: f64
}
impl Exp {
/// Construct a new `Exp` with the given shape parameter
/// `lambda`. Panics if `lambda <= 0`.
--- a/third_party/rust/rand/src/distributions/gamma.rs
+++ b/third_party/rust/rand/src/distributions/gamma.rs
@@ -44,22 +44,22 @@ use super::{IndependentSample, Sample, E
/// let v = gamma.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a Gamma(2, 5) distribution", v);
/// ```
///
/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
/// (September 2000),
/// 363-372. DOI:[10.1145/358407.358414](http://doi.acm.org/10.1145/358407.358414)
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Gamma {
repr: GammaRepr,
}
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
enum GammaRepr {
Large(GammaLargeShape),
One(Exp),
Small(GammaSmallShape)
}
// These two helpers could be made public, but saving the
// match-on-Gamma-enum branch from using them directly (e.g. if one
@@ -70,47 +70,49 @@ enum GammaRepr {
///
/// Note, samples from this require a compulsory floating-point `pow`
/// call, which makes it significantly slower than sampling from a
/// gamma distribution where the shape parameter is greater than or
/// equal to 1.
///
/// See `Gamma` for sampling from a Gamma distribution with general
/// shape parameters.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
struct GammaSmallShape {
inv_shape: f64,
large_shape: GammaLargeShape
}
/// Gamma distribution where the shape parameter is larger than 1.
///
/// See `Gamma` for sampling from a Gamma distribution with general
/// shape parameters.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
struct GammaLargeShape {
scale: f64,
c: f64,
d: f64
}
impl Gamma {
/// Construct an object representing the `Gamma(shape, scale)`
/// distribution.
///
/// Panics if `shape <= 0` or `scale <= 0`.
#[inline]
pub fn new(shape: f64, scale: f64) -> Gamma {
assert!(shape > 0.0, "Gamma::new called with shape <= 0");
assert!(scale > 0.0, "Gamma::new called with scale <= 0");
- let repr = match shape {
- 1.0 => One(Exp::new(1.0 / scale)),
- 0.0 ... 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
- _ => Large(GammaLargeShape::new_raw(shape, scale))
+ let repr = if shape == 1.0 {
+ One(Exp::new(1.0 / scale))
+ } else if shape < 1.0 {
+ Small(GammaSmallShape::new_raw(shape, scale))
+ } else {
+ Large(GammaLargeShape::new_raw(shape, scale))
};
Gamma { repr: repr }
}
}
impl GammaSmallShape {
fn new_raw(shape: f64, scale: f64) -> GammaSmallShape {
GammaSmallShape {
@@ -190,22 +192,22 @@ impl IndependentSample<f64> for GammaLar
///
/// ```rust
/// use rand::distributions::{ChiSquared, IndependentSample};
///
/// let chi = ChiSquared::new(11.0);
/// let v = chi.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a χ²(11) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct ChiSquared {
repr: ChiSquaredRepr,
}
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
enum ChiSquaredRepr {
// k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
// e.g. when alpha = 1/2 as it would be for this case, so special-
// casing and using the definition of N(0,1)^2 is faster.
DoFExactlyOne,
DoFAnythingElse(Gamma),
}
@@ -248,17 +250,17 @@ impl IndependentSample<f64> for ChiSquar
///
/// ```rust
/// use rand::distributions::{FisherF, IndependentSample};
///
/// let f = FisherF::new(2.0, 32.0);
/// let v = f.ind_sample(&mut rand::thread_rng());
/// println!("{} is from an F(2, 32) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct FisherF {
numer: ChiSquared,
denom: ChiSquared,
// denom_dof / numer_dof so that this can just be a straight
// multiplication, rather than a division.
dof_ratio: f64,
}
@@ -292,17 +294,17 @@ impl IndependentSample<f64> for FisherF
///
/// ```rust
/// use rand::distributions::{StudentT, IndependentSample};
///
/// let t = StudentT::new(11.0);
/// let v = t.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a t(11) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct StudentT {
chi: ChiSquared,
dof: f64
}
impl StudentT {
/// Create a new Student t distribution with `n` degrees of
/// freedom. Panics if `n <= 0`.
--- a/third_party/rust/rand/src/distributions/mod.rs
+++ b/third_party/rust/rand/src/distributions/mod.rs
@@ -48,16 +48,17 @@ pub trait Sample<Support> {
// trait called `Sample` and the other should be `DependentSample`.
pub trait IndependentSample<Support>: Sample<Support> {
/// Generate a random value.
fn ind_sample<R: Rng>(&self, &mut R) -> Support;
}
/// A wrapper for generating types that implement `Rand` via the
/// `Sample` & `IndependentSample` traits.
+#[derive(Debug)]
pub struct RandSample<Sup> {
_marker: marker::PhantomData<fn() -> Sup>,
}
impl<Sup> Copy for RandSample<Sup> {}
impl<Sup> Clone for RandSample<Sup> {
fn clone(&self) -> Self { *self }
}
@@ -74,18 +75,17 @@ impl<Sup: Rand> IndependentSample<Sup> f
impl<Sup> RandSample<Sup> {
pub fn new() -> RandSample<Sup> {
RandSample { _marker: marker::PhantomData }
}
}
/// A value with a particular weight for use with `WeightedChoice`.
-#[derive(Copy)]
-#[derive(Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct Weighted<T> {
/// The numerical weight of this item
pub weight: u32,
/// The actual item which is being weighted
pub item: T,
}
/// A distribution that selects from a finite collection of weighted items.
@@ -108,16 +108,17 @@ pub struct Weighted<T> {
/// Weighted { weight: 1, item: 'c' });
/// let wc = WeightedChoice::new(&mut items);
/// let mut rng = rand::thread_rng();
/// for _ in 0..16 {
/// // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
/// println!("{}", wc.ind_sample(&mut rng));
/// }
/// ```
+#[derive(Debug)]
pub struct WeightedChoice<'a, T:'a> {
items: &'a mut [Weighted<T>],
weight_range: Range<u32>
}
impl<'a, T: Clone> WeightedChoice<'a, T> {
/// Create a new `WeightedChoice`.
///
--- a/third_party/rust/rand/src/distributions/normal.rs
+++ b/third_party/rust/rand/src/distributions/normal.rs
@@ -28,17 +28,17 @@ use distributions::{ziggurat, ziggurat_t
/// # Example
///
/// ```rust
/// use rand::distributions::normal::StandardNormal;
///
/// let StandardNormal(x) = rand::random();
/// println!("{}", x);
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct StandardNormal(pub f64);
impl Rand for StandardNormal {
fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
#[inline]
fn pdf(x: f64) -> f64 {
(-x*x/2.0).exp()
}
@@ -83,17 +83,17 @@ impl Rand for StandardNormal {
/// ```rust
/// use rand::distributions::{Normal, IndependentSample};
///
/// // mean 2, standard deviation 3
/// let normal = Normal::new(2.0, 3.0);
/// let v = normal.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a N(2, 9) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Normal {
mean: f64,
std_dev: f64,
}
impl Normal {
/// Construct a new `Normal` distribution with the given mean and
/// standard deviation.
@@ -131,17 +131,17 @@ impl IndependentSample<f64> for Normal {
/// ```rust
/// use rand::distributions::{LogNormal, IndependentSample};
///
/// // mean 2, standard deviation 3
/// let log_normal = LogNormal::new(2.0, 3.0);
/// let v = log_normal.ind_sample(&mut rand::thread_rng());
/// println!("{} is from an ln N(2, 9) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct LogNormal {
norm: Normal
}
impl LogNormal {
/// Construct a new `LogNormal` distribution with the given mean
/// and standard deviation.
///
--- a/third_party/rust/rand/src/distributions/range.rs
+++ b/third_party/rust/rand/src/distributions/range.rs
@@ -41,17 +41,17 @@ use distributions::{Sample, IndependentS
/// let mut rng = rand::thread_rng();
/// let mut sum = 0;
/// for _ in 0..1000 {
/// sum += between.ind_sample(&mut rng);
/// }
/// println!("{}", sum);
/// }
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Range<X> {
low: X,
range: X,
accept_zone: X
}
impl<X: SampleRange + PartialOrd> Range<X> {
/// Create a new `Range` instance that samples uniformly from
@@ -91,32 +91,34 @@ macro_rules! integer_impl {
($ty:ty, $unsigned:ident) => {
impl SampleRange for $ty {
// we play free and fast with unsigned vs signed here
// (when $ty is signed), but that's fine, since the
// contract of this macro is for $ty and $unsigned to be
// "bit-equal", so casting between them is a no-op & a
// bijection.
+ #[inline]
fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
let range = (w(high as $unsigned) - w(low as $unsigned)).0;
let unsigned_max: $unsigned = ::std::$unsigned::MAX;
// this is the largest number that fits into $unsigned
// that `range` divides evenly, so, if we've sampled
// `n` uniformly from this region, then `n % range` is
// uniform in [0, range)
let zone = unsigned_max - unsigned_max % range;
Range {
low: low,
range: range as $ty,
accept_zone: zone as $ty
}
}
+
#[inline]
fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
loop {
// rejection sample
let v = rng.gen::<$unsigned>();
// until we find something that fits into the
// region which r.range evenly divides (this will
// be uniformly distributed)
--- a/third_party/rust/rand/src/isaac.rs
+++ b/third_party/rust/rand/src/isaac.rs
@@ -10,16 +10,17 @@
//! The ISAAC random number generator.
#![allow(non_camel_case_types)]
use std::slice;
use std::iter::repeat;
use std::num::Wrapping as w;
+use std::fmt;
use {Rng, SeedableRng, Rand, w32, w64};
const RAND_SIZE_LEN: usize = 8;
const RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
const RAND_SIZE_USIZE: usize = 1 << RAND_SIZE_LEN;
/// A random number generator that uses the ISAAC algorithm[1].
@@ -255,16 +256,22 @@ impl Rand for IsaacRng {
ret.b = w(0);
ret.c = w(0);
ret.init(true);
return ret;
}
}
+impl fmt::Debug for IsaacRng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "IsaacRng {{}}")
+ }
+}
+
const RAND_SIZE_64_LEN: usize = 8;
const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
/// A random number generator that uses ISAAC-64[1], the 64-bit
/// variant of the ISAAC algorithm.
///
/// The ISAAC algorithm is generally accepted as suitable for
/// cryptographic purposes, but this implementation has not be
@@ -498,16 +505,21 @@ impl Rand for Isaac64Rng {
ret.b = w(0);
ret.c = w(0);
ret.init(true);
return ret;
}
}
+impl fmt::Debug for Isaac64Rng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "Isaac64Rng {{}}")
+ }
+}
#[cfg(test)]
mod test {
use {Rng, SeedableRng};
use super::{IsaacRng, Isaac64Rng};
#[test]
fn test_rng_32_rand_seeded() {
--- a/third_party/rust/rand/src/lib.rs
+++ b/third_party/rust/rand/src/lib.rs
@@ -234,20 +234,25 @@
//! switch_wins as f32 / total_switches as f32);
//! println!("Estimated chance to win if we don't: {}",
//! keep_wins as f32 / total_keeps as f32);
//! }
//! ```
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
- html_root_url = "https://doc.rust-lang.org/rand/")]
+ html_root_url = "https://docs.rs/rand/0.3")]
+
+#![deny(missing_debug_implementations)]
+
+#![cfg_attr(feature = "i128_support", feature(i128_type))]
#[cfg(test)] #[macro_use] extern crate log;
+
use std::cell::RefCell;
use std::marker;
use std::mem;
use std::io;
use std::rc::Rc;
use std::num::Wrapping as w;
pub use os::OsRng;
@@ -272,29 +277,61 @@ pub mod os;
pub mod read;
#[allow(bad_style)]
type w64 = w<u64>;
#[allow(bad_style)]
type w32 = w<u32>;
/// A type that can be randomly generated using an `Rng`.
+///
+/// ## Built-in Implementations
+///
+/// This crate implements `Rand` for various primitive types. Assuming the
+/// provided `Rng` is well-behaved, these implementations generate values with
+/// the following ranges and distributions:
+///
+/// * Integers (`i32`, `u32`, `isize`, `usize`, etc.): Uniformly distributed
+/// over all values of the type.
+/// * `char`: Uniformly distributed over all Unicode scalar values, i.e. all
+/// code points in the range `0...0x10_FFFF`, except for the range
+/// `0xD800...0xDFFF` (the surrogate code points). This includes
+/// unassigned/reserved code points.
+/// * `bool`: Generates `false` or `true`, each with probability 0.5.
+/// * Floating point types (`f32` and `f64`): Uniformly distributed in the
+/// half-open range `[0, 1)`. (The [`Open01`], [`Closed01`], [`Exp1`], and
+/// [`StandardNormal`] wrapper types produce floating point numbers with
+/// alternative ranges or distributions.)
+///
+/// [`Open01`]: struct.Open01.html
+/// [`Closed01`]: struct.Closed01.html
+/// [`Exp1`]: struct.Exp1.html
+/// [`StandardNormal`]: struct.StandardNormal.html
+///
+/// The following aggregate types also implement `Rand` as long as their
+/// component types implement it:
+///
+/// * Tuples and arrays: Each element of the tuple or array is generated
+/// independently, using its own `Rand` implementation.
+/// * `Option<T>`: Returns `None` with probability 0.5; otherwise generates a
+/// random `T` and returns `Some(T)`.
+
pub trait Rand : Sized {
/// Generates a random instance of this type using the specified source of
/// randomness.
fn rand<R: Rng>(rng: &mut R) -> Self;
}
/// A random number generator.
pub trait Rng {
/// Return the next random u32.
///
/// This rarely needs to be called directly, prefer `r.gen()` to
/// `r.next_u32()`.
- // FIXME #7771: Should be implemented in terms of next_u64
+ // FIXME #rust-lang/rfcs#628: Should be implemented in terms of next_u64
fn next_u32(&mut self) -> u32;
/// Return the next random u64.
///
/// By default this is implemented in terms of `next_u32`. An
/// implementation of this trait must provide at least one of
/// these two methods. Similarly to `next_u32`, this rarely needs
/// to be called directly, prefer `r.gen()` to `r.next_u64()`.
@@ -526,16 +563,19 @@ pub trait Rng {
} else {
let len = values.len();
Some(&mut values[self.gen_range(0, len)])
}
}
/// Shuffle a mutable slice in place.
///
+ /// This applies Durstenfeld's algorithm for the [Fisher–Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm)
+ /// which produces an unbiased permutation.
+ ///
/// # Example
///
/// ```rust
/// use rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
/// let mut y = [1, 2, 3];
/// rng.shuffle(&mut y);
@@ -599,16 +639,17 @@ impl<R: ?Sized> Rng for Box<R> where R:
}
/// Iterator which will generate a stream of random items.
///
/// This iterator is created via the [`gen_iter`] method on [`Rng`].
///
/// [`gen_iter`]: trait.Rng.html#method.gen_iter
/// [`Rng`]: trait.Rng.html
+#[derive(Debug)]
pub struct Generator<'a, T, R:'a> {
rng: &'a mut R,
_marker: marker::PhantomData<fn() -> T>,
}
impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
type Item = T;
@@ -618,16 +659,17 @@ impl<'a, T: Rand, R: Rng> Iterator for G
}
/// Iterator which will continuously generate random ascii characters.
///
/// This iterator is created via the [`gen_ascii_chars`] method on [`Rng`].
///
/// [`gen_ascii_chars`]: trait.Rng.html#method.gen_ascii_chars
/// [`Rng`]: trait.Rng.html
+#[derive(Debug)]
pub struct AsciiGenerator<'a, R:'a> {
rng: &'a mut R,
}
impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
type Item = char;
fn next(&mut self) -> Option<char> {
@@ -677,17 +719,17 @@ pub trait SeedableRng<Seed>: Rng {
/// The Xorshift algorithm is not suitable for cryptographic purposes
/// but is very fast. If you do not know for sure that it fits your
/// requirements, use a more secure one such as `IsaacRng` or `OsRng`.
///
/// [1]: Marsaglia, George (July 2003). ["Xorshift
/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
/// Statistical Software*. Vol. 8 (Issue 14).
#[allow(missing_copy_implementations)]
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct XorShiftRng {
x: w32,
y: w32,
z: w32,
w: w32,
}
impl XorShiftRng {
@@ -767,16 +809,17 @@ impl Rand for XorShiftRng {
///
/// # Example
/// ```rust
/// use rand::{random, Open01};
///
/// let Open01(val) = random::<Open01<f32>>();
/// println!("f32 from (0,1): {}", val);
/// ```
+#[derive(Debug)]
pub struct Open01<F>(pub F);
/// A wrapper for generating floating point numbers uniformly in the
/// closed interval `[0,1]` (including both endpoints).
///
/// Use `Open01` for the closed interval `(0,1)`, and the default
/// `Rand` implementation of `f32` and `f64` for the half-open
/// `[0,1)`.
@@ -784,21 +827,22 @@ pub struct Open01<F>(pub F);
/// # Example
///
/// ```rust
/// use rand::{random, Closed01};
///
/// let Closed01(val) = random::<Closed01<f32>>();
/// println!("f32 from [0,1]: {}", val);
/// ```
+#[derive(Debug)]
pub struct Closed01<F>(pub F);
/// The standard RNG. This is designed to be efficient on the current
/// platform.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct StdRng {
rng: IsaacWordRng,
}
impl StdRng {
/// Create a randomly seeded instance of `StdRng`.
///
/// This is a very expensive operation as it has to read
@@ -851,31 +895,32 @@ impl<'a> SeedableRng<&'a [usize]> for St
pub fn weak_rng() -> XorShiftRng {
match OsRng::new() {
Ok(mut r) => r.gen(),
Err(e) => panic!("weak_rng: failed to create seeded RNG: {:?}", e)
}
}
/// Controls how the thread-local RNG is reseeded.
+#[derive(Debug)]
struct ThreadRngReseeder;
impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
fn reseed(&mut self, rng: &mut StdRng) {
*rng = match StdRng::new() {
Ok(r) => r,
Err(e) => panic!("could not reseed thread_rng: {}", e)
}
}
}
const THREAD_RNG_RESEED_THRESHOLD: u64 = 32_768;
type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
/// The thread-local RNG.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct ThreadRng {
rng: Rc<RefCell<ThreadRngInner>>,
}
/// Retrieve the lazily-initialized thread-local random number
/// generator, seeded by the system. Intended to be used in method
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
///
@@ -959,17 +1004,18 @@ impl Rng for ThreadRng {
/// *x = rng.gen();
/// }
/// ```
#[inline]
pub fn random<T: Rand>() -> T {
thread_rng().gen()
}
-/// Randomly sample up to `amount` elements from an iterator.
+/// Randomly sample up to `amount` elements from a finite iterator.
+/// The order of elements in the sample is not random.
///
/// # Example
///
/// ```rust
/// use rand::{thread_rng, sample};
///
/// let mut rng = thread_rng();
/// let sample = sample(&mut rng, 1..100, 5);
--- a/third_party/rust/rand/src/os.rs
+++ b/third_party/rust/rand/src/os.rs
@@ -6,62 +6,74 @@
// 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.
//! Interfaces to the operating system provided random number
//! generators.
-use std::{io, mem};
+use std::{io, mem, fmt};
use Rng;
/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
///
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
/// `/dev/urandom`, or from `getrandom(2)` system call if available.
/// - OpenBSD: calls `getentropy(2)`
/// - FreeBSD: uses the `kern.arandom` `sysctl(2)` mib
-/// - Windows: calls `CryptGenRandom`, using the default cryptographic
-/// service provider with the `PROV_RSA_FULL` type.
+/// - Windows: calls `RtlGenRandom`, exported from `advapi32.dll` as
+/// `SystemFunction036`.
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
/// - PNaCl: calls into the `nacl-irt-random-0.1` IRT interface.
///
-/// This does not block.
+/// This usually does not block. On some systems (e.g. FreeBSD, OpenBSD,
+/// Max OS X, and modern Linux) this may block very early in the init
+/// process, if the CSPRNG has not been seeded yet.[1]
+///
+/// [1] See https://www.python.org/dev/peps/pep-0524/ for a more in-depth
+/// discussion.
pub struct OsRng(imp::OsRng);
impl OsRng {
/// Create a new `OsRng`.
pub fn new() -> io::Result<OsRng> {
imp::OsRng::new().map(OsRng)
}
}
impl Rng for OsRng {
fn next_u32(&mut self) -> u32 { self.0.next_u32() }
fn next_u64(&mut self) -> u64 { self.0.next_u64() }
fn fill_bytes(&mut self, v: &mut [u8]) { self.0.fill_bytes(v) }
}
+impl fmt::Debug for OsRng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "OsRng {{}}")
+ }
+}
+
fn next_u32(mut fill_buf: &mut FnMut(&mut [u8])) -> u32 {
let mut buf: [u8; 4] = [0; 4];
fill_buf(&mut buf);
unsafe { mem::transmute::<[u8; 4], u32>(buf) }
}
fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
let mut buf: [u8; 8] = [0; 8];
fill_buf(&mut buf);
unsafe { mem::transmute::<[u8; 8], u64>(buf) }
}
#[cfg(all(unix, not(target_os = "ios"),
not(target_os = "nacl"),
not(target_os = "freebsd"),
+ not(target_os = "fuchsia"),
not(target_os = "openbsd"),
not(target_os = "redox")))]
mod imp {
extern crate libc;
use super::{next_u32, next_u64};
use self::OsRngInner::*;
@@ -208,16 +220,17 @@ mod imp {
extern crate libc;
use super::{next_u32, next_u64};
use std::io;
use Rng;
use self::libc::{c_int, size_t};
+ #[derive(Debug)]
pub struct OsRng;
enum SecRandom {}
#[allow(non_upper_case_globals)]
const kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;
#[link(name = "Security", kind = "framework")]
@@ -254,16 +267,17 @@ mod imp {
mod imp {
extern crate libc;
use std::{io, ptr};
use Rng;
use super::{next_u32, next_u64};
+ #[derive(Debug)]
pub struct OsRng;
impl OsRng {
pub fn new() -> io::Result<OsRng> {
Ok(OsRng)
}
}
@@ -297,16 +311,17 @@ mod imp {
mod imp {
extern crate libc;
use std::io;
use Rng;
use super::{next_u32, next_u64};
+ #[derive(Debug)]
pub struct OsRng;
impl OsRng {
pub fn new() -> io::Result<OsRng> {
Ok(OsRng)
}
}
@@ -334,16 +349,17 @@ mod imp {
#[cfg(target_os = "redox")]
mod imp {
use std::io;
use std::fs::File;
use Rng;
use read::ReadRng;
+ #[derive(Debug)]
pub struct OsRng {
inner: ReadRng<File>,
}
impl OsRng {
pub fn new() -> io::Result<OsRng> {
let reader = try!(File::open("rand:"));
let reader_rng = ReadRng::new(reader);
@@ -360,114 +376,114 @@ mod imp {
self.inner.next_u64()
}
fn fill_bytes(&mut self, v: &mut [u8]) {
self.inner.fill_bytes(v)
}
}
}
-#[cfg(windows)]
+#[cfg(target_os = "fuchsia")]
mod imp {
+ extern crate fuchsia_zircon;
+
use std::io;
- use std::ptr;
use Rng;
use super::{next_u32, next_u64};
- type BOOL = i32;
- type LPCSTR = *const i8;
- type DWORD = u32;
- type HCRYPTPROV = usize;
- type BYTE = u8;
-
- const PROV_RSA_FULL: DWORD = 1;
- const CRYPT_SILENT: DWORD = 0x00000040;
- const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
-
- #[link(name = "advapi32")]
- extern "system" {
- fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
- szContainer: LPCSTR,
- szProvider: LPCSTR,
- dwProvType: DWORD,
- dwFlags: DWORD) -> BOOL;
- fn CryptGenRandom(hProv: HCRYPTPROV,
- dwLen: DWORD,
- pbBuffer: *mut BYTE) -> BOOL;
- fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
- }
-
- pub struct OsRng {
- hcryptprov: HCRYPTPROV
- }
+ #[derive(Debug)]
+ pub struct OsRng;
impl OsRng {
pub fn new() -> io::Result<OsRng> {
- let mut hcp = 0;
- let ret = unsafe {
- CryptAcquireContextA(&mut hcp, ptr::null(), ptr::null(),
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
- };
-
- if ret == 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(OsRng { hcryptprov: hcp })
- }
+ Ok(OsRng)
}
}
impl Rng for OsRng {
fn next_u32(&mut self) -> u32 {
next_u32(&mut |v| self.fill_bytes(v))
}
fn next_u64(&mut self) -> u64 {
next_u64(&mut |v| self.fill_bytes(v))
}
fn fill_bytes(&mut self, v: &mut [u8]) {
- // CryptGenRandom takes a DWORD (u32) for the length so we need to
+ for s in v.chunks_mut(fuchsia_zircon::ZX_CPRNG_DRAW_MAX_LEN) {
+ let mut filled = 0;
+ while filled < s.len() {
+ match fuchsia_zircon::cprng_draw(&mut s[filled..]) {
+ Ok(actual) => filled += actual,
+ Err(e) => panic!("cprng_draw failed: {:?}", e),
+ };
+ }
+ }
+ }
+ }
+}
+
+#[cfg(windows)]
+mod imp {
+ use std::io;
+ use Rng;
+
+ use super::{next_u32, next_u64};
+
+ type BOOLEAN = u8;
+ type ULONG = u32;
+
+ #[link(name = "advapi32")]
+ extern "system" {
+ // This function's real name is `RtlGenRandom`.
+ fn SystemFunction036(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
+ }
+
+ #[derive(Debug)]
+ pub struct OsRng;
+
+ impl OsRng {
+ pub fn new() -> io::Result<OsRng> {
+ Ok(OsRng)
+ }
+ }
+
+ impl Rng for OsRng {
+ fn next_u32(&mut self) -> u32 {
+ next_u32(&mut |v| self.fill_bytes(v))
+ }
+ fn next_u64(&mut self) -> u64 {
+ next_u64(&mut |v| self.fill_bytes(v))
+ }
+ fn fill_bytes(&mut self, v: &mut [u8]) {
+ // RtlGenRandom takes an ULONG (u32) for the length so we need to
// split up the buffer.
- for slice in v.chunks_mut(<DWORD>::max_value() as usize) {
+ for slice in v.chunks_mut(<ULONG>::max_value() as usize) {
let ret = unsafe {
- CryptGenRandom(self.hcryptprov, slice.len() as DWORD,
- slice.as_mut_ptr())
+ SystemFunction036(slice.as_mut_ptr(), slice.len() as ULONG)
};
if ret == 0 {
panic!("couldn't generate random bytes: {}",
io::Error::last_os_error());
}
}
}
}
-
- impl Drop for OsRng {
- fn drop(&mut self) {
- let ret = unsafe {
- CryptReleaseContext(self.hcryptprov, 0)
- };
- if ret == 0 {
- panic!("couldn't release context: {}",
- io::Error::last_os_error());
- }
- }
- }
}
#[cfg(target_os = "nacl")]
mod imp {
extern crate libc;
use std::io;
use std::mem;
use Rng;
use super::{next_u32, next_u64};
+ #[derive(Debug)]
pub struct OsRng(extern fn(dest: *mut libc::c_void,
bytes: libc::size_t,
read: *mut libc::size_t) -> libc::c_int);
extern {
fn nacl_interface_query(name: *const libc::c_char,
table: *mut libc::c_void,
table_size: libc::size_t) -> libc::size_t;
--- a/third_party/rust/rand/src/rand_impls.rs
+++ b/third_party/rust/rand/src/rand_impls.rs
@@ -49,16 +49,24 @@ impl Rand for i32 {
impl Rand for i64 {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> i64 {
rng.next_u64() as i64
}
}
+#[cfg(feature = "i128_support")]
+impl Rand for i128 {
+ #[inline]
+ fn rand<R: Rng>(rng: &mut R) -> i128 {
+ rng.gen::<u128>() as i128
+ }
+}
+
impl Rand for usize {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> usize {
if mem::size_of::<usize>() == 4 {
rng.gen::<u32>() as usize
} else {
rng.gen::<u64>() as usize
}
@@ -88,16 +96,25 @@ impl Rand for u32 {
impl Rand for u64 {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> u64 {
rng.next_u64()
}
}
+#[cfg(feature = "i128_support")]
+impl Rand for u128 {
+ #[inline]
+ fn rand<R: Rng>(rng: &mut R) -> u128 {
+ ((rng.next_u64() as u128) << 64) | (rng.next_u64() as u128)
+ }
+}
+
+
macro_rules! float_impls {
($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
mod $mod_name {
use {Rand, Rng, Open01, Closed01};
const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
impl Rand for $ty {
--- a/third_party/rust/rand/src/read.rs
+++ b/third_party/rust/rand/src/read.rs
@@ -25,16 +25,17 @@ use Rng;
///
/// ```rust
/// use rand::{read, Rng};
///
/// let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
/// let mut rng = read::ReadRng::new(&data[..]);
/// println!("{:x}", rng.gen::<u32>());
/// ```
+#[derive(Debug)]
pub struct ReadRng<R> {
reader: R
}
impl<R: Read> ReadRng<R> {
/// Create a new `ReadRng` from a `Read`.
pub fn new(r: R) -> ReadRng<R> {
ReadRng {
--- a/third_party/rust/rand/src/reseeding.rs
+++ b/third_party/rust/rand/src/reseeding.rs
@@ -16,16 +16,17 @@ use std::default::Default;
use {Rng, SeedableRng};
/// How many bytes of entropy the underling RNG is allowed to generate
/// before it is reseeded
const DEFAULT_GENERATION_THRESHOLD: u64 = 32 * 1024;
/// A wrapper around any RNG which reseeds the underlying RNG after it
/// has generated a certain number of random bytes.
+#[derive(Debug)]
pub struct ReseedingRng<R, Rsdr> {
rng: R,
generation_threshold: u64,
bytes_generated: u64,
/// Controls the behaviour when reseeding the RNG.
pub reseeder: Rsdr,
}
@@ -127,17 +128,17 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseede
/// ```
pub trait Reseeder<R> {
/// Reseed the given RNG.
fn reseed(&mut self, rng: &mut R);
}
/// Reseed an RNG using a `Default` instance. This reseeds by
/// replacing the RNG with the result of a `Default::default` call.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct ReseedWithDefault;
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
fn reseed(&mut self, rng: &mut R) {
*rng = Default::default();
}
}
impl Default for ReseedWithDefault {
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -495,16 +495,32 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "fuchsia-zircon"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "futures"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -945,17 +961,17 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -983,17 +999,17 @@ dependencies = [
]
[[package]]
name = "phf_generator"
version = "0.7.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
version = "0.7.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1062,19 +1078,20 @@ dependencies = [
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
-version = "0.3.15"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -1086,17 +1103,17 @@ name = "rayon-core"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1464,17 +1481,17 @@ name = "u2fhid"
version = "0.1.0"
dependencies = [
"boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1672,16 +1689,18 @@ dependencies = [
"checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
"checksum euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "50c9e4c3b53de731815135191f0b77969bea953211b8bbd3cc3083a7b10e190e"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
+"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
+"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gamma-lut 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd65074503368cef99b98844012adfed8d7f99ff3e1e6d05e9055232f2d59dc9"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
"checksum gl_generator 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0940975a4ca12b088d32b5d5134826c47d2e73de4b0b459b05244c01503eccbb"
"checksum gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bf887141f0c2a83eae026cbf3fba74f0a5cb0f01d20e5cdfcd8c4ad39295be1e"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
@@ -1724,17 +1743,17 @@ dependencies = [
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
"checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
-"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
+"checksum rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "61efcbcd9fa8d8fbb07c84e34a8af18a1ff177b449689ad38a6e9457ecc7b2ae"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -494,16 +494,32 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "fuchsia-zircon"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "futures"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -933,17 +949,17 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -971,17 +987,17 @@ dependencies = [
]
[[package]]
name = "phf_generator"
version = "0.7.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
version = "0.7.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1050,19 +1066,20 @@ dependencies = [
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
-version = "0.3.15"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -1074,17 +1091,17 @@ name = "rayon-core"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1476,17 +1493,17 @@ name = "u2fhid"
version = "0.1.0"
dependencies = [
"boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
"libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1684,16 +1701,18 @@ dependencies = [
"checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
"checksum euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "50c9e4c3b53de731815135191f0b77969bea953211b8bbd3cc3083a7b10e190e"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
+"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
+"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gamma-lut 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd65074503368cef99b98844012adfed8d7f99ff3e1e6d05e9055232f2d59dc9"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
"checksum gl_generator 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0940975a4ca12b088d32b5d5134826c47d2e73de4b0b459b05244c01503eccbb"
"checksum gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bf887141f0c2a83eae026cbf3fba74f0a5cb0f01d20e5cdfcd8c4ad39295be1e"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
@@ -1736,17 +1755,17 @@ dependencies = [
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
"checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
-"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
+"checksum rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "61efcbcd9fa8d8fbb07c84e34a8af18a1ff177b449689ad38a6e9457ecc7b2ae"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
"checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"