about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs2
-rw-r--r--src/libstd/c_str.rs2
-rw-r--r--src/libstd/cast.rs5
-rw-r--r--src/libstd/cell.rs8
-rw-r--r--src/libstd/fmt/mod.rs98
-rw-r--r--src/libstd/io.rs1
-rw-r--r--src/libstd/iterator.rs15
-rw-r--r--src/libstd/local_data.rs1
-rw-r--r--src/libstd/macros.rs42
-rw-r--r--src/libstd/num/int_macros.rs1
-rw-r--r--src/libstd/num/uint_macros.rs4
-rw-r--r--src/libstd/option.rs2
-rw-r--r--src/libstd/os.rs33
-rw-r--r--src/libstd/ptr.rs43
-rw-r--r--src/libstd/rand.rs2
-rw-r--r--src/libstd/rand/distributions.rs2
-rw-r--r--src/libstd/repr.rs2
-rw-r--r--src/libstd/rt/args.rs4
-rw-r--r--src/libstd/rt/comm.rs41
-rw-r--r--src/libstd/rt/context.rs8
-rw-r--r--src/libstd/rt/io/extensions.rs296
-rw-r--r--src/libstd/rt/io/file.rs343
-rw-r--r--src/libstd/rt/io/mod.rs25
-rw-r--r--src/libstd/rt/io/timer.rs9
-rw-r--r--src/libstd/rt/kill.rs86
-rw-r--r--src/libstd/rt/local.rs34
-rw-r--r--src/libstd/rt/local_heap.rs7
-rw-r--r--src/libstd/rt/local_ptr.rs63
-rw-r--r--src/libstd/rt/message_queue.rs53
-rw-r--r--src/libstd/rt/metrics.rs98
-rw-r--r--src/libstd/rt/mod.rs6
-rw-r--r--src/libstd/rt/rtio.rs31
-rw-r--r--src/libstd/rt/sched.rs52
-rw-r--r--src/libstd/rt/sleeper_list.rs53
-rw-r--r--src/libstd/rt/task.rs33
-rw-r--r--src/libstd/rt/util.rs25
-rw-r--r--src/libstd/rt/uv/file.rs406
-rw-r--r--src/libstd/rt/uv/mod.rs22
-rw-r--r--src/libstd/rt/uv/uvio.rs487
-rw-r--r--src/libstd/rt/uv/uvll.rs183
-rw-r--r--src/libstd/run.rs2
-rw-r--r--src/libstd/select.rs4
-rw-r--r--src/libstd/std.rs2
-rw-r--r--src/libstd/str.rs448
-rw-r--r--src/libstd/task/mod.rs44
-rw-r--r--src/libstd/task/spawn.rs80
-rw-r--r--src/libstd/unstable/extfmt.rs2
-rw-r--r--src/libstd/unstable/finally.rs1
-rw-r--r--src/libstd/unstable/sync.rs34
-rw-r--r--src/libstd/vec.rs30
50 files changed, 2385 insertions, 890 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 120946ad161..d001e2c6970 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -255,8 +255,6 @@ pub mod raw {
         if capacity(*v) < n {
             let ptr: *mut *mut Box<Vec<()>> = transmute(v);
             let ty = intrinsics::get_tydesc::<T>();
-            // XXX transmute shouldn't be necessary
-            let ty = cast::transmute(ty);
             return reserve_raw(ty, ptr, n);
         }
     }
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index 98710c158e0..df2fe70ff0e 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -283,7 +283,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_with_ref_empty_fail() {
         let c_str = unsafe { CString::new(ptr::null(), false) };
         c_str.with_ref(|_| ());
@@ -306,7 +305,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))]
     fn test_to_c_str_fail() {
         use c_str::null_byte::cond;
 
diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs
index 9d1d6e65901..825d0147c80 100644
--- a/src/libstd/cast.rs
+++ b/src/libstd/cast.rs
@@ -66,7 +66,10 @@ pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
  *
  * # Example
  *
- *     assert!(transmute("L") == ~[76u8, 0u8]);
+ * ~~~ {.rust}
+ * let v: &[u8] = transmute("L");
+ * assert!(v == [76u8]);
+ * ~~~
  */
 #[inline]
 pub unsafe fn transmute<L, G>(thing: L) -> G {
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs
index 372effad61d..f9f5b66acb6 100644
--- a/src/libstd/cell.rs
+++ b/src/libstd/cell.rs
@@ -50,6 +50,12 @@ impl<T> Cell<T> {
         this.value.take_unwrap()
     }
 
+    /// Yields the value if the cell is full, or `None` if it is empty.
+    pub fn take_opt(&self) -> Option<T> {
+        let this = unsafe { transmute_mut(self) };
+        this.value.take()
+    }
+
     /// Returns the value, failing if the cell is full.
     pub fn put_back(&self, value: T) {
         let this = unsafe { transmute_mut(self) };
@@ -93,7 +99,6 @@ fn test_basic() {
 
 #[test]
 #[should_fail]
-#[ignore(cfg(windows))]
 fn test_take_empty() {
     let value_cell = Cell::new_empty::<~int>();
     value_cell.take();
@@ -101,7 +106,6 @@ fn test_take_empty() {
 
 #[test]
 #[should_fail]
-#[ignore(cfg(windows))]
 fn test_put_back_non_empty() {
     let value_cell = Cell::new(~10);
     value_cell.put_back(~20);
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index db8a17c0bd0..daf8c4afb07 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -12,33 +12,33 @@
 
 # The Formatting Module
 
-This module contains the runtime support for the `ifmt!` syntax extension. This
+This module contains the runtime support for the `format!` syntax extension. This
 macro is implemented in the compiler to emit calls to this module in order to
 format arguments at runtime into strings and streams.
 
 The functions contained in this module should not normally be used in everyday
-use cases of `ifmt!`. The assumptions made by these functions are unsafe for all
+use cases of `format!`. The assumptions made by these functions are unsafe for all
 inputs, and the compiler performs a large amount of validation on the arguments
-to `ifmt!` in order to ensure safety at runtime. While it is possible to call
+to `format!` in order to ensure safety at runtime. While it is possible to call
 these functions directly, it is not recommended to do so in the general case.
 
 ## Usage
 
-The `ifmt!` macro is intended to be familiar to those coming from C's
-printf/sprintf functions or Python's `str.format` function. In its current
-revision, the `ifmt!` macro returns a `~str` type which is the result of the
+The `format!` macro is intended to be familiar to those coming from C's
+printf/fprintf functions or Python's `str.format` function. In its current
+revision, the `format!` macro returns a `~str` type which is the result of the
 formatting. In the future it will also be able to pass in a stream to format
 arguments directly while performing minimal allocations.
 
-Some examples of the `ifmt!` extension are:
+Some examples of the `format!` extension are:
 
 ~~~{.rust}
-ifmt!("Hello")                  // => ~"Hello"
-ifmt!("Hello, {:s}!", "world")  // => ~"Hello, world!"
-ifmt!("The number is {:d}", 1)  // => ~"The number is 1"
-ifmt!("{}", ~[3, 4])            // => ~"~[3, 4]"
-ifmt!("{value}", value=4)       // => ~"4"
-ifmt!("{} {}", 1, 2)            // => ~"1 2"
+format!("Hello")                  // => ~"Hello"
+format!("Hello, {:s}!", "world")  // => ~"Hello, world!"
+format!("The number is {:d}", 1)  // => ~"The number is 1"
+format!("{}", ~[3, 4])            // => ~"~[3, 4]"
+format!("{value}", value=4)       // => ~"4"
+format!("{} {}", 1, 2)            // => ~"1 2"
 ~~~
 
 From these, you can see that the first argument is a format string. It is
@@ -62,7 +62,7 @@ format string, although it must always be referred to with the same type.
 ### Named parameters
 
 Rust itself does not have a Python-like equivalent of named parameters to a
-function, but the `ifmt!` macro is a syntax extension which allows it to
+function, but the `format!` macro is a syntax extension which allows it to
 leverage named parameters. Named parameters are listed at the end of the
 argument list and have the syntax:
 
@@ -146,7 +146,7 @@ helper methods.
 
 ## Internationalization
 
-The formatting syntax supported by the `ifmt!` extension supports
+The formatting syntax supported by the `format!` extension supports
 internationalization by providing "methods" which execute various different
 outputs depending on the input. The syntax and methods provided are similar to
 other internationalization systems, so again nothing should seem alien.
@@ -164,7 +164,7 @@ to reference the string value of the argument which was selected upon. As an
 example:
 
 ~~~
-ifmt!("{0, select, other{#}}", "hello") // => ~"hello"
+format!("{0, select, other{#}}", "hello") // => ~"hello"
 ~~~
 
 This example is the equivalent of `{0:s}` essentially.
@@ -399,7 +399,44 @@ pub trait Pointer { fn fmt(&Self, &mut Formatter); }
 #[allow(missing_doc)]
 pub trait Float { fn fmt(&Self, &mut Formatter); }
 
-/// The sprintf function takes a precompiled format string and a list of
+/// The `write` function takes an output stream, a precompiled format string,
+/// and a list of arguments. The arguments will be formatted according to the
+/// specified format string into the output stream provided.
+///
+/// See the documentation for `format` for why this function is unsafe and care
+/// should be taken if calling it manually.
+///
+/// Thankfully the rust compiler provides the macro `fmtf!` which will perform
+/// all of this validation at compile-time and provides a safe interface for
+/// invoking this function.
+///
+/// # Arguments
+///
+///   * output - the buffer to write output to
+///   * fmts - the precompiled format string to emit
+///   * args - the list of arguments to the format string. These are only the
+///            positional arguments (not named)
+///
+/// Note that this function assumes that there are enough arguments for the
+/// format string.
+pub unsafe fn write(output: &mut io::Writer,
+                    fmt: &[rt::Piece], args: &[Argument]) {
+    let mut formatter = Formatter {
+        flags: 0,
+        width: None,
+        precision: None,
+        buf: output,
+        align: parse::AlignUnknown,
+        fill: ' ',
+        args: args,
+        curarg: args.iter(),
+    };
+    for piece in fmt.iter() {
+        formatter.run(piece, None);
+    }
+}
+
+/// The format function takes a precompiled format string and a list of
 /// arguments, to return the resulting formatted string.
 ///
 /// This is currently an unsafe function because the types of all arguments
@@ -409,7 +446,7 @@ pub trait Float { fn fmt(&Self, &mut Formatter); }
 /// for formatting the right type value. Because of this, the function is marked
 /// as `unsafe` if this is being called manually.
 ///
-/// Thankfully the rust compiler provides the macro `ifmt!` which will perform
+/// Thankfully the rust compiler provides the macro `format!` which will perform
 /// all of this validation at compile-time and provides a safe interface for
 /// invoking this function.
 ///
@@ -421,24 +458,9 @@ pub trait Float { fn fmt(&Self, &mut Formatter); }
 ///
 /// Note that this function assumes that there are enough arguments for the
 /// format string.
-pub unsafe fn sprintf(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
-    let output = MemWriter::new();
-    {
-        let mut formatter = Formatter {
-            flags: 0,
-            width: None,
-            precision: None,
-            // FIXME(#8248): shouldn't need a transmute
-            buf: cast::transmute(&output as &io::Writer),
-            align: parse::AlignUnknown,
-            fill: ' ',
-            args: args,
-            curarg: args.iter(),
-        };
-        for piece in fmt.iter() {
-            formatter.run(piece, None);
-        }
-    }
+pub unsafe fn format(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
+    let mut output = MemWriter::new();
+    write(&mut output as &mut io::Writer, fmt, args);
     return str::from_bytes_owned(output.inner());
 }
 
@@ -446,7 +468,7 @@ impl<'self> Formatter<'self> {
 
     // First up is the collection of functions used to execute a format string
     // at runtime. This consumes all of the compile-time statics generated by
-    // the ifmt! syntax extension.
+    // the format! syntax extension.
 
     fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
         let setcount = |slot: &mut Option<uint>, cnt: &parse::Count| {
@@ -710,7 +732,7 @@ impl<'self> Formatter<'self> {
 }
 
 /// This is a function which calls are emitted to by the compiler itself to
-/// create the Argument structures that are passed into the `sprintf` function.
+/// create the Argument structures that are passed into the `format` function.
 #[doc(hidden)]
 pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter),
                        t: &'a T) -> Argument<'a> {
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 8f5a3728e95..2412ce9daf3 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -2017,7 +2017,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_read_buffer_too_small() {
         let path = &Path("tmp/lib-io-test-read-buffer-too-small.tmp");
         // ensure the file exists
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index c2d2e62a3c8..1af49ecd208 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -1592,6 +1592,21 @@ impl<A: Add<A, A> + Ord + Clone> Iterator<A> for RangeInclusive<A> {
             }
         }
     }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let (lo, hi) = self.range.size_hint();
+        if self.done {
+            (lo, hi)
+        } else {
+            let lo = lo.saturating_add(1);
+            let hi = match hi {
+                Some(x) => x.checked_add(&1),
+                None => None
+            };
+            (lo, hi)
+        }
+    }
 }
 
 impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for RangeInclusive<A> {
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index 4dbe61b0c49..5d6610e6b55 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -201,7 +201,6 @@ fn test_tls_overwrite_multiple_types() {
 
 #[test]
 #[should_fail]
-#[ignore(cfg(windows))]
 fn test_tls_cleanup_on_failure() {
     static str_key: Key<@~str> = &Key;
     static box_key: Key<@@()> = &Key;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 89c7b294512..5378a2c798d 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -27,8 +27,10 @@ macro_rules! rtdebug (
 
 macro_rules! rtassert (
     ( $arg:expr ) => ( {
-        if !$arg {
-            rtabort!("assertion failed: %s", stringify!($arg));
+        if ::rt::util::ENFORCE_SANITY {
+            if !$arg {
+                rtabort!("assertion failed: %s", stringify!($arg));
+            }
         }
     } )
 )
@@ -40,3 +42,39 @@ macro_rules! rtabort(
     } )
 )
 
+macro_rules! assert_once_ever(
+    ($( $msg:expr),+) => ( {
+        // FIXME(#8472) extra function should not be needed to hide unsafe
+        fn assert_once_ever() {
+            unsafe {
+                static mut already_happened: int = 0;
+                // Double-check lock to avoid a swap in the common case.
+                if already_happened != 0 ||
+                    ::unstable::intrinsics::atomic_xchg_relaxed(&mut already_happened, 1) != 0 {
+                        fail!(fmt!("assert_once_ever happened twice: %s", fmt!($($msg),+)));
+                }
+            }
+        }
+        assert_once_ever();
+    } )
+)
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn test_assert_once_ever_ok() {
+        assert_once_ever!("help i'm stuck in an");
+        assert_once_ever!("assertion error message");
+    }
+
+    #[test] #[ignore(cfg(windows))] #[should_fail]
+    fn test_assert_once_ever_fail() {
+        use task;
+
+        fn f() { assert_once_ever!("if you're seeing this... good!") }
+
+        // linked & watched, naturally
+        task::spawn(f);
+        task::spawn(f);
+    }
+}
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 4a7a5e32b32..e2218ce2736 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -919,7 +919,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_range_step_zero_step() {
         do range_step(0,10,0) |_i| { true };
     }
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 90a14503a8d..d81a2756ad8 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -638,14 +638,12 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     pub fn to_str_radix1() {
         100u.to_str_radix(1u);
     }
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     pub fn to_str_radix37() {
         100u.to_str_radix(37u);
     }
@@ -697,13 +695,11 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_range_step_zero_step_up() {
         do range_step(0,10,0) |_i| { true };
     }
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_range_step_zero_step_down() {
         do range_step(0,-10,0) |_i| { true };
     }
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 7faa98c2433..34c47d9f61e 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -479,7 +479,7 @@ mod tests {
         assert_eq!(y2, 5);
         assert!(y.is_none());
     }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
+    #[test] #[should_fail]
     fn test_option_too_much_dance() {
         let mut y = Some(util::NonCopyable);
         let _y2 = y.take_unwrap();
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 4e5a0e9b913..0b5f53dbf19 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -36,7 +36,6 @@ use iterator::range;
 use libc;
 use libc::{c_char, c_void, c_int, size_t};
 use libc::FILE;
-use local_data;
 use option::{Some, None};
 use os;
 use prelude::*;
@@ -1188,7 +1187,7 @@ unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
  * Returns a list of the command line arguments.
  */
 #[cfg(target_os = "macos")]
-pub fn real_args() -> ~[~str] {
+fn real_args() -> ~[~str] {
     #[fixed_stack_segment]; #[inline(never)];
 
     unsafe {
@@ -1201,7 +1200,7 @@ pub fn real_args() -> ~[~str] {
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "android")]
 #[cfg(target_os = "freebsd")]
-pub fn real_args() -> ~[~str] {
+fn real_args() -> ~[~str] {
     use rt;
 
     match rt::args::clone() {
@@ -1211,7 +1210,7 @@ pub fn real_args() -> ~[~str] {
 }
 
 #[cfg(windows)]
-pub fn real_args() -> ~[~str] {
+fn real_args() -> ~[~str] {
     #[fixed_stack_segment]; #[inline(never)];
 
     let mut nArgs: c_int = 0;
@@ -1261,28 +1260,10 @@ struct OverriddenArgs {
     val: ~[~str]
 }
 
-static overridden_arg_key: local_data::Key<@OverriddenArgs> = &local_data::Key;
-
 /// Returns the arguments which this program was started with (normally passed
 /// via the command line).
-///
-/// The return value of the function can be changed by invoking the
-/// `os::set_args` function.
 pub fn args() -> ~[~str] {
-    match local_data::get(overridden_arg_key, |k| k.map(|&k| *k)) {
-        None => real_args(),
-        Some(args) => args.val.clone()
-    }
-}
-
-/// For the current task, overrides the task-local cache of the arguments this
-/// program had when it started. These new arguments are only available to the
-/// current task via the `os::args` method.
-pub fn set_args(new_args: ~[~str]) {
-    let overridden_args = @OverriddenArgs {
-        val: new_args.clone()
-    };
-    local_data::set(overridden_arg_key, overridden_args);
+    real_args()
 }
 
 // FIXME #6100 we should really use an internal implementation of this - using
@@ -1770,7 +1751,7 @@ mod tests {
     use libc;
     use option::Some;
     use option;
-    use os::{env, getcwd, getenv, make_absolute, real_args};
+    use os::{env, getcwd, getenv, make_absolute, args};
     use os::{remove_file, setenv, unsetenv};
     use os;
     use path::Path;
@@ -1788,7 +1769,7 @@ mod tests {
 
     #[test]
     pub fn test_args() {
-        let a = real_args();
+        let a = args();
         assert!(a.len() >= 1);
     }
 
@@ -1815,7 +1796,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))]
     #[ignore]
     fn test_setenv_overwrite() {
         let n = make_rand_name();
@@ -1829,7 +1809,6 @@ mod tests {
     // Windows GetEnvironmentVariable requires some extra work to make sure
     // the buffer the variable is copied into is the right size
     #[test]
-    #[ignore(cfg(windows))]
     #[ignore]
     fn test_getenv_big() {
         let mut s = ~"";
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index c1163403423..12af303f33f 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -369,6 +369,47 @@ impl<T> Eq for *const T {
     fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
 }
 
+// Equality for extern "C" fn pointers
+#[cfg(not(test))]
+mod externfnpointers {
+    use cast;
+    use cmp::Eq;
+
+    impl<_R> Eq for extern "C" fn() -> _R {
+        #[inline]
+        fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
+            let self_: *() = unsafe { cast::transmute(*self) };
+            let other_: *() = unsafe { cast::transmute(*other) };
+            self_ == other_
+        }
+        #[inline]
+        fn ne(&self, other: &extern "C" fn() -> _R) -> bool {
+            !self.eq(other)
+        }
+    }
+    macro_rules! fnptreq(
+        ($($p:ident),*) => {
+            impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R {
+                #[inline]
+                fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
+                    let self_: *() = unsafe { cast::transmute(*self) };
+                    let other_: *() = unsafe { cast::transmute(*other) };
+                    self_ == other_
+                }
+                #[inline]
+                fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
+                    !self.eq(other)
+                }
+            }
+        }
+    )
+    fnptreq!(A)
+    fnptreq!(A,B)
+    fnptreq!(A,B,C)
+    fnptreq!(A,B,C,D)
+    fnptreq!(A,B,C,D,E)
+}
+
 // Comparison for pointers
 #[cfg(not(test))]
 impl<T> Ord for *const T {
@@ -670,7 +711,6 @@ pub mod ptr_tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_ptr_array_each_with_len_null_ptr() {
         unsafe {
             array_each_with_len(0 as **libc::c_char, 1, |e| {
@@ -680,7 +720,6 @@ pub mod ptr_tests {
     }
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_ptr_array_each_null_ptr() {
         unsafe {
             array_each(0 as **libc::c_char, |e| {
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index 7b10866207a..c7f3fd7740b 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -1007,7 +1007,6 @@ mod test {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_gen_int_from_fail() {
         let mut r = rng();
         r.gen_int_range(5, -2);
@@ -1024,7 +1023,6 @@ mod test {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_gen_uint_range_fail() {
         let mut r = rng();
         r.gen_uint_range(5u, 2u);
diff --git a/src/libstd/rand/distributions.rs b/src/libstd/rand/distributions.rs
index 67be7986c33..6d08b3c84bd 100644
--- a/src/libstd/rand/distributions.rs
+++ b/src/libstd/rand/distributions.rs
@@ -92,7 +92,7 @@ impl Rand for StandardNormal {
             let mut x = 1.0f64;
             let mut y = 0.0f64;
 
-            // XXX infinities?
+            // FIXME #7755: infinities?
             while -2.0 * y < x * x {
                 x = rng.gen::<f64>().ln() / ziggurat_tables::ZIG_NORM_R;
                 y = rng.gen::<f64>().ln();
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 743a47a812a..0218a0e7f3a 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -590,7 +590,7 @@ fn test_repr() {
     exact_test(&(~"he\u10f3llo"), "~\"he\\u10f3llo\"");
 
     exact_test(&(@10), "@10");
-    exact_test(&(@mut 10), "@10"); // FIXME: #4210: incorrect
+    exact_test(&(@mut 10), "@mut 10");
     exact_test(&((@mut 10, 2)), "(@mut 10, 2)");
     exact_test(&(~10), "~10");
     exact_test(&(&10), "&10");
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 71eae56c894..baaf3d44e79 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -17,8 +17,8 @@
 //! Only valid to call on linux. Mac and Windows use syscalls to
 //! discover the command line arguments.
 //!
-//! XXX: Would be nice for this to not exist.
-//! XXX: This has a lot of C glue for lack of globals.
+//! FIXME #7756: Would be nice for this to not exist.
+//! FIXME #7756: This has a lot of C glue for lack of globals.
 
 use option::Option;
 
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index 49cf8c239b7..bd83e286156 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -46,7 +46,7 @@ struct Packet<T> {
     payload: Option<T>,
 }
 
-/// A one-shot channel.
+// A one-shot channel.
 pub struct ChanOne<T> {
     void_packet: *mut Void,
     suppress_finalize: bool
@@ -125,7 +125,7 @@ impl<T> ChanOne<T> {
         unsafe {
 
             // Install the payload
-            assert!((*packet).payload.is_none());
+            rtassert!((*packet).payload.is_none());
             (*packet).payload = Some(val);
 
             // Atomically swap out the old state to figure out what
@@ -144,16 +144,8 @@ impl<T> ChanOne<T> {
             match oldstate {
                 STATE_BOTH => {
                     // Port is not waiting yet. Nothing to do
-                    do Local::borrow::<Scheduler, ()> |sched| {
-                        rtdebug!("non-rendezvous send");
-                        sched.metrics.non_rendezvous_sends += 1;
-                    }
                 }
                 STATE_ONE => {
-                    do Local::borrow::<Scheduler, ()> |sched| {
-                        rtdebug!("rendezvous send");
-                        sched.metrics.rendezvous_sends += 1;
-                    }
                     // Port has closed. Need to clean up.
                     let _packet: ~Packet<T> = cast::transmute(this.void_packet);
                     recvr_active = false;
@@ -251,7 +243,6 @@ impl<T> SelectInner for PortOne<T> {
                 STATE_BOTH => {
                     // Data has not been sent. Now we're blocked.
                     rtdebug!("non-rendezvous recv");
-                    sched.metrics.non_rendezvous_recvs += 1;
                     false
                 }
                 STATE_ONE => {
@@ -267,7 +258,6 @@ impl<T> SelectInner for PortOne<T> {
                     (*self.packet()).state.store(STATE_ONE, Relaxed);
 
                     rtdebug!("rendezvous recv");
-                    sched.metrics.rendezvous_recvs += 1;
 
                     // Channel is closed. Switch back and check the data.
                     // NB: We have to drop back into the scheduler event loop here
@@ -307,7 +297,7 @@ impl<T> SelectInner for PortOne<T> {
                         STATE_ONE  => true, // Lost the race. Data available.
                         same_ptr   => {
                             // We successfully unblocked our task pointer.
-                            assert!(task_as_state == same_ptr);
+                            rtassert!(task_as_state == same_ptr);
                             let handle = BlockedTask::cast_from_uint(task_as_state);
                             // Because we are already awake, the handle we
                             // gave to this port shall already be empty.
@@ -341,7 +331,8 @@ impl<T> SelectPortInner<T> for PortOne<T> {
         unsafe {
             // See corresponding store() above in block_on for rationale.
             // FIXME(#8130) This can happen only in test builds.
-            assert!((*packet).state.load(Relaxed) == STATE_ONE);
+            // This load is not required for correctness and may be compiled out.
+            rtassert!((*packet).state.load(Relaxed) == STATE_ONE);
 
             let payload = (*packet).payload.take();
 
@@ -387,7 +378,7 @@ impl<T> Drop for ChanOne<T> {
                 },
                 task_as_state => {
                     // The port is blocked waiting for a message we will never send. Wake it.
-                    assert!((*this.packet()).payload.is_none());
+                    rtassert!((*this.packet()).payload.is_none());
                     let recvr = BlockedTask::cast_from_uint(task_as_state);
                     do recvr.wake().map_move |woken_task| {
                         Scheduler::run_task(woken_task);
@@ -499,13 +490,14 @@ impl<T> GenericPort<T> for Port<T> {
     }
 
     fn try_recv(&self) -> Option<T> {
-        let pone = self.next.take();
-        match pone.try_recv() {
-            Some(StreamPayload { val, next }) => {
-                self.next.put_back(next);
-                Some(val)
+        do self.next.take_opt().map_move_default(None) |pone| {
+            match pone.try_recv() {
+                Some(StreamPayload { val, next }) => {
+                    self.next.put_back(next);
+                    Some(val)
+                }
+                None => None
             }
-            None => None
         }
     }
 }
@@ -681,7 +673,7 @@ impl<T> Clone for SharedPort<T> {
     }
 }
 
-// XXX: Need better name
+// FIXME #7760: Need better name
 type MegaPipe<T> = (SharedPort<T>, SharedChan<T>);
 
 pub fn megapipe<T: Send>() -> MegaPipe<T> {
@@ -1027,9 +1019,8 @@ mod test {
     fn shared_port_stress() {
         if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
         do run_in_mt_newsched_task {
-            // XXX: Removing these type annotations causes an ICE
-            let (end_port, end_chan) = stream::<()>();
-            let (port, chan) = stream::<()>();
+            let (end_port, end_chan) = stream();
+            let (port, chan) = stream();
             let end_chan = SharedChan::new(end_chan);
             let port = SharedPort::new(port);
             let total = stress_factor() + 100;
diff --git a/src/libstd/rt/context.rs b/src/libstd/rt/context.rs
index 890ad061a68..5aaddc68383 100644
--- a/src/libstd/rt/context.rs
+++ b/src/libstd/rt/context.rs
@@ -14,10 +14,10 @@ use libc::c_void;
 use cast::{transmute, transmute_mut_unsafe,
            transmute_region, transmute_mut_region};
 
-// XXX: Registers is boxed so that it is 16-byte aligned, for storing
+// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
 // SSE regs.  It would be marginally better not to do this. In C++ we
 // use an attribute on a struct.
-// XXX: It would be nice to define regs as `~Option<Registers>` since
+// FIXME #7761: It would be nice to define regs as `~Option<Registers>` since
 // the registers are sometimes empty, but the discriminant would
 // then misalign the regs again.
 pub struct Context {
@@ -37,7 +37,7 @@ impl Context {
 
     /// Create a new context that will resume execution by running ~fn()
     pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
-        // XXX: Putting main into a ~ so it's a thin pointer and can
+        // FIXME #7767: Putting main into a ~ so it's a thin pointer and can
         // be passed to the spawn function.  Another unfortunate
         // allocation
         let start = ~start;
@@ -206,7 +206,7 @@ fn align_down(sp: *mut uint) -> *mut uint {
     }
 }
 
-// XXX: ptr::offset is positive ints only
+// ptr::mut_offset is positive ints only
 #[inline]
 pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
     use std::sys::size_of;
diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs
index d136ddc0fdf..e82662c6b0d 100644
--- a/src/libstd/rt/io/extensions.rs
+++ b/src/libstd/rt/io/extensions.rs
@@ -68,209 +68,209 @@ pub trait ReaderByteConversions {
     /// Reads `n` little-endian unsigned integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_le_uint_n(&mut self, nbytes: uint) -> u64;
+    fn read_le_uint_n_(&mut self, nbytes: uint) -> u64;
 
     /// Reads `n` little-endian signed integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_le_int_n(&mut self, nbytes: uint) -> i64;
+    fn read_le_int_n_(&mut self, nbytes: uint) -> i64;
 
     /// Reads `n` big-endian unsigned integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_be_uint_n(&mut self, nbytes: uint) -> u64;
+    fn read_be_uint_n_(&mut self, nbytes: uint) -> u64;
 
     /// Reads `n` big-endian signed integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_be_int_n(&mut self, nbytes: uint) -> i64;
+    fn read_be_int_n_(&mut self, nbytes: uint) -> i64;
 
     /// Reads a little-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_le_uint(&mut self) -> uint;
+    fn read_le_uint_(&mut self) -> uint;
 
     /// Reads a little-endian integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_le_int(&mut self) -> int;
+    fn read_le_int_(&mut self) -> int;
 
     /// Reads a big-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_be_uint(&mut self) -> uint;
+    fn read_be_uint_(&mut self) -> uint;
 
     /// Reads a big-endian integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_be_int(&mut self) -> int;
+    fn read_be_int_(&mut self) -> int;
 
     /// Reads a big-endian `u64`.
     ///
     /// `u64`s are 8 bytes long.
-    fn read_be_u64(&mut self) -> u64;
+    fn read_be_u64_(&mut self) -> u64;
 
     /// Reads a big-endian `u32`.
     ///
     /// `u32`s are 4 bytes long.
-    fn read_be_u32(&mut self) -> u32;
+    fn read_be_u32_(&mut self) -> u32;
 
     /// Reads a big-endian `u16`.
     ///
     /// `u16`s are 2 bytes long.
-    fn read_be_u16(&mut self) -> u16;
+    fn read_be_u16_(&mut self) -> u16;
 
     /// Reads a big-endian `i64`.
     ///
     /// `i64`s are 8 bytes long.
-    fn read_be_i64(&mut self) -> i64;
+    fn read_be_i64_(&mut self) -> i64;
 
     /// Reads a big-endian `i32`.
     ///
     /// `i32`s are 4 bytes long.
-    fn read_be_i32(&mut self) -> i32;
+    fn read_be_i32_(&mut self) -> i32;
 
     /// Reads a big-endian `i16`.
     ///
     /// `i16`s are 2 bytes long.
-    fn read_be_i16(&mut self) -> i16;
+    fn read_be_i16_(&mut self) -> i16;
 
     /// Reads a big-endian `f64`.
     ///
     /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
-    fn read_be_f64(&mut self) -> f64;
+    fn read_be_f64_(&mut self) -> f64;
 
     /// Reads a big-endian `f32`.
     ///
     /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
-    fn read_be_f32(&mut self) -> f32;
+    fn read_be_f32_(&mut self) -> f32;
 
     /// Reads a little-endian `u64`.
     ///
     /// `u64`s are 8 bytes long.
-    fn read_le_u64(&mut self) -> u64;
+    fn read_le_u64_(&mut self) -> u64;
 
     /// Reads a little-endian `u32`.
     ///
     /// `u32`s are 4 bytes long.
-    fn read_le_u32(&mut self) -> u32;
+    fn read_le_u32_(&mut self) -> u32;
 
     /// Reads a little-endian `u16`.
     ///
     /// `u16`s are 2 bytes long.
-    fn read_le_u16(&mut self) -> u16;
+    fn read_le_u16_(&mut self) -> u16;
 
     /// Reads a little-endian `i64`.
     ///
     /// `i64`s are 8 bytes long.
-    fn read_le_i64(&mut self) -> i64;
+    fn read_le_i64_(&mut self) -> i64;
 
     /// Reads a little-endian `i32`.
     ///
     /// `i32`s are 4 bytes long.
-    fn read_le_i32(&mut self) -> i32;
+    fn read_le_i32_(&mut self) -> i32;
 
     /// Reads a little-endian `i16`.
     ///
     /// `i16`s are 2 bytes long.
-    fn read_le_i16(&mut self) -> i16;
+    fn read_le_i16_(&mut self) -> i16;
 
     /// Reads a little-endian `f64`.
     ///
     /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
-    fn read_le_f64(&mut self) -> f64;
+    fn read_le_f64_(&mut self) -> f64;
 
     /// Reads a little-endian `f32`.
     ///
     /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
-    fn read_le_f32(&mut self) -> f32;
+    fn read_le_f32_(&mut self) -> f32;
 
     /// Read a u8.
     ///
     /// `u8`s are 1 byte.
-    fn read_u8(&mut self) -> u8;
+    fn read_u8_(&mut self) -> u8;
 
     /// Read an i8.
     ///
     /// `i8`s are 1 byte.
-    fn read_i8(&mut self) -> i8;
+    fn read_i8_(&mut self) -> i8;
 
 }
 
 pub trait WriterByteConversions {
     /// Write the result of passing n through `int::to_str_bytes`.
-    fn write_int(&mut self, n: int);
+    fn write_int_(&mut self, n: int);
 
     /// Write the result of passing n through `uint::to_str_bytes`.
-    fn write_uint(&mut self, n: uint);
+    fn write_uint_(&mut self, n: uint);
 
     /// Write a little-endian uint (number of bytes depends on system).
-    fn write_le_uint(&mut self, n: uint);
+    fn write_le_uint_(&mut self, n: uint);
 
     /// Write a little-endian int (number of bytes depends on system).
-    fn write_le_int(&mut self, n: int);
+    fn write_le_int_(&mut self, n: int);
 
     /// Write a big-endian uint (number of bytes depends on system).
-    fn write_be_uint(&mut self, n: uint);
+    fn write_be_uint_(&mut self, n: uint);
 
     /// Write a big-endian int (number of bytes depends on system).
-    fn write_be_int(&mut self, n: int);
+    fn write_be_int_(&mut self, n: int);
 
     /// Write a big-endian u64 (8 bytes).
     fn write_be_u64_(&mut self, n: u64);
 
     /// Write a big-endian u32 (4 bytes).
-    fn write_be_u32(&mut self, n: u32);
+    fn write_be_u32_(&mut self, n: u32);
 
     /// Write a big-endian u16 (2 bytes).
-    fn write_be_u16(&mut self, n: u16);
+    fn write_be_u16_(&mut self, n: u16);
 
     /// Write a big-endian i64 (8 bytes).
-    fn write_be_i64(&mut self, n: i64);
+    fn write_be_i64_(&mut self, n: i64);
 
     /// Write a big-endian i32 (4 bytes).
-    fn write_be_i32(&mut self, n: i32);
+    fn write_be_i32_(&mut self, n: i32);
 
     /// Write a big-endian i16 (2 bytes).
-    fn write_be_i16(&mut self, n: i16);
+    fn write_be_i16_(&mut self, n: i16);
 
     /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
-    fn write_be_f64(&mut self, f: f64);
+    fn write_be_f64_(&mut self, f: f64);
 
     /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
-    fn write_be_f32(&mut self, f: f32);
+    fn write_be_f32_(&mut self, f: f32);
 
     /// Write a little-endian u64 (8 bytes).
     fn write_le_u64_(&mut self, n: u64);
 
     /// Write a little-endian u32 (4 bytes).
-    fn write_le_u32(&mut self, n: u32);
+    fn write_le_u32_(&mut self, n: u32);
 
     /// Write a little-endian u16 (2 bytes).
-    fn write_le_u16(&mut self, n: u16);
+    fn write_le_u16_(&mut self, n: u16);
 
     /// Write a little-endian i64 (8 bytes).
-    fn write_le_i64(&mut self, n: i64);
+    fn write_le_i64_(&mut self, n: i64);
 
     /// Write a little-endian i32 (4 bytes).
-    fn write_le_i32(&mut self, n: i32);
+    fn write_le_i32_(&mut self, n: i32);
 
     /// Write a little-endian i16 (2 bytes).
-    fn write_le_i16(&mut self, n: i16);
+    fn write_le_i16_(&mut self, n: i16);
 
     /// Write a little-endian IEEE754 double-precision floating-point
     /// (8 bytes).
-    fn write_le_f64(&mut self, f: f64);
+    fn write_le_f64_(&mut self, f: f64);
 
     /// Write a little-endian IEEE754 single-precision floating-point
     /// (4 bytes).
-    fn write_le_f32(&mut self, f: f32);
+    fn write_le_f32_(&mut self, f: f32);
 
     /// Write a u8 (1 byte).
-    fn write_u8(&mut self, n: u8);
+    fn write_u8_(&mut self, n: u8);
 
     /// Write a i8 (1 byte).
-    fn write_i8(&mut self, n: i8);
+    fn write_i8_(&mut self, n: i8);
 }
 
 impl<T: Reader> ReaderUtil for T {
@@ -340,136 +340,136 @@ impl<T: Reader> ReaderUtil for T {
 }
 
 impl<T: Reader> ReaderByteConversions for T {
-    fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
+    fn read_le_uint_n_(&mut self, nbytes: uint) -> u64 {
         assert!(nbytes > 0 && nbytes <= 8);
 
         let mut val = 0u64;
         let mut pos = 0;
         let mut i = nbytes;
         while i > 0 {
-            val += (self.read_u8() as u64) << pos;
+            val += (self.read_u8_() as u64) << pos;
             pos += 8;
             i -= 1;
         }
         val
     }
 
-    fn read_le_int_n(&mut self, nbytes: uint) -> i64 {
-        extend_sign(self.read_le_uint_n(nbytes), nbytes)
+    fn read_le_int_n_(&mut self, nbytes: uint) -> i64 {
+        extend_sign(self.read_le_uint_n_(nbytes), nbytes)
     }
 
-    fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
+    fn read_be_uint_n_(&mut self, nbytes: uint) -> u64 {
         assert!(nbytes > 0 && nbytes <= 8);
 
         let mut val = 0u64;
         let mut i = nbytes;
         while i > 0 {
             i -= 1;
-            val += (self.read_u8() as u64) << i * 8;
+            val += (self.read_u8_() as u64) << i * 8;
         }
         val
     }
 
-    fn read_be_int_n(&mut self, nbytes: uint) -> i64 {
-        extend_sign(self.read_be_uint_n(nbytes), nbytes)
+    fn read_be_int_n_(&mut self, nbytes: uint) -> i64 {
+        extend_sign(self.read_be_uint_n_(nbytes), nbytes)
     }
 
-    fn read_le_uint(&mut self) -> uint {
-        self.read_le_uint_n(uint::bytes) as uint
+    fn read_le_uint_(&mut self) -> uint {
+        self.read_le_uint_n_(uint::bytes) as uint
     }
 
-    fn read_le_int(&mut self) -> int {
-        self.read_le_int_n(int::bytes) as int
+    fn read_le_int_(&mut self) -> int {
+        self.read_le_int_n_(int::bytes) as int
     }
 
-    fn read_be_uint(&mut self) -> uint {
-        self.read_be_uint_n(uint::bytes) as uint
+    fn read_be_uint_(&mut self) -> uint {
+        self.read_be_uint_n_(uint::bytes) as uint
     }
 
-    fn read_be_int(&mut self) -> int {
-        self.read_be_int_n(int::bytes) as int
+    fn read_be_int_(&mut self) -> int {
+        self.read_be_int_n_(int::bytes) as int
     }
 
-    fn read_be_u64(&mut self) -> u64 {
-        self.read_be_uint_n(8) as u64
+    fn read_be_u64_(&mut self) -> u64 {
+        self.read_be_uint_n_(8) as u64
     }
 
-    fn read_be_u32(&mut self) -> u32 {
-        self.read_be_uint_n(4) as u32
+    fn read_be_u32_(&mut self) -> u32 {
+        self.read_be_uint_n_(4) as u32
     }
 
-    fn read_be_u16(&mut self) -> u16 {
-        self.read_be_uint_n(2) as u16
+    fn read_be_u16_(&mut self) -> u16 {
+        self.read_be_uint_n_(2) as u16
     }
 
-    fn read_be_i64(&mut self) -> i64 {
-        self.read_be_int_n(8) as i64
+    fn read_be_i64_(&mut self) -> i64 {
+        self.read_be_int_n_(8) as i64
     }
 
-    fn read_be_i32(&mut self) -> i32 {
-        self.read_be_int_n(4) as i32
+    fn read_be_i32_(&mut self) -> i32 {
+        self.read_be_int_n_(4) as i32
     }
 
-    fn read_be_i16(&mut self) -> i16 {
-        self.read_be_int_n(2) as i16
+    fn read_be_i16_(&mut self) -> i16 {
+        self.read_be_int_n_(2) as i16
     }
 
-    fn read_be_f64(&mut self) -> f64 {
+    fn read_be_f64_(&mut self) -> f64 {
         unsafe {
-            cast::transmute::<u64, f64>(self.read_be_u64())
+            cast::transmute::<u64, f64>(self.read_be_u64_())
         }
     }
 
-    fn read_be_f32(&mut self) -> f32 {
+    fn read_be_f32_(&mut self) -> f32 {
         unsafe {
-            cast::transmute::<u32, f32>(self.read_be_u32())
+            cast::transmute::<u32, f32>(self.read_be_u32_())
         }
     }
 
-    fn read_le_u64(&mut self) -> u64 {
-        self.read_le_uint_n(8) as u64
+    fn read_le_u64_(&mut self) -> u64 {
+        self.read_le_uint_n_(8) as u64
     }
 
-    fn read_le_u32(&mut self) -> u32 {
-        self.read_le_uint_n(4) as u32
+    fn read_le_u32_(&mut self) -> u32 {
+        self.read_le_uint_n_(4) as u32
     }
 
-    fn read_le_u16(&mut self) -> u16 {
-        self.read_le_uint_n(2) as u16
+    fn read_le_u16_(&mut self) -> u16 {
+        self.read_le_uint_n_(2) as u16
     }
 
-    fn read_le_i64(&mut self) -> i64 {
-        self.read_le_int_n(8) as i64
+    fn read_le_i64_(&mut self) -> i64 {
+        self.read_le_int_n_(8) as i64
     }
 
-    fn read_le_i32(&mut self) -> i32 {
-        self.read_le_int_n(4) as i32
+    fn read_le_i32_(&mut self) -> i32 {
+        self.read_le_int_n_(4) as i32
     }
 
-    fn read_le_i16(&mut self) -> i16 {
-        self.read_le_int_n(2) as i16
+    fn read_le_i16_(&mut self) -> i16 {
+        self.read_le_int_n_(2) as i16
     }
 
-    fn read_le_f64(&mut self) -> f64 {
+    fn read_le_f64_(&mut self) -> f64 {
         unsafe {
-            cast::transmute::<u64, f64>(self.read_le_u64())
+            cast::transmute::<u64, f64>(self.read_le_u64_())
         }
     }
 
-    fn read_le_f32(&mut self) -> f32 {
+    fn read_le_f32_(&mut self) -> f32 {
         unsafe {
-            cast::transmute::<u32, f32>(self.read_le_u32())
+            cast::transmute::<u32, f32>(self.read_le_u32_())
         }
     }
 
-    fn read_u8(&mut self) -> u8 {
+    fn read_u8_(&mut self) -> u8 {
         match self.read_byte() {
             Some(b) => b as u8,
             None => 0
         }
     }
 
-    fn read_i8(&mut self) -> i8 {
+    fn read_i8_(&mut self) -> i8 {
         match self.read_byte() {
             Some(b) => b as i8,
             None => 0
@@ -479,27 +479,27 @@ impl<T: Reader> ReaderByteConversions for T {
 }
 
 impl<T: Writer> WriterByteConversions for T {
-    fn write_int(&mut self, n: int) {
+    fn write_int_(&mut self, n: int) {
         int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
     }
 
-    fn write_uint(&mut self, n: uint) {
+    fn write_uint_(&mut self, n: uint) {
         uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
     }
 
-    fn write_le_uint(&mut self, n: uint) {
+    fn write_le_uint_(&mut self, n: uint) {
         u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
     }
 
-    fn write_le_int(&mut self, n: int) {
+    fn write_le_int_(&mut self, n: int) {
         u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v))
     }
 
-    fn write_be_uint(&mut self, n: uint) {
+    fn write_be_uint_(&mut self, n: uint) {
         u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v))
     }
 
-    fn write_be_int(&mut self, n: int) {
+    fn write_be_int_(&mut self, n: int) {
         u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v))
     }
 
@@ -507,35 +507,35 @@ impl<T: Writer> WriterByteConversions for T {
         u64_to_be_bytes(n, 8u, |v| self.write(v))
     }
 
-    fn write_be_u32(&mut self, n: u32) {
+    fn write_be_u32_(&mut self, n: u32) {
         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
     }
 
-    fn write_be_u16(&mut self, n: u16) {
+    fn write_be_u16_(&mut self, n: u16) {
         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
     }
 
-    fn write_be_i64(&mut self, n: i64) {
+    fn write_be_i64_(&mut self, n: i64) {
         u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
     }
 
-    fn write_be_i32(&mut self, n: i32) {
+    fn write_be_i32_(&mut self, n: i32) {
         u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
     }
 
-    fn write_be_i16(&mut self, n: i16) {
+    fn write_be_i16_(&mut self, n: i16) {
         u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
     }
 
-    fn write_be_f64(&mut self, f: f64) {
+    fn write_be_f64_(&mut self, f: f64) {
         unsafe {
             self.write_be_u64_(cast::transmute(f))
         }
     }
 
-    fn write_be_f32(&mut self, f: f32) {
+    fn write_be_f32_(&mut self, f: f32) {
         unsafe {
-            self.write_be_u32(cast::transmute(f))
+            self.write_be_u32_(cast::transmute(f))
         }
     }
 
@@ -543,43 +543,43 @@ impl<T: Writer> WriterByteConversions for T {
         u64_to_le_bytes(n, 8u, |v| self.write(v))
     }
 
-    fn write_le_u32(&mut self, n: u32) {
+    fn write_le_u32_(&mut self, n: u32) {
         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
     }
 
-    fn write_le_u16(&mut self, n: u16) {
+    fn write_le_u16_(&mut self, n: u16) {
         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
     }
 
-    fn write_le_i64(&mut self, n: i64) {
+    fn write_le_i64_(&mut self, n: i64) {
         u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
     }
 
-    fn write_le_i32(&mut self, n: i32) {
+    fn write_le_i32_(&mut self, n: i32) {
         u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
     }
 
-    fn write_le_i16(&mut self, n: i16) {
+    fn write_le_i16_(&mut self, n: i16) {
         u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
     }
 
-    fn write_le_f64(&mut self, f: f64) {
+    fn write_le_f64_(&mut self, f: f64) {
         unsafe {
             self.write_le_u64_(cast::transmute(f))
         }
     }
 
-    fn write_le_f32(&mut self, f: f32) {
+    fn write_le_f32_(&mut self, f: f32) {
         unsafe {
-            self.write_le_u32(cast::transmute(f))
+            self.write_le_u32_(cast::transmute(f))
         }
     }
 
-    fn write_u8(&mut self, n: u8) {
+    fn write_u8_(&mut self, n: u8) {
         self.write([n])
     }
 
-    fn write_i8(&mut self, n: i8) {
+    fn write_i8_(&mut self, n: i8) {
         self.write([n as u8])
     }
 }
@@ -594,7 +594,7 @@ mod test {
     use super::ReaderUtil;
     use option::{Some, None};
     use cell::Cell;
-    use rt::io::mem::MemReader;
+    use rt::io::mem::{MemReader, MemWriter};
     use rt::io::mock::MockReader;
     use rt::io::{read_error, placeholder_error};
 
@@ -751,7 +751,6 @@ mod test {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn push_bytes_fail_reset_len() {
         // push_bytes unsafely sets the vector length. This is testing that
         // upon failure the length is reset correctly.
@@ -806,7 +805,6 @@ mod test {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn read_to_end_error() {
         let mut reader = MockReader::new();
         let count = Cell::new(0);
@@ -827,51 +825,51 @@ mod test {
         assert!(buf == ~[10, 11]);
     }
 
-    // XXX: Some problem with resolve here
-    /*#[test]
-    fn test_read_write_le() {
-        let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
+    #[test]
+    fn test_read_write_le_mem() {
+        let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
 
         let mut writer = MemWriter::new();
-        for uints.each |i| {
-            writer.write_le_u64(*i);
+        for i in uints.iter() {
+            writer.write_le_u64_(*i);
         }
 
         let mut reader = MemReader::new(writer.inner());
-        for uints.each |i| {
-            assert!(reader.read_le_u64() == *i);
+        for i in uints.iter() {
+            assert!(reader.read_le_u64_() == *i);
         }
     }
 
+
     #[test]
     fn test_read_write_be() {
-        let uints = [0, 1, 2, 42, 10_123, 100_123_456, u64::max_value];
+        let uints = [0, 1, 2, 42, 10_123, 100_123_456, ::u64::max_value];
 
         let mut writer = MemWriter::new();
-        for uints.each |i| {
-            writer.write_be_u64(*i);
+        for i in uints.iter() {
+            writer.write_be_u64_(*i);
         }
 
         let mut reader = MemReader::new(writer.inner());
-        for uints.each |i| {
-            assert!(reader.read_be_u64() == *i);
+        for i in uints.iter() {
+            assert!(reader.read_be_u64_() == *i);
         }
     }
 
     #[test]
     fn test_read_be_int_n() {
-        let ints = [i32::min_value, -123456, -42, -5, 0, 1, i32::max_value];
+        let ints = [::i32::min_value, -123456, -42, -5, 0, 1, ::i32::max_value];
 
         let mut writer = MemWriter::new();
-        for ints.each |i| {
-            writer.write_be_i32(*i);
+        for i in ints.iter() {
+            writer.write_be_i32_(*i);
         }
 
         let mut reader = MemReader::new(writer.inner());
-        for ints.each |i| {
+        for i in ints.iter() {
             // this tests that the sign extension is working
             // (comparing the values as i32 would not test this)
-            assert!(reader.read_be_int_n(4) == *i as i64);
+            assert!(reader.read_be_int_n_(4) == *i as i64);
         }
     }
 
@@ -884,7 +882,7 @@ mod test {
         writer.write(buf);
 
         let mut reader = MemReader::new(writer.inner());
-        let f = reader.read_be_f32();
+        let f = reader.read_be_f32_();
         assert!(f == 8.1250);
     }
 
@@ -893,12 +891,12 @@ mod test {
         let f:f32 = 8.1250;
 
         let mut writer = MemWriter::new();
-        writer.write_be_f32(f);
-        writer.write_le_f32(f);
+        writer.write_be_f32_(f);
+        writer.write_le_f32_(f);
 
         let mut reader = MemReader::new(writer.inner());
-        assert!(reader.read_be_f32() == 8.1250);
-        assert!(reader.read_le_f32() == 8.1250);
-    }*/
+        assert!(reader.read_be_f32_() == 8.1250);
+        assert!(reader.read_le_f32_() == 8.1250);
+    }
 
 }
diff --git a/src/libstd/rt/io/file.rs b/src/libstd/rt/io/file.rs
index a99f5da032c..65db76d5ef7 100644
--- a/src/libstd/rt/io/file.rs
+++ b/src/libstd/rt/io/file.rs
@@ -11,69 +11,332 @@
 use prelude::*;
 use super::support::PathLike;
 use super::{Reader, Writer, Seek};
-use super::SeekStyle;
+use super::{SeekSet, SeekCur, SeekEnd, SeekStyle};
+use rt::rtio::{RtioFileStream, IoFactory, IoFactoryObject};
+use rt::io::{io_error, read_error, EndOfFile,
+             FileMode, FileAccess, Open, Read, Create, ReadWrite};
+use rt::local::Local;
+use rt::test::*;
 
-/// # XXX
-/// * Ugh, this is ridiculous. What is the best way to represent these options?
-enum FileMode {
-    /// Opens an existing file. IoError if file does not exist.
-    Open,
-    /// Creates a file. IoError if file exists.
-    Create,
-    /// Opens an existing file or creates a new one.
-    OpenOrCreate,
-    /// Opens an existing file or creates a new one, positioned at EOF.
-    Append,
-    /// Opens an existing file, truncating it to 0 bytes.
-    Truncate,
-    /// Opens an existing file or creates a new one, truncating it to 0 bytes.
-    CreateOrTruncate,
+/// Open a file for reading/writing, as indicated by `path`.
+pub fn open<P: PathLike>(path: &P,
+                         mode: FileMode,
+                         access: FileAccess
+                        ) -> Option<FileStream> {
+    let open_result = unsafe {
+        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        (*io).fs_open(path, mode, access)
+    };
+    match open_result {
+        Ok(fd) => Some(FileStream {
+            fd: fd,
+            last_nread: -1
+        }),
+        Err(ioerr) => {
+            io_error::cond.raise(ioerr);
+            None
+        }
+    }
 }
 
-enum FileAccess {
-    Read,
-    Write,
-    ReadWrite
+/// Unlink (remove) a file from the filesystem, as indicated
+/// by `path`.
+pub fn unlink<P: PathLike>(path: &P) {
+    let unlink_result = unsafe {
+        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        (*io).fs_unlink(path)
+    };
+    match unlink_result {
+        Ok(_) => (),
+        Err(ioerr) => {
+            io_error::cond.raise(ioerr);
+        }
+    }
 }
 
-pub struct FileStream;
+/// Abstraction representing *positional* access to a file. In this case,
+/// *positional* refers to it keeping an encounter *cursor* of where in the
+/// file a subsequent `read` or `write` will begin from. Users of a `FileStream`
+/// can `seek` to move the cursor to a given location *within the bounds of the
+/// file* and can ask to have the `FileStream` `tell` them the location, in
+/// bytes, of the cursor.
+///
+/// This abstraction is roughly modeled on the access workflow as represented
+/// by `open(2)`, `read(2)`, `write(2)` and friends.
+///
+/// The `open` and `unlink` static methods are provided to manage creation/removal
+/// of files. All other methods operatin on an instance of `FileStream`.
+pub struct FileStream {
+    fd: ~RtioFileStream,
+    last_nread: int,
+}
 
 impl FileStream {
-    pub fn open<P: PathLike>(_path: &P,
-                             _mode: FileMode,
-                             _access: FileAccess
-                            ) -> Option<FileStream> {
-        fail!()
-    }
 }
 
 impl Reader for FileStream {
-    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> {
-        fail!()
+    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+        match self.fd.read(buf) {
+            Ok(read) => {
+                self.last_nread = read;
+                match read {
+                    0 => None,
+                    _ => Some(read as uint)
+                }
+            },
+            Err(ioerr) => {
+                // EOF is indicated by returning None
+                if ioerr.kind != EndOfFile {
+                    read_error::cond.raise(ioerr);
+                }
+                return None;
+            }
+        }
     }
 
     fn eof(&mut self) -> bool {
-        fail!()
+        self.last_nread == 0
     }
 }
 
 impl Writer for FileStream {
-    fn write(&mut self, _v: &[u8]) { fail!() }
+    fn write(&mut self, buf: &[u8]) {
+        match self.fd.write(buf) {
+            Ok(_) => (),
+            Err(ioerr) => {
+                io_error::cond.raise(ioerr);
+            }
+        }
+    }
 
-    fn flush(&mut self) { fail!() }
+    fn flush(&mut self) {
+        match self.fd.flush() {
+            Ok(_) => (),
+            Err(ioerr) => {
+                read_error::cond.raise(ioerr);
+            }
+        }
+    }
 }
 
 impl Seek for FileStream {
-    fn tell(&self) -> u64 { fail!() }
+    fn tell(&self) -> u64 {
+        let res = self.fd.tell();
+        match res {
+            Ok(cursor) => cursor,
+            Err(ioerr) => {
+                read_error::cond.raise(ioerr);
+                return -1;
+            }
+        }
+    }
+
+    fn seek(&mut self, pos: i64, style: SeekStyle) {
+        match self.fd.seek(pos, style) {
+            Ok(_) => {
+                // successful seek resets EOF indicator
+                self.last_nread = -1;
+                ()
+            },
+            Err(ioerr) => {
+                read_error::cond.raise(ioerr);
+            }
+        }
+    }
+}
 
-    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+fn file_test_smoke_test_impl() {
+    do run_in_newsched_task {
+        let message = "it's alright. have a good time";
+        let filename = &Path("./tmp/file_rt_io_file_test.txt");
+        {
+            let mut write_stream = open(filename, Create, ReadWrite).unwrap();
+            write_stream.write(message.as_bytes());
+        }
+        {
+            use str;
+            let mut read_stream = open(filename, Open, Read).unwrap();
+            let mut read_buf = [0, .. 1028];
+            let read_str = match read_stream.read(read_buf).unwrap() {
+                -1|0 => fail!("shouldn't happen"),
+                n => str::from_bytes(read_buf.slice_to(n))
+            };
+            assert!(read_str == message.to_owned());
+        }
+        unlink(filename);
+    }
 }
 
 #[test]
-#[ignore]
-fn super_simple_smoke_test_lets_go_read_some_files_and_have_a_good_time() {
-    let message = "it's alright. have a good time";
-    let filename = &Path("test.txt");
-    let mut outstream = FileStream::open(filename, Create, Read).unwrap();
-    outstream.write(message.as_bytes());
+fn file_test_io_smoke_test() {
+    file_test_smoke_test_impl();
+}
+
+fn file_test_invalid_path_opened_without_create_should_raise_condition_impl() {
+    do run_in_newsched_task {
+        let filename = &Path("./tmp/file_that_does_not_exist.txt");
+        let mut called = false;
+        do io_error::cond.trap(|_| {
+            called = true;
+        }).inside {
+            let result = open(filename, Open, Read);
+            assert!(result.is_none());
+        }
+        assert!(called);
+    }
+}
+#[test]
+fn file_test_io_invalid_path_opened_without_create_should_raise_condition() {
+    file_test_invalid_path_opened_without_create_should_raise_condition_impl();
+}
+
+fn file_test_unlinking_invalid_path_should_raise_condition_impl() {
+    do run_in_newsched_task {
+        let filename = &Path("./tmp/file_another_file_that_does_not_exist.txt");
+        let mut called = false;
+        do io_error::cond.trap(|_| {
+            called = true;
+        }).inside {
+            unlink(filename);
+        }
+        assert!(called);
+    }
+}
+#[test]
+fn file_test_iounlinking_invalid_path_should_raise_condition() {
+    file_test_unlinking_invalid_path_should_raise_condition_impl();
+}
+
+fn file_test_io_non_positional_read_impl() {
+    do run_in_newsched_task {
+        use str;
+        let message = "ten-four";
+        let mut read_mem = [0, .. 8];
+        let filename = &Path("./tmp/file_rt_io_file_test_positional.txt");
+        {
+            let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+            rw_stream.write(message.as_bytes());
+        }
+        {
+            let mut read_stream = open(filename, Open, Read).unwrap();
+            {
+                let read_buf = read_mem.mut_slice(0, 4);
+                read_stream.read(read_buf);
+            }
+            {
+                let read_buf = read_mem.mut_slice(4, 8);
+                read_stream.read(read_buf);
+            }
+        }
+        unlink(filename);
+        let read_str = str::from_bytes(read_mem);
+        assert!(read_str == message.to_owned());
+    }
+}
+
+#[test]
+fn file_test_io_non_positional_read() {
+    file_test_io_non_positional_read_impl();
+}
+
+fn file_test_io_seeking_impl() {
+    do run_in_newsched_task {
+        use str;
+        let message = "ten-four";
+        let mut read_mem = [0, .. 4];
+        let set_cursor = 4 as u64;
+        let mut tell_pos_pre_read;
+        let mut tell_pos_post_read;
+        let filename = &Path("./tmp/file_rt_io_file_test_seeking.txt");
+        {
+            let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+            rw_stream.write(message.as_bytes());
+        }
+        {
+            let mut read_stream = open(filename, Open, Read).unwrap();
+            read_stream.seek(set_cursor as i64, SeekSet);
+            tell_pos_pre_read = read_stream.tell();
+            read_stream.read(read_mem);
+            tell_pos_post_read = read_stream.tell();
+        }
+        unlink(filename);
+        let read_str = str::from_bytes(read_mem);
+        assert!(read_str == message.slice(4, 8).to_owned());
+        assert!(tell_pos_pre_read == set_cursor);
+        assert!(tell_pos_post_read == message.len() as u64);
+    }
+}
+#[test]
+fn file_test_io_seek_and_tell_smoke_test() {
+    file_test_io_seeking_impl();
+}
+
+fn file_test_io_seek_and_write_impl() {
+    use io;
+    do run_in_newsched_task {
+        use str;
+        let initial_msg =   "food-is-yummy";
+        let overwrite_msg =    "-the-bar!!";
+        let final_msg =     "foo-the-bar!!";
+        let seek_idx = 3;
+        let mut read_mem = [0, .. 13];
+        let filename = &Path("./tmp/file_rt_io_file_test_seek_and_write.txt");
+        {
+            let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+            rw_stream.write(initial_msg.as_bytes());
+            rw_stream.seek(seek_idx as i64, SeekSet);
+            rw_stream.write(overwrite_msg.as_bytes());
+        }
+        {
+            let mut read_stream = open(filename, Open, Read).unwrap();
+            read_stream.read(read_mem);
+        }
+        unlink(filename);
+        let read_str = str::from_bytes(read_mem);
+        io::println(fmt!("read_str: '%?' final_msg: '%?'", read_str, final_msg));
+        assert!(read_str == final_msg.to_owned());
+    }
+}
+#[test]
+fn file_test_io_seek_and_write() {
+    file_test_io_seek_and_write_impl();
+}
+
+fn file_test_io_seek_shakedown_impl() {
+    do run_in_newsched_task {
+        use str;          // 01234567890123
+        let initial_msg =   "qwer-asdf-zxcv";
+        let chunk_one = "qwer";
+        let chunk_two = "asdf";
+        let chunk_three = "zxcv";
+        let mut read_mem = [0, .. 4];
+        let filename = &Path("./tmp/file_rt_io_file_test_seek_shakedown.txt");
+        {
+            let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
+            rw_stream.write(initial_msg.as_bytes());
+        }
+        {
+            let mut read_stream = open(filename, Open, Read).unwrap();
+
+            read_stream.seek(-4, SeekEnd);
+            read_stream.read(read_mem);
+            let read_str = str::from_bytes(read_mem);
+            assert!(read_str == chunk_three.to_owned());
+
+            read_stream.seek(-9, SeekCur);
+            read_stream.read(read_mem);
+            let read_str = str::from_bytes(read_mem);
+            assert!(read_str == chunk_two.to_owned());
+
+            read_stream.seek(0, SeekSet);
+            read_stream.read(read_mem);
+            let read_str = str::from_bytes(read_mem);
+            assert!(read_str == chunk_one.to_owned());
+        }
+        unlink(filename);
+    }
+}
+#[test]
+fn file_test_io_seek_shakedown() {
+    file_test_io_seek_shakedown_impl();
 }
diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs
index 8b18fbcfa45..116d240308a 100644
--- a/src/libstd/rt/io/mod.rs
+++ b/src/libstd/rt/io/mod.rs
@@ -461,6 +461,7 @@ pub enum SeekStyle {
 /// # XXX
 /// * Are `u64` and `i64` the right choices?
 pub trait Seek {
+    /// Return position of file cursor in the stream
     fn tell(&self) -> u64;
 
     /// Seek to an offset in a stream
@@ -539,3 +540,27 @@ pub fn placeholder_error() -> IoError {
         detail: None
     }
 }
+
+/// Instructions on how to open a file and return a `FileStream`.
+pub enum FileMode {
+    /// Opens an existing file. IoError if file does not exist.
+    Open,
+    /// Creates a file. IoError if file exists.
+    Create,
+    /// Opens an existing file or creates a new one.
+    OpenOrCreate,
+    /// Opens an existing file or creates a new one, positioned at EOF.
+    Append,
+    /// Opens an existing file, truncating it to 0 bytes.
+    Truncate,
+    /// Opens an existing file or creates a new one, truncating it to 0 bytes.
+    CreateOrTruncate,
+}
+
+/// Access permissions with which the file should be opened.
+/// `FileStream`s opened with `Read` will raise an `io_error` condition if written to.
+pub enum FileAccess {
+    Read,
+    Write,
+    ReadWrite
+}
diff --git a/src/libstd/rt/io/timer.rs b/src/libstd/rt/io/timer.rs
index bfd1ed48ac1..b0ec747800d 100644
--- a/src/libstd/rt/io/timer.rs
+++ b/src/libstd/rt/io/timer.rs
@@ -18,9 +18,6 @@ use rt::local::Local;
 pub struct Timer(~RtioTimerObject);
 
 impl Timer {
-    fn new_on_rt(i: ~RtioTimerObject) -> Timer {
-        Timer(i)
-    }
 
     pub fn new() -> Option<Timer> {
         let timer = unsafe {
@@ -30,7 +27,7 @@ impl Timer {
             (*io).timer_init()
         };
         match timer {
-            Ok(t) => Some(Timer::new_on_rt(t)),
+            Ok(t) => Some(Timer(t)),
             Err(ioerr) => {
                 rtdebug!("Timer::init: failed to init: %?", ioerr);
                 io_error::cond.raise(ioerr);
@@ -38,10 +35,8 @@ impl Timer {
             }
         }
     }
-}
 
-impl RtioTimer for Timer {
-    fn sleep(&mut self, msecs: u64) {
+    pub fn sleep(&mut self, msecs: u64) {
         (**self).sleep(msecs);
     }
 }
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs
index 1608d8cbc2c..b0b425e3aee 100644
--- a/src/libstd/rt/kill.rs
+++ b/src/libstd/rt/kill.rs
@@ -20,6 +20,7 @@ observed by the parent of a task::try task that itself spawns child tasks
 (such as any #[test] function). In both cases the data structures live in
 KillHandle.
 
+
 I. Task killing.
 
 The model for killing involves two atomic flags, the "kill flag" and the
@@ -60,9 +61,92 @@ killer does perform both writes, it means it saw a KILL_RUNNING in the
 unkillable flag, which means an unkillable task will see KILL_KILLED and fail
 immediately (rendering the subsequent write to the kill flag unnecessary).
 
+
 II. Exit code propagation.
 
-FIXME(#7544): Decide on the ultimate model for this and document it.
+The basic model for exit code propagation, which is used with the "watched"
+spawn mode (on by default for linked spawns, off for supervised and unlinked
+spawns), is that a parent will wait for all its watched children to exit
+before reporting whether it succeeded or failed. A watching parent will only
+report success if it succeeded and all its children also reported success;
+otherwise, it will report failure. This is most useful for writing test cases:
+
+~~~
+#[test]
+fn test_something_in_another_task {
+    do spawn {
+        assert!(collatz_conjecture_is_false());
+    }
+}
+~~~
+
+Here, as the child task will certainly outlive the parent task, we might miss
+the failure of the child when deciding whether or not the test case passed.
+The watched spawn mode avoids this problem.
+
+In order to propagate exit codes from children to their parents, any
+'watching' parent must wait for all of its children to exit before it can
+report its final exit status. We achieve this by using an UnsafeArc, using the
+reference counting to track how many children are still alive, and using the
+unwrap() operation in the parent's exit path to wait for all children to exit.
+The UnsafeArc referred to here is actually the KillHandle itself.
+
+This also works transitively, as if a "middle" watched child task is itself
+watching a grandchild task, the "middle" task will do unwrap() on its own
+KillHandle (thereby waiting for the grandchild to exit) before dropping its
+reference to its watching parent (which will alert the parent).
+
+While UnsafeArc::unwrap() accomplishes the synchronization, there remains the
+matter of reporting the exit codes themselves. This is easiest when an exiting
+watched task has no watched children of its own:
+
+- If the task with no watched children exits successfully, it need do nothing.
+- If the task with no watched children has failed, it sets a flag in the
+  parent's KillHandle ("any_child_failed") to false. It then stays false forever.
+
+However, if a "middle" watched task with watched children of its own exits
+before its child exits, we need to ensure that the grandparent task may still
+see a failure from the grandchild task. While we could achieve this by having
+each intermediate task block on its handle, this keeps around the other resources
+the task was using. To be more efficient, this is accomplished via "tombstones".
+
+A tombstone is a closure, ~fn() -> bool, which will perform any waiting necessary
+to collect the exit code of descendant tasks. In its environment is captured
+the KillHandle of whichever task created the tombstone, and perhaps also any
+tombstones that that task itself had, and finally also another tombstone,
+effectively creating a lazy-list of heap closures.
+
+When a child wishes to exit early and leave tombstones behind for its parent,
+it must use a LittleLock (pthread mutex) to synchronize with any possible
+sibling tasks which are trying to do the same thing with the same parent.
+However, on the other side, when the parent is ready to pull on the tombstones,
+it need not use this lock, because the unwrap() serves as a barrier that ensures
+no children will remain with references to the handle.
+
+The main logic for creating and assigning tombstones can be found in the
+function reparent_children_to() in the impl for KillHandle.
+
+
+IIA. Issues with exit code propagation.
+
+There are two known issues with the current scheme for exit code propagation.
+
+- As documented in issue #8136, the structure mandates the possibility for stack
+  overflow when collecting tombstones that are very deeply nested. This cannot
+  be avoided with the closure representation, as tombstones end up structured in
+  a sort of tree. However, notably, the tombstones do not actually need to be
+  collected in any particular order, and so a doubly-linked list may be used.
+  However we do not do this yet because DList is in libextra.
+
+- A discussion with Graydon made me realize that if we decoupled the exit code
+  propagation from the parents-waiting action, this could result in a simpler
+  implementation as the exit codes themselves would not have to be propagated,
+  and could instead be propagated implicitly through the taskgroup mechanism
+  that we already have. The tombstoning scheme would still be required. I have
+  not implemented this because currently we can't receive a linked failure kill
+  signal during the task cleanup activity, as that is currently "unkillable",
+  and occurs outside the task's unwinder's "try" block, so would require some
+  restructuring.
 
 */
 
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
index 1faad913b50..18b7394700f 100644
--- a/src/libstd/rt/local.rs
+++ b/src/libstd/rt/local.rs
@@ -21,12 +21,15 @@ pub trait Local {
     fn take() -> ~Self;
     fn exists() -> bool;
     fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
+    unsafe fn unsafe_take() -> ~Self;
     unsafe fn unsafe_borrow() -> *mut Self;
     unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
 }
 
 impl Local for Task {
+    #[inline]
     fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
+    #[inline]
     fn take() -> ~Task { unsafe { local_ptr::take() } }
     fn exists() -> bool { local_ptr::exists() }
     fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
@@ -43,7 +46,11 @@ impl Local for Task {
             None => { rtabort!("function failed in local_borrow") }
         }
     }
+    #[inline]
+    unsafe fn unsafe_take() -> ~Task { local_ptr::unsafe_take() }
+    #[inline]
     unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
+    #[inline]
     unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
         local_ptr::try_unsafe_borrow()
     }
@@ -57,12 +64,12 @@ impl Local for Scheduler {
             task.sched = Some(value.take());
         };
     }
+    #[inline]
     fn take() -> ~Scheduler {
-        do Local::borrow::<Task,~Scheduler> |task| {
-            let sched = task.sched.take_unwrap();
-            let task = task;
-            task.sched = None;
-            sched
+        unsafe {
+            // XXX: Unsafe for speed
+            let task = Local::unsafe_borrow::<Task>();
+            (*task).sched.take_unwrap()
         }
     }
     fn exists() -> bool {
@@ -85,6 +92,7 @@ impl Local for Scheduler {
             }
         }
     }
+    unsafe fn unsafe_take() -> ~Scheduler { rtabort!("unimpl") }
     unsafe fn unsafe_borrow() -> *mut Scheduler {
         match (*Local::unsafe_borrow::<Task>()).sched {
             Some(~ref mut sched) => {
@@ -97,10 +105,17 @@ impl Local for Scheduler {
         }
     }
     unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> {
-        if Local::exists::<Scheduler>() {
-            Some(Local::unsafe_borrow())
-        } else {
-            None
+        match Local::try_unsafe_borrow::<Task>() {
+            Some(task) => {
+                match (*task).sched {
+                    Some(~ref mut sched) => {
+                        let s: *mut Scheduler = &mut *sched;
+                        Some(s)
+                    }
+                    None => None
+                }
+            }
+            None => None
         }
     }
 }
@@ -111,6 +126,7 @@ impl Local for IoFactoryObject {
     fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
     fn exists() -> bool { rtabort!("unimpl") }
     fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
+    unsafe fn unsafe_take() -> ~IoFactoryObject { rtabort!("unimpl") }
     unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
         let sched = Local::unsafe_borrow::<Scheduler>();
         let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index bca1b4a70f4..aa8c5dd4674 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -40,12 +40,10 @@ impl LocalHeap {
     #[fixed_stack_segment] #[inline(never)]
     pub fn new() -> LocalHeap {
         unsafe {
-            // Don't need synchronization for the single-threaded local heap
-            let synchronized = false as uintptr_t;
             // XXX: These usually come from the environment
             let detailed_leaks = false as uintptr_t;
             let poison_on_free = false as uintptr_t;
-            let region = rust_new_memory_region(synchronized, detailed_leaks, poison_on_free);
+            let region = rust_new_memory_region(detailed_leaks, poison_on_free);
             assert!(region.is_not_null());
             let boxed = rust_new_boxed_region(region, poison_on_free);
             assert!(boxed.is_not_null());
@@ -109,8 +107,7 @@ pub fn live_allocs() -> *raw::Box<()> {
 
 extern {
     #[fast_ffi]
-    fn rust_new_memory_region(synchronized: uintptr_t,
-                               detailed_leaks: uintptr_t,
+    fn rust_new_memory_region(detailed_leaks: uintptr_t,
                                poison_on_free: uintptr_t) -> *MemoryRegion;
     #[fast_ffi]
     fn rust_delete_memory_region(region: *MemoryRegion);
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
index 77303cb8c06..e843fd1adef 100644
--- a/src/libstd/rt/local_ptr.rs
+++ b/src/libstd/rt/local_ptr.rs
@@ -23,14 +23,16 @@ use option::{Option, Some, None};
 use unstable::finally::Finally;
 use tls = rt::thread_local_storage;
 
+static mut RT_TLS_KEY: tls::Key = -1;
+
 /// Initialize the TLS key. Other ops will fail if this isn't executed first.
 #[fixed_stack_segment]
 #[inline(never)]
 pub fn init_tls_key() {
     unsafe {
-        rust_initialize_rt_tls_key();
+        rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
         extern {
-            fn rust_initialize_rt_tls_key();
+            fn rust_initialize_rt_tls_key(key: *mut tls::Key);
         }
     }
 }
@@ -40,6 +42,7 @@ pub fn init_tls_key() {
 /// # Safety note
 ///
 /// Does not validate the pointer type.
+#[inline]
 pub unsafe fn put<T>(sched: ~T) {
     let key = tls_key();
     let void_ptr: *mut c_void = cast::transmute(sched);
@@ -51,6 +54,7 @@ pub unsafe fn put<T>(sched: ~T) {
 /// # Safety note
 ///
 /// Does not validate the pointer type.
+#[inline]
 pub unsafe fn take<T>() -> ~T {
     let key = tls_key();
     let void_ptr: *mut c_void = tls::get(key);
@@ -62,6 +66,23 @@ pub unsafe fn take<T>() -> ~T {
     return ptr;
 }
 
+/// Take ownership of a pointer from thread-local storage.
+///
+/// # Safety note
+///
+/// Does not validate the pointer type.
+/// Leaves the old pointer in TLS for speed.
+#[inline]
+pub unsafe fn unsafe_take<T>() -> ~T {
+    let key = tls_key();
+    let void_ptr: *mut c_void = tls::get(key);
+    if void_ptr.is_null() {
+        rtabort!("thread-local pointer is null. bogus!");
+    }
+    let ptr: ~T = cast::transmute(void_ptr);
+    return ptr;
+}
+
 /// Check whether there is a thread-local pointer installed.
 pub fn exists() -> bool {
     unsafe {
@@ -99,10 +120,15 @@ pub unsafe fn borrow<T>(f: &fn(&mut T)) {
 /// Because this leaves the value in thread-local storage it is possible
 /// For the Scheduler pointer to be aliased
 pub unsafe fn unsafe_borrow<T>() -> *mut T {
-    match try_unsafe_borrow() {
-        Some(p) => p,
-        None => rtabort!("thread-local pointer is null. bogus!")
+    let key = tls_key();
+    let mut void_ptr: *mut c_void = tls::get(key);
+    if void_ptr.is_null() {
+        rtabort!("thread-local pointer is null. bogus!");
     }
+    let ptr: *mut *mut c_void = &mut void_ptr;
+    let ptr: *mut ~T = ptr as *mut ~T;
+    let ptr: *mut T = &mut **ptr;
+    return ptr;
 }
 
 pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
@@ -119,6 +145,7 @@ pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
     }
 }
 
+#[inline]
 fn tls_key() -> tls::Key {
     match maybe_tls_key() {
         Some(key) => key,
@@ -126,15 +153,10 @@ fn tls_key() -> tls::Key {
     }
 }
 
-#[fixed_stack_segment]
-#[inline(never)]
-fn maybe_tls_key() -> Option<tls::Key> {
+#[inline]
+#[cfg(not(test))]
+pub fn maybe_tls_key() -> Option<tls::Key> {
     unsafe {
-        let key: *mut c_void = rust_get_rt_tls_key();
-        let key: &mut tls::Key = cast::transmute(key);
-        let key = *key;
-        // Check that the key has been initialized.
-
         // NB: This is a little racy because, while the key is
         // initalized under a mutex and it's assumed to be initalized
         // in the Scheduler ctor by any thread that needs to use it,
@@ -145,14 +167,19 @@ fn maybe_tls_key() -> Option<tls::Key> {
         // another thread. I think this is fine since the only action
         // they could take if it was initialized would be to check the
         // thread-local value and see that it's not set.
-        if key != -1 {
-            return Some(key);
+        if RT_TLS_KEY != -1 {
+            return Some(RT_TLS_KEY);
         } else {
             return None;
         }
     }
+}
 
-    extern {
-        fn rust_get_rt_tls_key() -> *mut c_void;
-    }
+// XXX: The boundary between the running runtime and the testing runtime
+// seems to be fuzzy at the moment, and trying to use two different keys
+// results in disaster. This should not be necessary.
+#[inline]
+#[cfg(test)]
+pub fn maybe_tls_key() -> Option<tls::Key> {
+    unsafe { ::cast::transmute(::realstd::rt::local_ptr::maybe_tls_key()) }
 }
diff --git a/src/libstd/rt/message_queue.rs b/src/libstd/rt/message_queue.rs
index 8518ddaeae1..2bbcaff6d28 100644
--- a/src/libstd/rt/message_queue.rs
+++ b/src/libstd/rt/message_queue.rs
@@ -16,33 +16,66 @@ use kinds::Send;
 use vec::OwnedVector;
 use cell::Cell;
 use option::*;
-use unstable::sync::Exclusive;
+use unstable::sync::{UnsafeAtomicRcBox, LittleLock};
 use clone::Clone;
 
 pub struct MessageQueue<T> {
-    // XXX: Another mystery bug fixed by boxing this lock
-    priv queue: ~Exclusive<~[T]>
+    priv state: UnsafeAtomicRcBox<State<T>>
+}
+
+struct State<T> {
+    count: uint,
+    queue: ~[T],
+    lock: LittleLock
 }
 
 impl<T: Send> MessageQueue<T> {
     pub fn new() -> MessageQueue<T> {
         MessageQueue {
-            queue: ~Exclusive::new(~[])
+            state: UnsafeAtomicRcBox::new(State {
+                count: 0,
+                queue: ~[],
+                lock: LittleLock::new()
+            })
         }
     }
 
     pub fn push(&mut self, value: T) {
         unsafe {
             let value = Cell::new(value);
-            self.queue.with(|q| q.push(value.take()) );
+            let state = self.state.get();
+            do (*state).lock.lock {
+                (*state).count += 1;
+                (*state).queue.push(value.take());
+            }
         }
     }
 
     pub fn pop(&mut self) -> Option<T> {
         unsafe {
-            do self.queue.with |q| {
-                if !q.is_empty() {
-                    Some(q.shift())
+            let state = self.state.get();
+            do (*state).lock.lock {
+                if !(*state).queue.is_empty() {
+                    (*state).count += 1;
+                    Some((*state).queue.shift())
+                } else {
+                    None
+                }
+            }
+        }
+    }
+
+    /// A pop that may sometimes miss enqueued elements, but is much faster
+    /// to give up without doing any synchronization
+    pub fn casual_pop(&mut self) -> Option<T> {
+        unsafe {
+            let state = self.state.get();
+            // NB: Unsynchronized check
+            if (*state).count == 0 { return None; }
+            do (*state).lock.lock {
+                if !(*state).queue.is_empty() {
+                    (*state).count += 1;
+                    Some((*state).queue.shift())
                 } else {
                     None
                 }
@@ -51,10 +84,10 @@ impl<T: Send> MessageQueue<T> {
     }
 }
 
-impl<T> Clone for MessageQueue<T> {
+impl<T: Send> Clone for MessageQueue<T> {
     fn clone(&self) -> MessageQueue<T> {
         MessageQueue {
-            queue: self.queue.clone()
+            state: self.state.clone()
         }
     }
 }
diff --git a/src/libstd/rt/metrics.rs b/src/libstd/rt/metrics.rs
deleted file mode 100644
index b0c0fa5d708..00000000000
--- a/src/libstd/rt/metrics.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use to_str::ToStr;
-
-pub struct SchedMetrics {
-    // The number of times executing `run_sched_once`.
-    turns: uint,
-    // The number of turns that received a message.
-    messages_received: uint,
-    // The number of turns that ran a task from the queue.
-    tasks_resumed_from_queue: uint,
-    // The number of turns that found no work to perform.
-    wasted_turns: uint,
-    // The number of times the scheduler went to sleep.
-    sleepy_times: uint,
-    // Context switches from the scheduler into a task.
-    context_switches_sched_to_task: uint,
-    // Context switches from a task into the scheduler.
-    context_switches_task_to_sched: uint,
-    // Context switches from a task to a task.
-    context_switches_task_to_task: uint,
-    // Message sends that unblock the receiver
-    rendezvous_sends: uint,
-    // Message sends that do not unblock the receiver
-    non_rendezvous_sends: uint,
-    // Message receives that do not block the receiver
-    rendezvous_recvs: uint,
-    // Message receives that block the receiver
-    non_rendezvous_recvs: uint,
-    // JoinLatch releases that create tombstones
-    release_tombstone: uint,
-    // JoinLatch releases that do not create tombstones
-    release_no_tombstone: uint,
-}
-
-impl SchedMetrics {
-    pub fn new() -> SchedMetrics {
-        SchedMetrics {
-            turns: 0,
-            messages_received: 0,
-            tasks_resumed_from_queue: 0,
-            wasted_turns: 0,
-            sleepy_times: 0,
-            context_switches_sched_to_task: 0,
-            context_switches_task_to_sched: 0,
-            context_switches_task_to_task: 0,
-            rendezvous_sends: 0,
-            non_rendezvous_sends: 0,
-            rendezvous_recvs: 0,
-            non_rendezvous_recvs: 0,
-            release_tombstone: 0,
-            release_no_tombstone: 0
-        }
-    }
-}
-
-impl ToStr for SchedMetrics {
-    fn to_str(&self) -> ~str {
-        fmt!("turns: %u\n\
-              messages_received: %u\n\
-              tasks_resumed_from_queue: %u\n\
-              wasted_turns: %u\n\
-              sleepy_times: %u\n\
-              context_switches_sched_to_task: %u\n\
-              context_switches_task_to_sched: %u\n\
-              context_switches_task_to_task: %u\n\
-              rendezvous_sends: %u\n\
-              non_rendezvous_sends: %u\n\
-              rendezvous_recvs: %u\n\
-              non_rendezvous_recvs: %u\n\
-              release_tombstone: %u\n\
-              release_no_tombstone: %u\n\
-              ",
-             self.turns,
-             self.messages_received,
-             self.tasks_resumed_from_queue,
-             self.wasted_turns,
-             self.sleepy_times,
-             self.context_switches_sched_to_task,
-             self.context_switches_task_to_sched,
-             self.context_switches_task_to_task,
-             self.rendezvous_sends,
-             self.non_rendezvous_sends,
-             self.rendezvous_recvs,
-             self.non_rendezvous_recvs,
-             self.release_tombstone,
-             self.release_no_tombstone
-        )
-    }
-}
\ No newline at end of file
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index db1bfdf1bf5..0d59d5780cc 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -152,8 +152,6 @@ pub mod local_ptr;
 /// Bindings to pthread/windows thread-local storage.
 pub mod thread_local_storage;
 
-pub mod metrics;
-
 // FIXME #5248 shouldn't be pub
 /// Just stuff
 pub mod util;
@@ -224,10 +222,7 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) {
         args::init(argc, argv);
         env::init();
         logging::init(crate_map);
-        rust_update_gc_metadata(crate_map);
     }
-
-    externfn!(fn rust_update_gc_metadata(crate_map: *u8));
 }
 
 /// One-time runtime cleanup.
@@ -323,6 +318,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
     // task tree, shut down the schedulers and set the exit code.
     let handles = Cell::new(handles);
     let on_exit: ~fn(bool) = |exit_success| {
+        assert_once_ever!("last task exiting");
 
         let mut handles = handles.take();
         for handle in handles.mut_iter() {
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index f36c96706e5..1788b7a04e3 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -10,10 +10,15 @@
 
 use option::*;
 use result::*;
+use libc::c_int;
 
 use rt::io::IoError;
 use super::io::net::ip::{IpAddr, SocketAddr};
 use rt::uv::uvio;
+use path::Path;
+use super::io::support::PathLike;
+use super::io::{SeekStyle};
+use super::io::{FileMode, FileAccess};
 
 // XXX: ~object doesn't work currently so these are some placeholder
 // types to use instead
@@ -46,11 +51,27 @@ pub trait RemoteCallback {
     fn fire(&mut self);
 }
 
+/// Data needed to make a successful open(2) call
+/// Using unix flag conventions for now, which happens to also be what's supported
+/// libuv (it does translation to windows under the hood).
+pub struct FileOpenConfig {
+    /// Path to file to be opened
+    path: Path,
+    /// Flags for file access mode (as per open(2))
+    flags: int,
+    /// File creation mode, ignored unless O_CREAT is passed as part of flags
+    mode: int
+}
+
 pub trait IoFactory {
     fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStreamObject, IoError>;
     fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListenerObject, IoError>;
     fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError>;
     fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
+    fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream;
+    fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
+        -> Result<~RtioFileStream, IoError>;
+    fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
 }
 
 pub trait RtioTcpListener : RtioSocket {
@@ -93,3 +114,13 @@ pub trait RtioUdpSocket : RtioSocket {
 pub trait RtioTimer {
     fn sleep(&mut self, msecs: u64);
 }
+
+pub trait RtioFileStream {
+    fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError>;
+    fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
+    fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError>;
+    fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError>;
+    fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError>;
+    fn tell(&self) -> Result<u64, IoError>;
+    fn flush(&mut self) -> Result<(), IoError>;
+}
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 5ec2df32c48..7d59627ba39 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -24,7 +24,6 @@ use rt::kill::BlockedTask;
 use rt::local_ptr;
 use rt::local::Local;
 use rt::rtio::{RemoteCallback, PausibleIdleCallback};
-use rt::metrics::SchedMetrics;
 use borrow::{to_uint};
 use cell::Cell;
 use rand::{XorShiftRng, RngUtil};
@@ -71,7 +70,6 @@ pub struct Scheduler {
     /// An action performed after a context switch on behalf of the
     /// code running before the context switch
     cleanup_job: Option<CleanupJob>,
-    metrics: SchedMetrics,
     /// Should this scheduler run any task, or only pinned tasks?
     run_anything: bool,
     /// If the scheduler shouldn't run some tasks, a friend to send
@@ -83,6 +81,14 @@ pub struct Scheduler {
     idle_callback: Option<~PausibleIdleCallback>
 }
 
+/// An indication of how hard to work on a given operation, the difference
+/// mainly being whether memory is synchronized or not
+#[deriving(Eq)]
+enum EffortLevel {
+    DontTryTooHard,
+    GiveItYourBest
+}
+
 impl Scheduler {
 
     // * Initialization Functions
@@ -118,7 +124,6 @@ impl Scheduler {
             stack_pool: StackPool::new(),
             sched_task: None,
             cleanup_job: None,
-            metrics: SchedMetrics::new(),
             run_anything: run_anything,
             friend_handle: friend,
             rng: XorShiftRng::new(),
@@ -186,7 +191,7 @@ impl Scheduler {
 
         // Should not have any messages
         let message = stask.sched.get_mut_ref().message_queue.pop();
-        assert!(message.is_none());
+        rtassert!(message.is_none());
 
         stask.destroyed = true;
     }
@@ -237,14 +242,21 @@ impl Scheduler {
 
         // First we check for scheduler messages, these are higher
         // priority than regular tasks.
-        let sched = match sched.interpret_message_queue() {
+        let sched = match sched.interpret_message_queue(DontTryTooHard) {
             Some(sched) => sched,
             None => return
         };
 
         // This helper will use a randomized work-stealing algorithm
         // to find work.
-        let mut sched = match sched.do_work() {
+        let sched = match sched.do_work() {
+            Some(sched) => sched,
+            None => return
+        };
+
+        // Now, before sleeping we need to find out if there really
+        // were any messages. Give it your best!
+        let mut sched = match sched.interpret_message_queue(GiveItYourBest) {
             Some(sched) => sched,
             None => return
         };
@@ -252,10 +264,8 @@ impl Scheduler {
         // If we got here then there was no work to do.
         // Generate a SchedHandle and push it to the sleeper list so
         // somebody can wake us up later.
-        sched.metrics.wasted_turns += 1;
         if !sched.sleepy && !sched.no_sleep {
             rtdebug!("scheduler has no work to do, going to sleep");
-            sched.metrics.sleepy_times += 1;
             sched.sleepy = true;
             let handle = sched.make_handle();
             sched.sleeper_list.push(handle);
@@ -277,10 +287,18 @@ impl Scheduler {
     // returns the still-available scheduler. At this point all
     // message-handling will count as a turn of work, and as a result
     // return None.
-    fn interpret_message_queue(~self) -> Option<~Scheduler> {
+    fn interpret_message_queue(~self, effort: EffortLevel) -> Option<~Scheduler> {
 
         let mut this = self;
-        match this.message_queue.pop() {
+
+        let msg = if effort == DontTryTooHard {
+            // Do a cheap check that may miss messages
+            this.message_queue.casual_pop()
+        } else {
+            this.message_queue.pop()
+        };
+
+        match msg {
             Some(PinnedTask(task)) => {
                 let mut task = task;
                 task.give_home(Sched(this.make_handle()));
@@ -469,10 +487,7 @@ impl Scheduler {
         // We've made work available. Notify a
         // sleeping scheduler.
 
-        // XXX: perf. Check for a sleeper without
-        // synchronizing memory.  It's not critical
-        // that we always find it.
-        match this.sleeper_list.pop() {
+        match this.sleeper_list.casual_pop() {
             Some(handle) => {
                         let mut handle = handle;
                 handle.send(Wake)
@@ -505,7 +520,9 @@ impl Scheduler {
         let mut this = self;
 
         // The current task is grabbed from TLS, not taken as an input.
-        let current_task: ~Task = Local::take::<Task>();
+        // Doing an unsafe_take to avoid writing back a null pointer -
+        // We're going to call `put` later to do that.
+        let current_task: ~Task = unsafe { Local::unsafe_take::<Task>() };
 
         // Check that the task is not in an atomically() section (e.g.,
         // holding a pthread mutex, which could deadlock the scheduler).
@@ -563,11 +580,10 @@ impl Scheduler {
         // run the cleanup job, as expected by the previously called
         // swap_contexts function.
         unsafe {
-            let sched = Local::unsafe_borrow::<Scheduler>();
-            (*sched).run_cleanup_job();
+            let task = Local::unsafe_borrow::<Task>();
+            (*task).sched.get_mut_ref().run_cleanup_job();
 
             // Must happen after running the cleanup job (of course).
-            let task = Local::unsafe_borrow::<Task>();
             (*task).death.check_killed((*task).unwinder.unwinding);
         }
     }
diff --git a/src/libstd/rt/sleeper_list.rs b/src/libstd/rt/sleeper_list.rs
index d327023de97..7232afd6594 100644
--- a/src/libstd/rt/sleeper_list.rs
+++ b/src/libstd/rt/sleeper_list.rs
@@ -15,33 +15,68 @@ use container::Container;
 use vec::OwnedVector;
 use option::{Option, Some, None};
 use cell::Cell;
-use unstable::sync::Exclusive;
+use unstable::sync::{UnsafeAtomicRcBox, LittleLock};
 use rt::sched::SchedHandle;
 use clone::Clone;
 
 pub struct SleeperList {
-    priv stack: ~Exclusive<~[SchedHandle]>
+    priv state: UnsafeAtomicRcBox<State>
+}
+
+struct State {
+    count: uint,
+    stack: ~[SchedHandle],
+    lock: LittleLock
 }
 
 impl SleeperList {
     pub fn new() -> SleeperList {
         SleeperList {
-            stack: ~Exclusive::new(~[])
+            state: UnsafeAtomicRcBox::new(State {
+                count: 0,
+                stack: ~[],
+                lock: LittleLock::new()
+            })
         }
     }
 
     pub fn push(&mut self, handle: SchedHandle) {
         let handle = Cell::new(handle);
         unsafe {
-            self.stack.with(|s| s.push(handle.take()));
+            let state = self.state.get();
+            do (*state).lock.lock {
+                (*state).count += 1;
+                (*state).stack.push(handle.take());
+            }
         }
     }
 
     pub fn pop(&mut self) -> Option<SchedHandle> {
         unsafe {
-            do self.stack.with |s| {
-                if !s.is_empty() {
-                    Some(s.pop())
+            let state = self.state.get();
+            do (*state).lock.lock {
+                if !(*state).stack.is_empty() {
+                    (*state).count -= 1;
+                    Some((*state).stack.pop())
+                } else {
+                    None
+                }
+            }
+        }
+    }
+
+    /// A pop that may sometimes miss enqueued elements, but is much faster
+    /// to give up without doing any synchronization
+    pub fn casual_pop(&mut self) -> Option<SchedHandle> {
+        unsafe {
+            let state = self.state.get();
+            // NB: Unsynchronized check
+            if (*state).count == 0 { return None; }
+            do (*state).lock.lock {
+                if !(*state).stack.is_empty() {
+                    // NB: count is also protected by the lock
+                    (*state).count -= 1;
+                    Some((*state).stack.pop())
                 } else {
                     None
                 }
@@ -53,7 +88,7 @@ impl SleeperList {
 impl Clone for SleeperList {
     fn clone(&self) -> SleeperList {
         SleeperList {
-            stack: self.stack.clone()
+            state: self.state.clone()
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 3b8eb87f8af..9c2a6e646d2 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -59,7 +59,7 @@ pub struct Task {
 }
 
 pub enum TaskType {
-    GreenTask(Option<~SchedHome>),
+    GreenTask(Option<SchedHome>),
     SchedTask
 }
 
@@ -173,7 +173,7 @@ impl Task {
             name: None,
             coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
             sched: None,
-            task_type: GreenTask(Some(~home)),
+            task_type: GreenTask(Some(home)),
             borrow_list: None
         }
     }
@@ -196,7 +196,7 @@ impl Task {
             name: None,
             coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
             sched: None,
-            task_type: GreenTask(Some(~home)),
+            task_type: GreenTask(Some(home)),
             borrow_list: None
         }
     }
@@ -204,7 +204,7 @@ impl Task {
     pub fn give_home(&mut self, new_home: SchedHome) {
         match self.task_type {
             GreenTask(ref mut home) => {
-                *home = Some(~new_home);
+                *home = Some(new_home);
             }
             SchedTask => {
                 rtabort!("type error: used SchedTask as GreenTask");
@@ -216,7 +216,7 @@ impl Task {
         match self.task_type {
             GreenTask(ref mut home) => {
                 let out = home.take_unwrap();
-                return *out;
+                return out;
             }
             SchedTask => {
                 rtabort!("type error: used SchedTask as GreenTask");
@@ -275,8 +275,8 @@ impl Task {
 
     pub fn is_home_no_tls(&self, sched: &~Scheduler) -> bool {
         match self.task_type {
-            GreenTask(Some(~AnySched)) => { false }
-            GreenTask(Some(~Sched(SchedHandle { sched_id: ref id, _}))) => {
+            GreenTask(Some(AnySched)) => { false }
+            GreenTask(Some(Sched(SchedHandle { sched_id: ref id, _}))) => {
                 *id == sched.sched_id()
             }
             GreenTask(None) => {
@@ -291,8 +291,8 @@ impl Task {
 
     pub fn homed(&self) -> bool {
         match self.task_type {
-            GreenTask(Some(~AnySched)) => { false }
-            GreenTask(Some(~Sched(SchedHandle { _ }))) => { true }
+            GreenTask(Some(AnySched)) => { false }
+            GreenTask(Some(Sched(SchedHandle { _ }))) => { true }
             GreenTask(None) => {
                 rtabort!("task without home");
             }
@@ -309,11 +309,11 @@ impl Task {
             let sched_id = task.sched.get_ref().sched_id();
             let sched_run_anything = task.sched.get_ref().run_anything;
             match task.task_type {
-                GreenTask(Some(~AnySched)) => {
+                GreenTask(Some(AnySched)) => {
                     rtdebug!("anysched task in sched check ****");
                     sched_run_anything
                 }
-                GreenTask(Some(~Sched(SchedHandle { sched_id: ref id, _ }))) => {
+                GreenTask(Some(Sched(SchedHandle { sched_id: ref id, _ }))) => {
                     rtdebug!("homed task in sched check ****");
                     *id == sched_id
                 }
@@ -445,8 +445,17 @@ impl Unwinder {
         }
 
         extern {
+            #[cfg(not(stage0))]
             #[rust_stack]
-            fn rust_try(f: *u8, code: *c_void, data: *c_void) -> uintptr_t;
+            fn rust_try(f: extern "C" fn(*c_void, *c_void),
+                        code: *c_void,
+                        data: *c_void) -> uintptr_t;
+
+            #[cfg(stage0)]
+            #[rust_stack]
+            fn rust_try(f: *u8,
+                        code: *c_void,
+                        data: *c_void) -> uintptr_t;
         }
     }
 
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 1f29830aa04..9113f03ffee 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -14,10 +14,15 @@ use libc;
 use option::{Some, None};
 use os;
 use str::StrSlice;
+use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 
 #[cfg(target_os="macos")]
 use unstable::running_on_valgrind;
 
+// Indicates whether we should perform expensive sanity checks, including rtassert!
+// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
+pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);
+
 /// Get the number of cores available
 pub fn num_cpus() -> uint {
     #[fixed_stack_segment]; #[inline(never)];
@@ -129,24 +134,12 @@ memory and partly incapable of presentation to others.",
     }
 }
 
-pub fn set_exit_status(code: int) {
-    #[fixed_stack_segment]; #[inline(never)];
-    unsafe {
-        return rust_set_exit_status_newrt(code as libc::uintptr_t);
-    }
+static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;
 
-    extern {
-        fn rust_set_exit_status_newrt(code: libc::uintptr_t);
-    }
+pub fn set_exit_status(code: int) {
+    unsafe { EXIT_STATUS.store(code, SeqCst) }
 }
 
 pub fn get_exit_status() -> int {
-    #[fixed_stack_segment]; #[inline(never)];
-    unsafe {
-        return rust_get_exit_status_newrt() as int;
-    }
-
-    extern {
-        fn rust_get_exit_status_newrt() -> libc::uintptr_t;
-    }
+    unsafe { EXIT_STATUS.load(SeqCst) }
 }
diff --git a/src/libstd/rt/uv/file.rs b/src/libstd/rt/uv/file.rs
index 2d145055097..405dfe0a7f0 100644
--- a/src/libstd/rt/uv/file.rs
+++ b/src/libstd/rt/uv/file.rs
@@ -11,30 +11,123 @@
 use prelude::*;
 use ptr::null;
 use libc::c_void;
-use rt::uv::{Request, NativeHandle, Loop, FsCallback};
+use rt::uv::{Request, NativeHandle, Loop, FsCallback, Buf,
+             status_to_maybe_uv_error_with_loop, UvError};
 use rt::uv::uvll;
 use rt::uv::uvll::*;
+use super::super::io::support::PathLike;
+use cast::transmute;
+use libc::{c_int};
+use option::{None, Some, Option};
 
 pub struct FsRequest(*uvll::uv_fs_t);
 impl Request for FsRequest;
 
+pub struct RequestData {
+    complete_cb: Option<FsCallback>,
+    raw_fd: Option<c_int>
+}
+
 impl FsRequest {
-    fn new() -> FsRequest {
+    pub fn new(cb: Option<FsCallback>) -> FsRequest {
         let fs_req = unsafe { malloc_req(UV_FS) };
         assert!(fs_req.is_not_null());
-        let fs_req = fs_req as *uvll::uv_write_t;
-        unsafe { uvll::set_data_for_req(fs_req, null::<()>()); }
-        NativeHandle::from_native_handle(fs_req)
+        let fs_req: FsRequest = NativeHandle::from_native_handle(fs_req);
+        fs_req.install_req_data(cb);
+        fs_req
+    }
+
+    fn open_common<P: PathLike>(loop_: &Loop, path: &P, flags: int, mode: int,
+               cb: Option<FsCallback>) -> int {
+        let complete_cb_ptr = match cb {
+            Some(_) => compl_cb as *u8,
+            None => 0 as *u8
+        };
+        let is_sync = cb.is_none();
+        let req = FsRequest::new(cb);
+        let result = path.path_as_str(|p| {
+            p.to_c_str().with_ref(|p| unsafe {
+            uvll::fs_open(loop_.native_handle(),
+                          req.native_handle(), p, flags, mode, complete_cb_ptr) as int
+            })
+        });
+        if is_sync { req.cleanup_and_delete(); }
+        result
+    }
+    pub fn open<P: PathLike>(loop_: &Loop, path: &P, flags: int, mode: int,
+               cb: FsCallback) {
+        FsRequest::open_common(loop_, path, flags, mode, Some(cb));
+    }
+
+    pub fn open_sync<P: PathLike>(loop_: &Loop, path: &P, flags: int, mode: int)
+          -> Result<int, UvError> {
+        let result = FsRequest::open_common(loop_, path, flags, mode, None);
+        sync_cleanup(loop_, result)
+    }
+
+    fn unlink_common<P: PathLike>(loop_: &Loop, path: &P, cb: Option<FsCallback>) -> int {
+        let complete_cb_ptr = match cb {
+            Some(_) => compl_cb as *u8,
+            None => 0 as *u8
+        };
+        let is_sync = cb.is_none();
+        let req = FsRequest::new(cb);
+        let result = path.path_as_str(|p| {
+            p.to_c_str().with_ref(|p| unsafe {
+                uvll::fs_unlink(loop_.native_handle(),
+                              req.native_handle(), p, complete_cb_ptr) as int
+            })
+        });
+        if is_sync { req.cleanup_and_delete(); }
+        result
+    }
+    pub fn unlink<P: PathLike>(loop_: &Loop, path: &P, cb: FsCallback) {
+        let result = FsRequest::unlink_common(loop_, path, Some(cb));
+        sync_cleanup(loop_, result);
+    }
+    pub fn unlink_sync<P: PathLike>(loop_: &Loop, path: &P) -> Result<int, UvError> {
+        let result = FsRequest::unlink_common(loop_, path, None);
+        sync_cleanup(loop_, result)
+    }
+
+    pub fn install_req_data(&self, cb: Option<FsCallback>) {
+        let fs_req = (self.native_handle()) as *uvll::uv_write_t;
+        let data = ~RequestData {
+            complete_cb: cb,
+            raw_fd: None
+        };
+        unsafe {
+            let data = transmute::<~RequestData, *c_void>(data);
+            uvll::set_data_for_req(fs_req, data);
+        }
     }
 
-    fn delete(self) {
-        unsafe { free_req(self.native_handle() as *c_void) }
+    fn get_req_data<'r>(&'r mut self) -> &'r mut RequestData {
+        unsafe {
+            let data = uvll::get_data_for_req((self.native_handle()));
+            let data = transmute::<&*c_void, &mut ~RequestData>(&data);
+            return &mut **data;
+        }
     }
 
-    fn open(&mut self, _loop_: &Loop, _cb: FsCallback) {
+    pub fn get_result(&mut self) -> c_int {
+        unsafe {
+            uvll::get_result_from_fs_req(self.native_handle())
+        }
     }
 
-    fn close(&mut self, _loop_: &Loop, _cb: FsCallback) {
+    pub fn get_loop(&self) -> Loop {
+        unsafe { Loop{handle:uvll::get_loop_from_fs_req(self.native_handle())} }
+    }
+
+    fn cleanup_and_delete(self) {
+        unsafe {
+            let data = uvll::get_data_for_req(self.native_handle());
+            let _data = transmute::<*c_void, ~RequestData>(data);
+            uvll::set_data_for_req(self.native_handle(), null::<()>());
+            uvll::fs_req_cleanup(self.native_handle());
+            free_req(self.native_handle() as *c_void)
+        }
     }
 }
 
@@ -46,3 +139,298 @@ impl NativeHandle<*uvll::uv_fs_t> for FsRequest {
         match self { &FsRequest(ptr) => ptr }
     }
 }
+    fn sync_cleanup(loop_: &Loop, result: int)
+          -> Result<int, UvError> {
+        match status_to_maybe_uv_error_with_loop(loop_.native_handle(), result as i32) {
+            Some(err) => Err(err),
+            None => Ok(result)
+        }
+    }
+
+pub struct FileDescriptor(c_int);
+impl FileDescriptor {
+    fn new(fd: c_int) -> FileDescriptor {
+        FileDescriptor(fd)
+    }
+
+
+    pub fn from_open_req(req: &mut FsRequest) -> FileDescriptor {
+        FileDescriptor::new(req.get_result())
+    }
+
+    // as per bnoordhuis in #libuv: offset >= 0 uses prwrite instead of write
+    fn write_common(&mut self, loop_: &Loop, buf: Buf, offset: i64, cb: Option<FsCallback>)
+          -> int {
+        let complete_cb_ptr = match cb {
+            Some(_) => compl_cb as *u8,
+            None => 0 as *u8
+        };
+        let is_sync = cb.is_none();
+        let mut req = FsRequest::new(cb);
+        let base_ptr = buf.base as *c_void;
+        let len = buf.len as uint;
+        req.get_req_data().raw_fd = Some(self.native_handle());
+        let result = unsafe {
+            uvll::fs_write(loop_.native_handle(), req.native_handle(),
+                           self.native_handle(), base_ptr,
+                           len, offset, complete_cb_ptr) as int
+        };
+        if is_sync { req.cleanup_and_delete(); }
+        result
+    }
+    pub fn write(&mut self, loop_: &Loop, buf: Buf, offset: i64, cb: FsCallback) {
+        self.write_common(loop_, buf, offset, Some(cb));
+    }
+    pub fn write_sync(&mut self, loop_: &Loop, buf: Buf, offset: i64)
+          -> Result<int, UvError> {
+        let result = self.write_common(loop_, buf, offset, None);
+        sync_cleanup(loop_, result)
+    }
+
+    fn read_common(&mut self, loop_: &Loop, buf: Buf,
+                   offset: i64, cb: Option<FsCallback>)
+          -> int {
+        let complete_cb_ptr = match cb {
+            Some(_) => compl_cb as *u8,
+            None => 0 as *u8
+        };
+        let is_sync = cb.is_none();
+        let mut req = FsRequest::new(cb);
+        req.get_req_data().raw_fd = Some(self.native_handle());
+        let buf_ptr = buf.base as *c_void;
+        let result = unsafe {
+            uvll::fs_read(loop_.native_handle(), req.native_handle(),
+                           self.native_handle(), buf_ptr,
+                           buf.len as uint, offset, complete_cb_ptr) as int
+        };
+        if is_sync { req.cleanup_and_delete(); }
+        result
+    }
+    pub fn read(&mut self, loop_: &Loop, buf: Buf, offset: i64, cb: FsCallback) {
+        self.read_common(loop_, buf, offset, Some(cb));
+    }
+    pub fn read_sync(&mut self, loop_: &Loop, buf: Buf, offset: i64)
+          -> Result<int, UvError> {
+        let result = self.read_common(loop_, buf, offset, None);
+        sync_cleanup(loop_, result)
+    }
+
+    fn close_common(self, loop_: &Loop, cb: Option<FsCallback>) -> int {
+        let complete_cb_ptr = match cb {
+            Some(_) => compl_cb as *u8,
+            None => 0 as *u8
+        };
+        let is_sync = cb.is_none();
+        let req = FsRequest::new(cb);
+        let result = unsafe {
+            uvll::fs_close(loop_.native_handle(), req.native_handle(),
+                           self.native_handle(), complete_cb_ptr) as int
+        };
+        if is_sync { req.cleanup_and_delete(); }
+        result
+    }
+    pub fn close(self, loop_: &Loop, cb: FsCallback) {
+        self.close_common(loop_, Some(cb));
+    }
+    pub fn close_sync(self, loop_: &Loop) -> Result<int, UvError> {
+        let result = self.close_common(loop_, None);
+        sync_cleanup(loop_, result)
+    }
+}
+extern fn compl_cb(req: *uv_fs_t) {
+    let mut req: FsRequest = NativeHandle::from_native_handle(req);
+    let loop_ = req.get_loop();
+    // pull the user cb out of the req data
+    let cb = {
+        let data = req.get_req_data();
+        assert!(data.complete_cb.is_some());
+        // option dance, option dance. oooooh yeah.
+        data.complete_cb.take_unwrap()
+    };
+    // in uv_fs_open calls, the result will be the fd in the
+    // case of success, otherwise it's -1 indicating an error
+    let result = req.get_result();
+    let status = status_to_maybe_uv_error_with_loop(
+        loop_.native_handle(), result);
+    // we have a req and status, call the user cb..
+    // only giving the user a ref to the FsRequest, as we
+    // have to clean it up, afterwards (and they aren't really
+    // reusable, anyways
+    cb(&mut req, status);
+    // clean up the req (and its data!) after calling the user cb
+    req.cleanup_and_delete();
+}
+
+impl NativeHandle<c_int> for FileDescriptor {
+    fn from_native_handle(handle: c_int) -> FileDescriptor {
+        FileDescriptor(handle)
+    }
+    fn native_handle(&self) -> c_int {
+        match self { &FileDescriptor(ptr) => ptr }
+    }
+}
+
+mod test {
+    use super::*;
+    //use rt::test::*;
+    use libc::{STDOUT_FILENO};
+    use vec;
+    use str;
+    use unstable::run_in_bare_thread;
+    use path::Path;
+    use rt::uv::{Loop, Buf, slice_to_uv_buf};
+    use libc::{O_CREAT, O_RDWR, O_RDONLY,
+               S_IWUSR, S_IRUSR}; //NOTE: need defs for S_**GRP|S_**OTH in libc:: ...
+               //S_IRGRP, S_IROTH};
+
+    fn file_test_full_simple_impl() {
+        do run_in_bare_thread {
+            let mut loop_ = Loop::new();
+            let create_flags = O_RDWR | O_CREAT;
+            let read_flags = O_RDONLY;
+            // 0644 BZZT! WRONG! 0600! See below.
+            let mode = S_IWUSR |S_IRUSR;
+                // these aren't defined in std::libc :(
+                //map_mode(S_IRGRP) |
+                //map_mode(S_IROTH);
+            let path_str = "./tmp/file_full_simple.txt";
+            let write_val = "hello".as_bytes().to_owned();
+            let write_buf  = slice_to_uv_buf(write_val);
+            let write_buf_ptr: *Buf = &write_buf;
+            let read_buf_len = 1028;
+            let read_mem = vec::from_elem(read_buf_len, 0u8);
+            let read_buf = slice_to_uv_buf(read_mem);
+            let read_buf_ptr: *Buf = &read_buf;
+            let p = Path(path_str);
+            do FsRequest::open(&loop_, &p, create_flags as int, mode as int)
+            |req, uverr| {
+                assert!(uverr.is_none());
+                let mut fd = FileDescriptor::from_open_req(req);
+                let raw_fd = fd.native_handle();
+                let buf = unsafe { *write_buf_ptr };
+                do fd.write(&req.get_loop(), buf, -1) |req, uverr| {
+                    let fd = FileDescriptor(raw_fd);
+                    do fd.close(&req.get_loop()) |req, _| {
+                        let loop_ = req.get_loop();
+                        assert!(uverr.is_none());
+                        do FsRequest::open(&loop_, &Path(path_str), read_flags as int,0)
+                            |req, uverr| {
+                            assert!(uverr.is_none());
+                            let loop_ = req.get_loop();
+                            let mut fd = FileDescriptor::from_open_req(req);
+                            let raw_fd = fd.native_handle();
+                            let read_buf = unsafe { *read_buf_ptr };
+                            do fd.read(&loop_, read_buf, 0) |req, uverr| {
+                                assert!(uverr.is_none());
+                                let loop_ = req.get_loop();
+                                // we know nread >=0 because uverr is none..
+                                let nread = req.get_result() as uint;
+                                // nread == 0 would be EOF
+                                if nread > 0 {
+                                    let read_str = unsafe {
+                                        let read_buf = *read_buf_ptr;
+                                        str::from_bytes(
+                                            vec::from_buf(
+                                                read_buf.base, nread))
+                                    };
+                                    assert!(read_str == ~"hello");
+                                    do FileDescriptor(raw_fd).close(&loop_) |req,uverr| {
+                                        assert!(uverr.is_none());
+                                        let loop_ = &req.get_loop();
+                                        do FsRequest::unlink(loop_, &Path(path_str))
+                                        |_,uverr| {
+                                            assert!(uverr.is_none());
+                                        };
+                                    };
+                                }
+                            };
+                        };
+                    };
+                };
+            };
+            loop_.run();
+            loop_.close();
+        }
+    }
+    fn file_test_full_simple_impl_sync() {
+        do run_in_bare_thread {
+            // setup
+            let mut loop_ = Loop::new();
+            let create_flags = O_RDWR |
+                O_CREAT;
+            let read_flags = O_RDONLY;
+            // 0644
+            let mode = S_IWUSR |
+                S_IRUSR;
+                //S_IRGRP |
+                //S_IROTH;
+            let path_str = "./tmp/file_full_simple_sync.txt";
+            let write_val = "hello".as_bytes().to_owned();
+            let write_buf = slice_to_uv_buf(write_val);
+            // open/create
+            let result = FsRequest::open_sync(&loop_, &Path(path_str),
+                                                   create_flags as int, mode as int);
+            assert!(result.is_ok());
+            let mut fd = FileDescriptor(result.unwrap() as i32);
+            // write
+            let result = fd.write_sync(&loop_, write_buf, -1);
+            assert!(result.is_ok());
+            // close
+            let result = fd.close_sync(&loop_);
+            assert!(result.is_ok());
+            // re-open
+            let result = FsRequest::open_sync(&loop_, &Path(path_str),
+                                                   read_flags as int,0);
+            assert!(result.is_ok());
+            let len = 1028;
+            let mut fd = FileDescriptor(result.unwrap() as i32);
+            // read
+            let read_mem: ~[u8] = vec::from_elem(len, 0u8);
+            let buf = slice_to_uv_buf(read_mem);
+            let result = fd.read_sync(&loop_, buf, 0);
+            assert!(result.is_ok());
+            let nread = result.unwrap();
+            // nread == 0 would be EOF.. we know it's >= zero because otherwise
+            // the above assert would fail
+            if nread > 0 {
+                let read_str = str::from_bytes(
+                    read_mem.slice(0, nread as uint));
+                assert!(read_str == ~"hello");
+                // close
+                let result = fd.close_sync(&loop_);
+                assert!(result.is_ok());
+                // unlink
+                let result = FsRequest::unlink_sync(&loop_, &Path(path_str));
+                assert!(result.is_ok());
+            } else { fail!("nread was 0.. wudn't expectin' that."); }
+            loop_.close();
+        }
+    }
+
+    #[test]
+    fn file_test_full_simple() {
+        file_test_full_simple_impl();
+    }
+
+    #[test]
+    fn file_test_full_simple_sync() {
+        file_test_full_simple_impl_sync();
+    }
+
+    fn naive_print(loop_: &Loop, input: &str) {
+        let mut stdout = FileDescriptor(STDOUT_FILENO);
+        let write_val = input.as_bytes();
+        let write_buf = slice_to_uv_buf(write_val);
+        stdout.write_sync(loop_, write_buf, -1);
+    }
+
+    #[test]
+    fn file_test_write_to_stdout() {
+        do run_in_bare_thread {
+            let mut loop_ = Loop::new();
+            naive_print(&loop_, "zanzibar!\n");
+            loop_.run();
+            loop_.close();
+        };
+    }
+}
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs
index 9312efbf03e..75b9a5ac553 100644
--- a/src/libstd/rt/uv/mod.rs
+++ b/src/libstd/rt/uv/mod.rs
@@ -53,7 +53,7 @@ use rt::io::IoError;
 
 //#[cfg(test)] use unstable::run_in_bare_thread;
 
-pub use self::file::FsRequest;
+pub use self::file::{FsRequest};
 pub use self::net::{StreamWatcher, TcpWatcher, UdpWatcher};
 pub use self::idle::IdleWatcher;
 pub use self::timer::TimerWatcher;
@@ -125,7 +125,7 @@ pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
 pub type NullCallback = ~fn();
 pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
 pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
-pub type FsCallback = ~fn(FsRequest, Option<UvError>);
+pub type FsCallback = ~fn(&mut FsRequest, Option<UvError>);
 pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
 pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
 pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
@@ -282,6 +282,20 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
 }
 
 /// Given a uv handle, convert a callback status to a UvError
+pub fn status_to_maybe_uv_error_with_loop(
+    loop_: *uvll::uv_loop_t,
+    status: c_int) -> Option<UvError> {
+    if status != -1 {
+        None
+    } else {
+        unsafe {
+            rtdebug!("loop: %x", loop_ as uint);
+            let err = uvll::last_error(loop_);
+            Some(UvError(err))
+        }
+    }
+}
+/// Given a uv handle, convert a callback status to a UvError
 pub fn status_to_maybe_uv_error<T, U: Watcher + NativeHandle<*T>>(handle: U,
                                                                  status: c_int) -> Option<UvError> {
     if status != -1 {
@@ -290,9 +304,7 @@ pub fn status_to_maybe_uv_error<T, U: Watcher + NativeHandle<*T>>(handle: U,
         unsafe {
             rtdebug!("handle: %x", handle.native_handle() as uint);
             let loop_ = uvll::get_loop_for_uv_handle(handle.native_handle());
-            rtdebug!("loop: %x", loop_ as uint);
-            let err = uvll::last_error(loop_);
-            Some(UvError(err))
+            status_to_maybe_uv_error_with_loop(loop_, status)
         }
     }
 }
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index 6920e776a09..6e79a78e061 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -17,10 +17,11 @@ use libc::{c_int, c_uint, c_void};
 use ops::Drop;
 use option::*;
 use ptr;
+use str;
 use result::*;
 use rt::io::IoError;
 use rt::io::net::ip::{SocketAddr, IpAddr};
-use rt::io::{standard_error, OtherIoError};
+use rt::io::{standard_error, OtherIoError, SeekStyle, SeekSet, SeekCur, SeekEnd};
 use rt::local::Local;
 use rt::rtio::*;
 use rt::sched::{Scheduler, SchedHandle};
@@ -29,6 +30,12 @@ use rt::uv::*;
 use rt::uv::idle::IdleWatcher;
 use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
 use unstable::sync::Exclusive;
+use super::super::io::support::PathLike;
+use libc::{lseek, off_t, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
+          S_IRUSR, S_IWUSR};
+use rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
+            CreateOrTruncate, Append, Truncate, Read, Write, ReadWrite};
+use task;
 
 #[cfg(test)] use container::Container;
 #[cfg(test)] use unstable::run_in_bare_thread;
@@ -49,30 +56,68 @@ trait HomingIO {
         // go home
         let old_home = Cell::new_empty();
         let old_home_ptr = &old_home;
-        let scheduler = Local::take::<Scheduler>();
-        do scheduler.deschedule_running_task_and_then |_, task| {
-            // get the old home first
-            do task.wake().map_move |mut task| {
-                old_home_ptr.put_back(task.take_unwrap_home());
-                self.home().send(PinnedTask(task));
-            };
+        do task::unkillable { // FIXME(#8674)
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                // get the old home first
+                do task.wake().map_move |mut task| {
+                    old_home_ptr.put_back(task.take_unwrap_home());
+                    self.home().send(PinnedTask(task));
+                };
+            }
         }
 
         // do IO
         let a = io(self);
 
         // unhome home
-        let scheduler = Local::take::<Scheduler>();
-        do scheduler.deschedule_running_task_and_then |scheduler, task| {
-            do task.wake().map_move |mut task| {
-                task.give_home(old_home.take());
-                scheduler.make_handle().send(TaskFromFriend(task));
-            };
+        do task::unkillable { // FIXME(#8674)
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |scheduler, task| {
+                do task.wake().map_move |mut task| {
+                    task.give_home(old_home.take());
+                    scheduler.make_handle().send(TaskFromFriend(task));
+                };
+            }
         }
 
         // return the result of the IO
         a
     }
+
+    fn home_for_io_with_sched<A>(&mut self, io_sched: &fn(&mut Self, ~Scheduler) -> A) -> A {
+        use rt::sched::{PinnedTask, TaskFromFriend};
+
+        do task::unkillable { // FIXME(#8674)
+            // go home
+            let old_home = Cell::new_empty();
+            let old_home_ptr = &old_home;
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                // get the old home first
+                do task.wake().map_move |mut task| {
+                    old_home_ptr.put_back(task.take_unwrap_home());
+                    self.home().send(PinnedTask(task));
+                };
+            }
+
+            // do IO
+            let scheduler = Local::take::<Scheduler>();
+            let a = io_sched(self, scheduler);
+
+            // unhome home
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |scheduler, task| {
+                do task.wake().map_move |mut task| {
+                    task.give_home(old_home.take());
+                    scheduler.make_handle().send(TaskFromFriend(task));
+                };
+            }
+
+            // return the result of the IO
+            a
+        }
+    }
 }
 
 // get a handle for the current scheduler
@@ -370,35 +415,37 @@ impl IoFactory for UvIoFactory {
         let result_cell_ptr: *Cell<Result<~RtioTcpStreamObject, IoError>> = &result_cell;
 
         // Block this task and take ownership, switch to scheduler context
-        let scheduler = Local::take::<Scheduler>();
-        do scheduler.deschedule_running_task_and_then |_, task| {
-
-            let mut tcp = TcpWatcher::new(self.uv_loop());
-            let task_cell = Cell::new(task);
+        do task::unkillable { // FIXME(#8674)
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |_, task| {
 
-            // Wait for a connection
-            do tcp.connect(addr) |stream, status| {
-                match status {
-                    None => {
-                        let tcp = NativeHandle::from_native_handle(stream.native_handle());
-                        let home = get_handle_to_current_scheduler!();
-                        let res = Ok(~UvTcpStream { watcher: tcp, home: home });
+                let mut tcp = TcpWatcher::new(self.uv_loop());
+                let task_cell = Cell::new(task);
 
-                        // Store the stream in the task's stack
-                        unsafe { (*result_cell_ptr).put_back(res); }
+                // Wait for a connection
+                do tcp.connect(addr) |stream, status| {
+                    match status {
+                        None => {
+                            let tcp = NativeHandle::from_native_handle(stream.native_handle());
+                            let home = get_handle_to_current_scheduler!();
+                            let res = Ok(~UvTcpStream { watcher: tcp, home: home });
 
-                        // Context switch
-                        let scheduler = Local::take::<Scheduler>();
-                        scheduler.resume_blocked_task_immediately(task_cell.take());
-                    }
-                    Some(_) => {
-                        let task_cell = Cell::new(task_cell.take());
-                        do stream.close {
-                            let res = Err(uv_error_to_io_error(status.unwrap()));
+                            // Store the stream in the task's stack
                             unsafe { (*result_cell_ptr).put_back(res); }
+
+                            // Context switch
                             let scheduler = Local::take::<Scheduler>();
                             scheduler.resume_blocked_task_immediately(task_cell.take());
                         }
+                        Some(_) => {
+                            let task_cell = Cell::new(task_cell.take());
+                            do stream.close {
+                                let res = Err(uv_error_to_io_error(status.unwrap()));
+                                unsafe { (*result_cell_ptr).put_back(res); }
+                                let scheduler = Local::take::<Scheduler>();
+                                scheduler.resume_blocked_task_immediately(task_cell.take());
+                            }
+                        }
                     }
                 }
             }
@@ -416,15 +463,17 @@ impl IoFactory for UvIoFactory {
                 Ok(~UvTcpListener::new(watcher, home))
             }
             Err(uverr) => {
-                let scheduler = Local::take::<Scheduler>();
-                do scheduler.deschedule_running_task_and_then |_, task| {
-                    let task_cell = Cell::new(task);
-                    do watcher.as_stream().close {
-                        let scheduler = Local::take::<Scheduler>();
-                        scheduler.resume_blocked_task_immediately(task_cell.take());
+                do task::unkillable { // FIXME(#8674)
+                    let scheduler = Local::take::<Scheduler>();
+                    do scheduler.deschedule_running_task_and_then |_, task| {
+                        let task_cell = Cell::new(task);
+                        do watcher.as_stream().close {
+                            let scheduler = Local::take::<Scheduler>();
+                            scheduler.resume_blocked_task_immediately(task_cell.take());
+                        }
                     }
+                    Err(uv_error_to_io_error(uverr))
                 }
-                Err(uv_error_to_io_error(uverr))
             }
         }
     }
@@ -437,15 +486,17 @@ impl IoFactory for UvIoFactory {
                 Ok(~UvUdpSocket { watcher: watcher, home: home })
             }
             Err(uverr) => {
-                let scheduler = Local::take::<Scheduler>();
-                do scheduler.deschedule_running_task_and_then |_, task| {
-                    let task_cell = Cell::new(task);
-                    do watcher.close {
-                        let scheduler = Local::take::<Scheduler>();
-                        scheduler.resume_blocked_task_immediately(task_cell.take());
+                do task::unkillable { // FIXME(#8674)
+                    let scheduler = Local::take::<Scheduler>();
+                    do scheduler.deschedule_running_task_and_then |_, task| {
+                        let task_cell = Cell::new(task);
+                        do watcher.close {
+                            let scheduler = Local::take::<Scheduler>();
+                            scheduler.resume_blocked_task_immediately(task_cell.take());
+                        }
                     }
+                    Err(uv_error_to_io_error(uverr))
                 }
-                Err(uv_error_to_io_error(uverr))
             }
         }
     }
@@ -455,6 +506,91 @@ impl IoFactory for UvIoFactory {
         let home = get_handle_to_current_scheduler!();
         Ok(~UvTimer::new(watcher, home))
     }
+
+    fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream {
+        let loop_ = Loop {handle: self.uv_loop().native_handle()};
+        let fd = file::FileDescriptor(fd);
+        let home = get_handle_to_current_scheduler!();
+        ~UvFileStream::new(loop_, fd, close_on_drop, home) as ~RtioFileStream
+    }
+
+    fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
+        -> Result<~RtioFileStream, IoError> {
+        let mut flags = match fm {
+            Open => 0,
+            Create => O_CREAT,
+            OpenOrCreate => O_CREAT,
+            Append => O_APPEND,
+            Truncate => O_TRUNC,
+            CreateOrTruncate => O_TRUNC | O_CREAT
+        };
+        flags = match fa {
+            Read => flags | O_RDONLY,
+            Write => flags | O_WRONLY,
+            ReadWrite => flags | O_RDWR
+        };
+        let create_mode = match fm {
+            Create|OpenOrCreate|CreateOrTruncate =>
+                S_IRUSR | S_IWUSR,
+            _ => 0
+        };
+        let result_cell = Cell::new_empty();
+        let result_cell_ptr: *Cell<Result<~RtioFileStream,
+                                           IoError>> = &result_cell;
+        let path_cell = Cell::new(path);
+        do task::unkillable { // FIXME(#8674)
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                let task_cell = Cell::new(task);
+                let path = path_cell.take();
+                do file::FsRequest::open(self.uv_loop(), path, flags as int, create_mode as int)
+                      |req,err| {
+                    if err.is_none() {
+                        let loop_ = Loop {handle: req.get_loop().native_handle()};
+                        let home = get_handle_to_current_scheduler!();
+                        let fd = file::FileDescriptor(req.get_result());
+                        let fs = ~UvFileStream::new(
+                            loop_, fd, true, home) as ~RtioFileStream;
+                        let res = Ok(fs);
+                        unsafe { (*result_cell_ptr).put_back(res); }
+                        let scheduler = Local::take::<Scheduler>();
+                        scheduler.resume_blocked_task_immediately(task_cell.take());
+                    } else {
+                        let res = Err(uv_error_to_io_error(err.unwrap()));
+                        unsafe { (*result_cell_ptr).put_back(res); }
+                        let scheduler = Local::take::<Scheduler>();
+                        scheduler.resume_blocked_task_immediately(task_cell.take());
+                    }
+                };
+            };
+        }
+        assert!(!result_cell.is_empty());
+        return result_cell.take();
+    }
+
+    fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError> {
+        let result_cell = Cell::new_empty();
+        let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
+        let path_cell = Cell::new(path);
+        do task::unkillable { // FIXME(#8674)
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                let task_cell = Cell::new(task);
+                let path = path_cell.take();
+                do file::FsRequest::unlink(self.uv_loop(), path) |_, err| {
+                    let res = match err {
+                        None => Ok(()),
+                        Some(err) => Err(uv_error_to_io_error(err))
+                    };
+                    unsafe { (*result_cell_ptr).put_back(res); }
+                    let scheduler = Local::take::<Scheduler>();
+                    scheduler.resume_blocked_task_immediately(task_cell.take());
+                };
+            };
+        }
+        assert!(!result_cell.is_empty());
+        return result_cell.take();
+    }
 }
 
 pub struct UvTcpListener {
@@ -485,8 +621,7 @@ impl Drop for UvTcpListener {
     fn drop(&self) {
         // XXX need mutable finalizer
         let self_ = unsafe { transmute::<&UvTcpListener, &mut UvTcpListener>(self) };
-        do self_.home_for_io |self_| {
-            let scheduler = Local::take::<Scheduler>();
+        do self_.home_for_io_with_sched |self_, scheduler| {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher().as_stream().close {
@@ -578,8 +713,7 @@ impl Drop for UvTcpStream {
     fn drop(&self) {
         // XXX need mutable finalizer
         let this = unsafe { transmute::<&UvTcpStream, &mut UvTcpStream>(self) };
-        do this.home_for_io |self_| {
-            let scheduler = Local::take::<Scheduler>();
+        do this.home_for_io_with_sched |self_, scheduler| {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher.as_stream().close {
@@ -601,11 +735,10 @@ impl RtioSocket for UvTcpStream {
 
 impl RtioTcpStream for UvTcpStream {
     fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
-        do self.home_for_io |self_| {
+        do self.home_for_io_with_sched |self_, scheduler| {
             let result_cell = Cell::new_empty();
             let result_cell_ptr: *Cell<Result<uint, IoError>> = &result_cell;
 
-            let scheduler = Local::take::<Scheduler>();
             let buf_ptr: *&mut [u8] = &buf;
             do scheduler.deschedule_running_task_and_then |_sched, task| {
                 let task_cell = Cell::new(task);
@@ -643,10 +776,9 @@ impl RtioTcpStream for UvTcpStream {
     }
 
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
+        do self.home_for_io_with_sched |self_, scheduler| {
             let result_cell = Cell::new_empty();
             let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
-            let scheduler = Local::take::<Scheduler>();
             let buf_ptr: *&[u8] = &buf;
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
@@ -740,11 +872,10 @@ impl Drop for UvUdpSocket {
     fn drop(&self) {
         // XXX need mutable finalizer
         let this = unsafe { transmute::<&UvUdpSocket, &mut UvUdpSocket>(self) };
-        do this.home_for_io |_| {
-            let scheduler = Local::take::<Scheduler>();
+        do this.home_for_io_with_sched |self_, scheduler| {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
-                do this.watcher.close {
+                do self_.watcher.close {
                     let scheduler = Local::take::<Scheduler>();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
@@ -763,11 +894,10 @@ impl RtioSocket for UvUdpSocket {
 
 impl RtioUdpSocket for UvUdpSocket {
     fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError> {
-        do self.home_for_io |self_| {
+        do self.home_for_io_with_sched |self_, scheduler| {
             let result_cell = Cell::new_empty();
             let result_cell_ptr: *Cell<Result<(uint, SocketAddr), IoError>> = &result_cell;
 
-            let scheduler = Local::take::<Scheduler>();
             let buf_ptr: *&mut [u8] = &buf;
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
@@ -798,10 +928,9 @@ impl RtioUdpSocket for UvUdpSocket {
     }
 
     fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
-        do self.home_for_io |self_| {
+        do self.home_for_io_with_sched |self_, scheduler| {
             let result_cell = Cell::new_empty();
             let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
-            let scheduler = Local::take::<Scheduler>();
             let buf_ptr: *&[u8] = &buf;
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
@@ -960,9 +1089,8 @@ impl UvTimer {
 impl Drop for UvTimer {
     fn drop(&self) {
         let self_ = unsafe { transmute::<&UvTimer, &mut UvTimer>(self) };
-        do self_.home_for_io |self_| {
+        do self_.home_for_io_with_sched |self_, scheduler| {
             rtdebug!("closing UvTimer");
-            let scheduler = Local::take::<Scheduler>();
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher.close {
@@ -976,8 +1104,7 @@ impl Drop for UvTimer {
 
 impl RtioTimer for UvTimer {
     fn sleep(&mut self, msecs: u64) {
-        do self.home_for_io |self_| {
-            let scheduler = Local::take::<Scheduler>();
+        do self.home_for_io_with_sched |self_, scheduler| {
             do scheduler.deschedule_running_task_and_then |_sched, task| {
                 rtdebug!("sleep: entered scheduler context");
                 let task_cell = Cell::new(task);
@@ -992,6 +1119,137 @@ impl RtioTimer for UvTimer {
     }
 }
 
+pub struct UvFileStream {
+    loop_: Loop,
+    fd: file::FileDescriptor,
+    close_on_drop: bool,
+    home: SchedHandle
+}
+
+impl HomingIO for UvFileStream {
+    fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
+}
+
+impl UvFileStream {
+    fn new(loop_: Loop, fd: file::FileDescriptor, close_on_drop: bool,
+           home: SchedHandle) -> UvFileStream {
+        UvFileStream {
+            loop_: loop_,
+            fd: fd,
+            close_on_drop: close_on_drop,
+            home: home
+        }
+    }
+    fn base_read(&mut self, buf: &mut [u8], offset: i64) -> Result<int, IoError> {
+        let result_cell = Cell::new_empty();
+        let result_cell_ptr: *Cell<Result<int, IoError>> = &result_cell;
+        let buf_ptr: *&mut [u8] = &buf;
+        do self.home_for_io_with_sched |self_, scheduler| {
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
+                let task_cell = Cell::new(task);
+                do self_.fd.read(&self_.loop_, buf, offset) |req, uverr| {
+                    let res = match uverr  {
+                        None => Ok(req.get_result() as int),
+                        Some(err) => Err(uv_error_to_io_error(err))
+                    };
+                    unsafe { (*result_cell_ptr).put_back(res); }
+                    let scheduler = Local::take::<Scheduler>();
+                    scheduler.resume_blocked_task_immediately(task_cell.take());
+                };
+            };
+        };
+        result_cell.take()
+    }
+    fn base_write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> {
+        let result_cell = Cell::new_empty();
+        let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
+        let buf_ptr: *&[u8] = &buf;
+        do self.home_for_io_with_sched |self_, scheduler| {
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
+                let task_cell = Cell::new(task);
+                do self_.fd.write(&self_.loop_, buf, offset) |_, uverr| {
+                    let res = match uverr  {
+                        None => Ok(()),
+                        Some(err) => Err(uv_error_to_io_error(err))
+                    };
+                    unsafe { (*result_cell_ptr).put_back(res); }
+                    let scheduler = Local::take::<Scheduler>();
+                    scheduler.resume_blocked_task_immediately(task_cell.take());
+                };
+            };
+        };
+        result_cell.take()
+    }
+    fn seek_common(&mut self, pos: i64, whence: c_int) ->
+        Result<u64, IoError>{
+        #[fixed_stack_segment]; #[inline(never)];
+        unsafe {
+            match lseek((*self.fd), pos as off_t, whence) {
+                -1 => {
+                    Err(IoError {
+                        kind: OtherIoError,
+                        desc: "Failed to lseek.",
+                        detail: None
+                    })
+                },
+                n => Ok(n as u64)
+            }
+        }
+    }
+}
+
+impl Drop for UvFileStream {
+    fn drop(&self) {
+        let self_ = unsafe { transmute::<&UvFileStream, &mut UvFileStream>(self) };
+        if self.close_on_drop {
+            do self_.home_for_io_with_sched |self_, scheduler| {
+                do scheduler.deschedule_running_task_and_then |_, task| {
+                    let task_cell = Cell::new(task);
+                    do self_.fd.close(&self.loop_) |_,_| {
+                        let scheduler = Local::take::<Scheduler>();
+                        scheduler.resume_blocked_task_immediately(task_cell.take());
+                    };
+                };
+            }
+        }
+    }
+}
+
+impl RtioFileStream for UvFileStream {
+    fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
+        self.base_read(buf, -1)
+    }
+    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
+        self.base_write(buf, -1)
+    }
+    fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
+        self.base_read(buf, offset as i64)
+    }
+    fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
+        self.base_write(buf, offset as i64)
+    }
+    fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError> {
+        use libc::{SEEK_SET, SEEK_CUR, SEEK_END};
+        let whence = match whence {
+            SeekSet => SEEK_SET,
+            SeekCur => SEEK_CUR,
+            SeekEnd => SEEK_END
+        };
+        self.seek_common(pos, whence)
+    }
+    fn tell(&self) -> Result<u64, IoError> {
+        use libc::SEEK_CUR;
+        // this is temporary
+        let self_ = unsafe { cast::transmute::<&UvFileStream, &mut UvFileStream>(self) };
+        self_.seek_common(0, SEEK_CUR)
+    }
+    fn flush(&mut self) -> Result<(), IoError> {
+        Ok(())
+    }
+}
+
 #[test]
 fn test_simple_io_no_connect() {
     do run_in_newsched_task {
@@ -1052,14 +1310,16 @@ fn test_simple_homed_udp_io_bind_then_move_task_then_home_and_close() {
             assert!(maybe_socket.is_ok());
 
             // block self on sched1
-            let scheduler = Local::take::<Scheduler>();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                // unblock task
-                do task.wake().map_move |task| {
-                  // send self to sched2
-                  tasksFriendHandle.take().send(TaskFromFriend(task));
-                };
-                // sched1 should now sleep since it has nothing else to do
+            do task::unkillable { // FIXME(#8674)
+                let scheduler = Local::take::<Scheduler>();
+                do scheduler.deschedule_running_task_and_then |_, task| {
+                    // unblock task
+                    do task.wake().map_move |task| {
+                      // send self to sched2
+                      tasksFriendHandle.take().send(TaskFromFriend(task));
+                    };
+                    // sched1 should now sleep since it has nothing else to do
+                }
             }
             // sched2 will wake up and get the task
             // as we do nothing else, the function ends and the socket goes out of scope
@@ -1327,13 +1587,15 @@ fn test_read_and_block() {
                 }
                 reads += 1;
 
-                let scheduler = Local::take::<Scheduler>();
-                // Yield to the other task in hopes that it
-                // will trigger a read callback while we are
-                // not ready for it
-                do scheduler.deschedule_running_task_and_then |sched, task| {
-                    let task = Cell::new(task);
-                    sched.enqueue_blocked_task(task.take());
+                do task::unkillable { // FIXME(#8674)
+                    let scheduler = Local::take::<Scheduler>();
+                    // Yield to the other task in hopes that it
+                    // will trigger a read callback while we are
+                    // not ready for it
+                    do scheduler.deschedule_running_task_and_then |sched, task| {
+                        let task = Cell::new(task);
+                        sched.enqueue_blocked_task(task.take());
+                    }
                 }
             }
 
@@ -1498,3 +1760,60 @@ fn test_timer_sleep_simple() {
         }
     }
 }
+
+fn file_test_uvio_full_simple_impl() {
+    use str::StrSlice; // why does this have to be explicitly imported to work?
+                       // compiler was complaining about no trait for str that
+                       // does .as_bytes() ..
+    use path::Path;
+    use rt::io::{Open, Create, ReadWrite, Read};
+    unsafe {
+        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        let write_val = "hello uvio!";
+        let path = "./tmp/file_test_uvio_full.txt";
+        {
+            let create_fm = Create;
+            let create_fa = ReadWrite;
+            let mut fd = (*io).fs_open(&Path(path), create_fm, create_fa).unwrap();
+            let write_buf = write_val.as_bytes();
+            fd.write(write_buf);
+        }
+        {
+            let ro_fm = Open;
+            let ro_fa = Read;
+            let mut fd = (*io).fs_open(&Path(path), ro_fm, ro_fa).unwrap();
+            let mut read_vec = [0, .. 1028];
+            let nread = fd.read(read_vec).unwrap();
+            let read_val = str::from_bytes(read_vec.slice(0, nread as uint));
+            assert!(read_val == write_val.to_owned());
+        }
+        (*io).fs_unlink(&Path(path));
+    }
+}
+
+#[test]
+fn file_test_uvio_full_simple() {
+    do run_in_newsched_task {
+        file_test_uvio_full_simple_impl();
+    }
+}
+
+fn uvio_naive_print(input: &str) {
+    use str::StrSlice;
+    unsafe {
+        use libc::{STDOUT_FILENO};
+        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        {
+            let mut fd = (*io).fs_from_raw_fd(STDOUT_FILENO, false);
+            let write_buf = input.as_bytes();
+            fd.write(write_buf);
+        }
+    }
+}
+
+#[test]
+fn file_test_uvio_write_to_stdout() {
+    do run_in_newsched_task {
+        uvio_naive_print("jubilation\n");
+    }
+}
diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs
index 0ea2175336a..1e189e90885 100644
--- a/src/libstd/rt/uv/uvll.rs
+++ b/src/libstd/rt/uv/uvll.rs
@@ -31,6 +31,8 @@
 
 use c_str::ToCStr;
 use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
+#[cfg(not(stage0))]
+use libc::ssize_t;
 use libc::{malloc, free};
 use libc;
 use prelude::*;
@@ -63,6 +65,7 @@ pub type uv_idle_t = c_void;
 pub type uv_tcp_t = c_void;
 pub type uv_udp_t = c_void;
 pub type uv_connect_t = c_void;
+pub type uv_connection_t = c_void;
 pub type uv_write_t = c_void;
 pub type uv_async_t = c_void;
 pub type uv_timer_t = c_void;
@@ -70,10 +73,70 @@ pub type uv_stream_t = c_void;
 pub type uv_fs_t = c_void;
 pub type uv_udp_send_t = c_void;
 
+#[cfg(stage0)]
 pub type uv_idle_cb = *u8;
+#[cfg(stage0)]
 pub type uv_alloc_cb = *u8;
+#[cfg(stage0)]
+pub type uv_read_cb = *u8;
+#[cfg(stage0)]
 pub type uv_udp_send_cb = *u8;
+#[cfg(stage0)]
 pub type uv_udp_recv_cb = *u8;
+#[cfg(stage0)]
+pub type uv_close_cb = *u8;
+#[cfg(stage0)]
+pub type uv_walk_cb = *u8;
+#[cfg(stage0)]
+pub type uv_async_cb = *u8;
+#[cfg(stage0)]
+pub type uv_connect_cb = *u8;
+#[cfg(stage0)]
+pub type uv_connection_cb = *u8;
+#[cfg(stage0)]
+pub type uv_timer_cb = *u8;
+#[cfg(stage0)]
+pub type uv_write_cb = *u8;
+
+#[cfg(not(stage0))]
+pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
+                                    status: c_int);
+#[cfg(not(stage0))]
+pub type uv_alloc_cb = extern "C" fn(stream: *uv_stream_t,
+                                     suggested_size: size_t) -> uv_buf_t;
+#[cfg(not(stage0))]
+pub type uv_read_cb = extern "C" fn(stream: *uv_stream_t,
+                                    nread: ssize_t,
+                                    buf: uv_buf_t);
+#[cfg(not(stage0))]
+pub type uv_udp_send_cb = extern "C" fn(req: *uv_udp_send_t,
+                                        status: c_int);
+#[cfg(not(stage0))]
+pub type uv_udp_recv_cb = extern "C" fn(handle: *uv_udp_t,
+                                        nread: ssize_t,
+                                        buf: uv_buf_t,
+                                        addr: *sockaddr,
+                                        flags: c_uint);
+#[cfg(not(stage0))]
+pub type uv_close_cb = extern "C" fn(handle: *uv_handle_t);
+#[cfg(not(stage0))]
+pub type uv_walk_cb = extern "C" fn(handle: *uv_handle_t,
+                                    arg: *c_void);
+#[cfg(not(stage0))]
+pub type uv_async_cb = extern "C" fn(handle: *uv_async_t,
+                                     status: c_int);
+#[cfg(not(stage0))]
+pub type uv_connect_cb = extern "C" fn(handle: *uv_connect_t,
+                                       status: c_int);
+#[cfg(not(stage0))]
+pub type uv_connection_cb = extern "C" fn(handle: *uv_connection_t,
+                                          status: c_int);
+#[cfg(not(stage0))]
+pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t,
+                                     status: c_int);
+#[cfg(not(stage0))]
+pub type uv_write_cb = extern "C" fn(handle: *uv_write_t,
+                                     status: c_int);
 
 pub type sockaddr = c_void;
 pub type sockaddr_in = c_void;
@@ -191,13 +254,13 @@ pub unsafe fn run(loop_handle: *c_void) {
     rust_uv_run(loop_handle);
 }
 
-pub unsafe fn close<T>(handle: *T, cb: *u8) {
+pub unsafe fn close<T>(handle: *T, cb: uv_close_cb) {
     #[fixed_stack_segment]; #[inline(never)];
 
     rust_uv_close(handle as *c_void, cb);
 }
 
-pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) {
+pub unsafe fn walk(loop_handle: *c_void, cb: uv_walk_cb, arg: *c_void) {
     #[fixed_stack_segment]; #[inline(never)];
 
     rust_uv_walk(loop_handle, cb, arg);
@@ -332,14 +395,14 @@ pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
 }
 
 pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
-                          addr_ptr: *sockaddr_in, after_connect_cb: *u8) -> c_int {
+                          addr_ptr: *sockaddr_in, after_connect_cb: uv_connect_cb) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
     return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
 }
 
 pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
-                           addr_ptr: *sockaddr_in6, after_connect_cb: *u8) -> c_int {
+                           addr_ptr: *sockaddr_in6, after_connect_cb: uv_connect_cb) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
     return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
@@ -387,7 +450,8 @@ pub unsafe fn tcp_simultaneous_accepts(handle: *uv_tcp_t, enable: c_int) -> c_in
     return rust_uv_tcp_simultaneous_accepts(handle, enable);
 }
 
-pub unsafe fn listen<T>(stream: *T, backlog: c_int, cb: *u8) -> c_int {
+pub unsafe fn listen<T>(stream: *T, backlog: c_int,
+                        cb: uv_connection_cb) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
     return rust_uv_listen(stream as *c_void, backlog, cb);
@@ -399,14 +463,19 @@ pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
     return rust_uv_accept(server as *c_void, client as *c_void);
 }
 
-pub unsafe fn write<T>(req: *uv_write_t, stream: *T, buf_in: &[uv_buf_t], cb: *u8) -> c_int {
+pub unsafe fn write<T>(req: *uv_write_t,
+                       stream: *T,
+                       buf_in: &[uv_buf_t],
+                       cb: uv_write_cb) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
     let buf_ptr = vec::raw::to_ptr(buf_in);
     let buf_cnt = buf_in.len() as i32;
     return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
 }
-pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: uv_alloc_cb, on_read: *u8) -> c_int {
+pub unsafe fn read_start(stream: *uv_stream_t,
+                         on_alloc: uv_alloc_cb,
+                         on_read: uv_read_cb) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
     return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
@@ -435,7 +504,9 @@ pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
     return rust_uv_err_name(err);
 }
 
-pub unsafe fn async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int {
+pub unsafe fn async_init(loop_handle: *c_void,
+                         async_handle: *uv_async_t,
+                         cb: uv_async_cb) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
     return rust_uv_async_init(loop_handle, async_handle, cb);
@@ -460,7 +531,8 @@ pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
 
     return rust_uv_timer_init(loop_ptr, timer_ptr);
 }
-pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: u64,
+pub unsafe fn timer_start(timer_ptr: *uv_timer_t,
+                          cb: uv_timer_cb, timeout: u64,
                           repeat: u64) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
 
@@ -545,7 +617,54 @@ pub unsafe fn ip6_port(addr: *sockaddr_in6) -> c_uint {
     return rust_uv_ip6_port(addr);
 }
 
+pub unsafe fn fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, flags: int, mode: int,
+                cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_fs_open(loop_ptr, req, path, flags as c_int, mode as c_int, cb)
+}
+
+pub unsafe fn fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
+                cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_fs_unlink(loop_ptr, req, path, cb)
+}
+pub unsafe fn fs_write(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
+                       len: uint, offset: i64, cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_fs_write(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
+}
+pub unsafe fn fs_read(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
+                       len: uint, offset: i64, cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_fs_read(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
+}
+pub unsafe fn fs_close(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int,
+                cb: *u8) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_fs_close(loop_ptr, req, fd, cb)
+}
+pub unsafe fn fs_req_cleanup(req: *uv_fs_t) {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_fs_req_cleanup(req);
+}
+
 // data access helpers
+pub unsafe fn get_result_from_fs_req(req: *uv_fs_t) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_get_result_from_fs_req(req)
+}
+pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_get_loop_from_fs_req(req)
+}
 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
     #[fixed_stack_segment]; #[inline(never)];
 
@@ -634,8 +753,8 @@ extern {
     fn rust_uv_loop_new() -> *c_void;
     fn rust_uv_loop_delete(lp: *c_void);
     fn rust_uv_run(loop_handle: *c_void);
-    fn rust_uv_close(handle: *c_void, cb: *u8);
-    fn rust_uv_walk(loop_handle: *c_void, cb: *u8, arg: *c_void);
+    fn rust_uv_close(handle: *c_void, cb: uv_close_cb);
+    fn rust_uv_walk(loop_handle: *c_void, cb: uv_walk_cb, arg: *c_void);
 
     fn rust_uv_idle_new() -> *uv_idle_t;
     fn rust_uv_idle_delete(handle: *uv_idle_t);
@@ -644,7 +763,9 @@ extern {
     fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int;
 
     fn rust_uv_async_send(handle: *uv_async_t);
-    fn rust_uv_async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int;
+    fn rust_uv_async_init(loop_handle: *c_void,
+                          async_handle: *uv_async_t,
+                          cb: uv_async_cb) -> c_int;
     fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
     fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t);
     fn rust_uv_last_error(loop_handle: *c_void) -> uv_err_t;
@@ -658,10 +779,12 @@ extern {
     fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int;
     fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
     fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
-    fn rust_uv_tcp_connect(req: *uv_connect_t, handle: *uv_tcp_t, cb: *u8,
+    fn rust_uv_tcp_connect(req: *uv_connect_t, handle: *uv_tcp_t,
+                           cb: uv_connect_cb,
                            addr: *sockaddr_in) -> c_int;
     fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int;
-    fn rust_uv_tcp_connect6(req: *uv_connect_t, handle: *uv_tcp_t, cb: *u8,
+    fn rust_uv_tcp_connect6(req: *uv_connect_t, handle: *uv_tcp_t,
+                            cb: uv_connect_cb,
                             addr: *sockaddr_in6) -> c_int;
     fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int;
     fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
@@ -674,10 +797,12 @@ extern {
     fn rust_uv_udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int;
     fn rust_uv_udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int;
     fn rust_uv_udp_send(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
-                        buf_cnt: c_int, addr: *sockaddr_in, cb: *u8) -> c_int;
+                        buf_cnt: c_int, addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int;
     fn rust_uv_udp_send6(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
-                         buf_cnt: c_int, addr: *sockaddr_in6, cb: *u8) -> c_int;
-    fn rust_uv_udp_recv_start(server: *uv_udp_t, on_alloc: *u8, on_recv: *u8) -> c_int;
+                         buf_cnt: c_int, addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int;
+    fn rust_uv_udp_recv_start(server: *uv_udp_t,
+                              on_alloc: uv_alloc_cb,
+                              on_recv: uv_udp_recv_cb) -> c_int;
     fn rust_uv_udp_recv_stop(server: *uv_udp_t) -> c_int;
     fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t;
     fn rust_uv_udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int;
@@ -693,16 +818,32 @@ extern {
     fn rust_uv_malloc_sockaddr_storage() -> *sockaddr_storage;
     fn rust_uv_free_sockaddr_storage(ss: *sockaddr_storage);
 
-    fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int;
+    fn rust_uv_listen(stream: *c_void, backlog: c_int,
+                      cb: uv_connection_cb) -> c_int;
     fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
     fn rust_uv_write(req: *c_void, stream: *c_void, buf_in: *uv_buf_t, buf_cnt: c_int,
-                     cb: *u8) -> c_int;
-    fn rust_uv_read_start(stream: *c_void, on_alloc: *u8, on_read: *u8) -> c_int;
+                     cb: uv_write_cb) -> c_int;
+    fn rust_uv_read_start(stream: *c_void,
+                          on_alloc: uv_alloc_cb,
+                          on_read: uv_read_cb) -> c_int;
     fn rust_uv_read_stop(stream: *c_void) -> c_int;
     fn rust_uv_timer_init(loop_handle: *c_void, timer_handle: *uv_timer_t) -> c_int;
-    fn rust_uv_timer_start(timer_handle: *uv_timer_t, cb: *u8, timeout: libc::uint64_t,
+    fn rust_uv_timer_start(timer_handle: *uv_timer_t, cb: uv_timer_cb, timeout: libc::uint64_t,
                            repeat: libc::uint64_t) -> c_int;
     fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
+    fn rust_uv_fs_open(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
+                       flags: c_int, mode: c_int, cb: *u8) -> c_int;
+    fn rust_uv_fs_unlink(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
+                       cb: *u8) -> c_int;
+    fn rust_uv_fs_write(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
+                       buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
+    fn rust_uv_fs_read(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
+                       buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
+    fn rust_uv_fs_close(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
+                        cb: *u8) -> c_int;
+    fn rust_uv_fs_req_cleanup(req: *uv_fs_t);
+    fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
+    fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t;
 
     fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
     fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index eeaee4c14a5..7fc2deff97d 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -949,7 +949,7 @@ fn waitpid(pid: pid_t) -> int {
 #[cfg(test)]
 mod tests {
     use io;
-    use libc::{c_int, uintptr_t};
+    use libc::c_int;
     use option::{Option, None, Some};
     use os;
     use path::Path;
diff --git a/src/libstd/select.rs b/src/libstd/select.rs
index f537a1f6c33..531d55f6043 100644
--- a/src/libstd/select.rs
+++ b/src/libstd/select.rs
@@ -136,7 +136,7 @@ mod test {
     use cell::Cell;
     use iterator::{Iterator, range};
 
-    #[test] #[ignore(cfg(windows))] #[should_fail]
+    #[test] #[should_fail]
     fn select_doesnt_get_trolled() {
         select::<PortOne<()>>([]);
     }
@@ -316,7 +316,7 @@ mod test {
         }
     }
 
-    #[test] #[ignore(cfg(windows))]
+    #[test]
     fn select_killed() {
         do run_in_newsched_task {
             let (success_p, success_c) = oneshot::<bool>();
diff --git a/src/libstd/std.rs b/src/libstd/std.rs
index 7f22f44a6f8..278df5b170e 100644
--- a/src/libstd/std.rs
+++ b/src/libstd/std.rs
@@ -198,7 +198,7 @@ mod unicode;
 #[path = "num/cmath.rs"]
 mod cmath;
 
-// XXX: This shouldn't be pub, and it should be reexported under 'unstable'
+// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
 // but name resolution doesn't work without it being pub.
 pub mod rt;
 
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 0dd84fd3443..bee354a0a5d 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
- * String manipulation
- *
- * Strings are a packed UTF-8 representation of text, stored as null
- * terminated buffers of u8 bytes.  Strings should be indexed in bytes,
- * for efficiency, but UTF-8 unsafe operations should be avoided.
- */
+//! String manipulation
+//!
+//! Strings are a packed UTF-8 representation of text, stored as
+//! buffers of u8 bytes. The buffer is not null terminated.
+//! Strings should be indexed in bytes, for efficiency, but UTF-8 unsafe
+//! operations should be avoided.
 
 use at_vec;
 use cast;
@@ -24,10 +23,10 @@ use clone::{Clone, DeepClone};
 use container::{Container, Mutable};
 use iter::Times;
 use iterator::{Iterator, FromIterator, Extendable};
-use iterator::{Filter, AdditiveIterator, Map};
+use iterator::{Filter, AdditiveIterator, Map, Enumerate};
 use iterator::{Invert, DoubleEndedIterator};
 use libc;
-use num::Zero;
+use num::{Saturating, Zero};
 use option::{None, Option, Some};
 use ptr;
 use ptr::RawPtr;
@@ -255,56 +254,101 @@ impl<'self, C: CharEq> CharEq for &'self [C] {
 Section: Iterators
 */
 
-/// External iterator for a string's characters and their byte offsets.
+/// External iterator for a string's characters.
 /// Use with the `std::iterator` module.
 #[deriving(Clone)]
-pub struct CharOffsetIterator<'self> {
-    priv index_front: uint,
-    priv index_back: uint,
+pub struct CharIterator<'self> {
+    /// The slice remaining to be iterated
     priv string: &'self str,
 }
 
-impl<'self> Iterator<(uint, char)> for CharOffsetIterator<'self> {
+impl<'self> Iterator<char> for CharIterator<'self> {
     #[inline]
-    fn next(&mut self) -> Option<(uint, char)> {
-        if self.index_front < self.index_back {
-            let CharRange {ch, next} = self.string.char_range_at(self.index_front);
-            let index = self.index_front;
-            self.index_front = next;
-            Some((index, ch))
+    fn next(&mut self) -> Option<char> {
+        // Decode the next codepoint, then update
+        // the slice to be just the remaining part
+        if self.string.len() != 0 {
+            let CharRange {ch, next} = self.string.char_range_at(0);
+            unsafe {
+                self.string = raw::slice_unchecked(self.string, next, self.string.len());
+            }
+            Some(ch)
         } else {
             None
         }
     }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (self.string.len().saturating_add(3)/4, Some(self.string.len()))
+    }
 }
 
-impl<'self> DoubleEndedIterator<(uint, char)> for CharOffsetIterator<'self> {
+impl<'self> DoubleEndedIterator<char> for CharIterator<'self> {
     #[inline]
-    fn next_back(&mut self) -> Option<(uint, char)> {
-        if self.index_front < self.index_back {
-            let CharRange {ch, next} = self.string.char_range_at_reverse(self.index_back);
-            self.index_back = next;
-            Some((next, ch))
+    fn next_back(&mut self) -> Option<char> {
+        if self.string.len() != 0 {
+            let CharRange {ch, next} = self.string.char_range_at_reverse(self.string.len());
+            unsafe {
+                self.string = raw::slice_unchecked(self.string, 0, next);
+            }
+            Some(ch)
         } else {
             None
         }
     }
 }
 
-/// External iterator for a string's characters and their byte offsets in reverse order.
-/// Use with the `std::iterator` module.
-pub type CharOffsetRevIterator<'self> =
-    Invert<CharOffsetIterator<'self>>;
 
-/// External iterator for a string's characters.
+/// External iterator for a string's characters and their byte offsets.
 /// Use with the `std::iterator` module.
-pub type CharIterator<'self> =
-    Map<'self, (uint, char), char, CharOffsetIterator<'self>>;
+#[deriving(Clone)]
+pub struct CharOffsetIterator<'self> {
+    /// The original string to be iterated
+    priv string: &'self str,
+    priv iter: CharIterator<'self>,
+}
+
+impl<'self> Iterator<(uint, char)> for CharOffsetIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<(uint, char)> {
+        // Compute the byte offset by using the pointer offset between
+        // the original string slice and the iterator's remaining part
+        let offset = do self.string.as_imm_buf |a, _| {
+            do self.iter.string.as_imm_buf |b, _| {
+                b as uint - a as uint
+            }
+        };
+        self.iter.next().map_move(|ch| (offset, ch))
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<'self> DoubleEndedIterator<(uint, char)> for CharOffsetIterator<'self> {
+    #[inline]
+    fn next_back(&mut self) -> Option<(uint, char)> {
+        self.iter.next_back().map_move(|ch| {
+            let offset = do self.string.as_imm_buf |a, _| {
+                do self.iter.string.as_imm_buf |b, len| {
+                    b as uint - a as uint + len
+                }
+            };
+            (offset, ch)
+        })
+    }
+}
 
 /// External iterator for a string's characters in reverse order.
 /// Use with the `std::iterator` module.
-pub type CharRevIterator<'self> =
-    Invert<Map<'self, (uint, char), char, CharOffsetIterator<'self>>>;
+pub type CharRevIterator<'self> = Invert<CharIterator<'self>>;
+
+/// External iterator for a string's characters and their byte offsets in reverse order.
+/// Use with the `std::iterator` module.
+pub type CharOffsetRevIterator<'self> = Invert<CharOffsetIterator<'self>>;
 
 /// External iterator for a string's bytes.
 /// Use with the `std::iterator` module.
@@ -313,12 +357,20 @@ pub type ByteIterator<'self> =
 
 /// External iterator for a string's bytes in reverse order.
 /// Use with the `std::iterator` module.
-pub type ByteRevIterator<'self> =
-    Invert<Map<'self, &'self u8, u8, vec::VecIterator<'self, u8>>>;
+pub type ByteRevIterator<'self> = Invert<ByteIterator<'self>>;
+
+/// An iterator over byte index and either &u8 or char
+#[deriving(Clone)]
+enum OffsetIterator<'self> {
+    // use ByteIterator here when it can be cloned
+    ByteOffset(Enumerate<vec::VecIterator<'self, u8>>),
+    CharOffset(CharOffsetIterator<'self>),
+}
 
 /// An iterator over the substrings of a string, separated by `sep`.
 #[deriving(Clone)]
 pub struct CharSplitIterator<'self,Sep> {
+    priv iter: OffsetIterator<'self>,
     priv string: &'self str,
     priv position: uint,
     priv sep: Sep,
@@ -327,7 +379,6 @@ pub struct CharSplitIterator<'self,Sep> {
     /// Whether an empty string at the end is allowed
     priv allow_trailing_empty: bool,
     priv finished: bool,
-    priv only_ascii: bool
 }
 
 /// An iterator over the words of a string, separated by an sequence of whitespace
@@ -343,39 +394,39 @@ impl<'self, Sep: CharEq> Iterator<&'self str> for CharSplitIterator<'self, Sep>
     fn next(&mut self) -> Option<&'self str> {
         if self.finished { return None }
 
-        let l = self.string.len();
         let start = self.position;
-
-        if self.only_ascii {
-            // this gives a *huge* speed up for splitting on ASCII
-            // characters (e.g. '\n' or ' ')
-            while self.position < l && self.count > 0 {
-                let byte = self.string[self.position];
-
-                if self.sep.matches(byte as char) {
-                    let slice = unsafe { raw::slice_bytes(self.string, start, self.position) };
-                    self.position += 1;
-                    self.count -= 1;
-                    return Some(slice);
-                }
-                self.position += 1;
-            }
-        } else {
-            while self.position < l && self.count > 0 {
-                let CharRange {ch, next} = self.string.char_range_at(self.position);
-
-                if self.sep.matches(ch) {
-                    let slice = unsafe { raw::slice_bytes(self.string, start, self.position) };
-                    self.position = next;
-                    self.count -= 1;
-                    return Some(slice);
-                }
-                self.position = next;
+        let len = self.string.len();
+
+        if self.count > 0 {
+            match self.iter {
+                // this gives a *huge* speed up for splitting on ASCII
+                // characters (e.g. '\n' or ' ')
+                ByteOffset(ref mut iter) =>
+                    for (idx, &byte) in *iter {
+                        if self.sep.matches(byte as char) {
+                            self.position = idx + 1;
+                            self.count -= 1;
+                            return Some(unsafe {
+                                raw::slice_bytes(self.string, start, idx)
+                            })
+                        }
+                    },
+                CharOffset(ref mut iter) =>
+                    for (idx, ch) in *iter {
+                        if self.sep.matches(ch) {
+                            // skip over the separator
+                            self.position = self.string.char_range_at(idx).next;
+                            self.count -= 1;
+                            return Some(unsafe {
+                                raw::slice_bytes(self.string, start, idx)
+                            })
+                        }
+                    },
             }
         }
         self.finished = true;
-        if self.allow_trailing_empty || start < l {
-            Some(unsafe { raw::slice_bytes(self.string, start, l) })
+        if self.allow_trailing_empty || start < len {
+            Some(unsafe { raw::slice_bytes(self.string, start, len) })
         } else {
             None
         }
@@ -938,12 +989,21 @@ pub mod raw {
     /// If end is greater than the length of the string.
     #[inline]
     pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
-        do s.as_imm_buf |sbuf, n| {
-             assert!((begin <= end));
-             assert!((end <= n));
+        assert!(begin <= end);
+        assert!(end <= s.len());
+        slice_unchecked(s, begin, end)
+    }
 
+    /// Takes a bytewise (not UTF-8) slice from a string.
+    ///
+    /// Returns the substring from [`begin`..`end`).
+    ///
+    /// Caller must check slice boundaries!
+    #[inline]
+    pub unsafe fn slice_unchecked<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
+        do s.as_imm_buf |sbuf, _n| {
              cast::transmute(Slice {
-                 data: ptr::offset(sbuf, begin as int),
+                 data: sbuf.offset_inbounds(begin as int),
                  len: end - begin,
              })
         }
@@ -1302,7 +1362,7 @@ impl<'self> StrSlice<'self> for &'self str {
     /// ~~~
     #[inline]
     fn iter(&self) -> CharIterator<'self> {
-        self.char_offset_iter().map(|(_, c)| c)
+        CharIterator{string: *self}
     }
 
     /// An iterator over the characters of `self`, in reverse order.
@@ -1326,14 +1386,11 @@ impl<'self> StrSlice<'self> for &'self str {
     /// An iterator over the characters of `self` and their byte offsets.
     #[inline]
     fn char_offset_iter(&self) -> CharOffsetIterator<'self> {
-        CharOffsetIterator {
-            index_front: 0,
-            index_back: self.len(),
-            string: *self
-        }
+        CharOffsetIterator{string: *self, iter: self.iter()}
     }
 
-    /// An iterator over the characters of `self` and their byte offsets.
+    /// An iterator over the characters of `self` and their byte offsets,
+    /// in reverse order.
     #[inline]
     fn char_offset_rev_iter(&self) -> CharOffsetRevIterator<'self> {
         self.char_offset_iter().invert()
@@ -1371,15 +1428,19 @@ impl<'self> StrSlice<'self> for &'self str {
     #[inline]
     fn split_options_iter<Sep: CharEq>(&self, sep: Sep, count: uint, allow_trailing_empty: bool)
         -> CharSplitIterator<'self, Sep> {
-        let only_ascii = sep.only_ascii();
+        let iter = if sep.only_ascii() {
+            ByteOffset(self.as_bytes().iter().enumerate())
+        } else {
+            CharOffset(self.char_offset_iter())
+        };
         CharSplitIterator {
+            iter: iter,
             string: *self,
             position: 0,
             sep: sep,
             count: count,
             allow_trailing_empty: allow_trailing_empty,
             finished: false,
-            only_ascii: only_ascii
         }
     }
 
@@ -1481,8 +1542,7 @@ impl<'self> StrSlice<'self> for &'self str {
     /// beyond the last character of the string
     #[inline]
     fn slice(&self, begin: uint, end: uint) -> &'self str {
-        assert!(self.is_char_boundary(begin));
-        assert!(self.is_char_boundary(end));
+        assert!(self.is_char_boundary(begin) && self.is_char_boundary(end));
         unsafe { raw::slice_bytes(*self, begin, end) }
     }
 
@@ -1502,7 +1562,8 @@ impl<'self> StrSlice<'self> for &'self str {
     /// out of bounds.
     #[inline]
     fn slice_to(&self, end: uint) -> &'self str {
-        self.slice(0, end)
+        assert!(self.is_char_boundary(end));
+        unsafe { raw::slice_bytes(*self, 0, end) }
     }
 
     /// Returns a slice of the string from the char range
@@ -1512,23 +1573,24 @@ impl<'self> StrSlice<'self> for &'self str {
     /// beyond the last character of the string.
     fn slice_chars(&self, begin: uint, end: uint) -> &'self str {
         assert!(begin <= end);
-        // not sure how to use the iterators for this nicely.
-        let mut position = 0;
         let mut count = 0;
-        let l = self.len();
-        while count < begin && position < l {
-            position = self.char_range_at(position).next;
+        let mut begin_byte = None;
+        let mut end_byte = None;
+
+        // This could be even more efficient by not decoding,
+        // only finding the char boundaries
+        for (idx, _) in self.char_offset_iter() {
+            if count == begin { begin_byte = Some(idx); }
+            if count == end { end_byte = Some(idx); break; }
             count += 1;
         }
-        if count < begin { fail!("Attempted to begin slice_chars beyond end of string") }
-        let start_byte = position;
-        while count < end && position < l {
-            position = self.char_range_at(position).next;
-            count += 1;
-        }
-        if count < end { fail!("Attempted to end slice_chars beyond end of string") }
+        if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
 
-        self.slice(start_byte, position)
+        match (begin_byte, end_byte) {
+            (None, _) => fail!("slice_chars: `begin` is beyond end of string"),
+            (_, None) => fail!("slice_chars: `end` is beyond end of string"),
+            (Some(a), Some(b)) => unsafe { raw::slice_bytes(*self, a, b) }
+        }
     }
 
     /// Returns true if `needle` is a prefix of the string.
@@ -1724,6 +1786,7 @@ impl<'self> StrSlice<'self> for &'self str {
 
     /// Returns false if the index points into the middle of a multi-byte
     /// character sequence.
+    #[inline]
     fn is_char_boundary(&self, index: uint) -> bool {
         if index == self.len() { return true; }
         let b = self[index];
@@ -1809,24 +1872,33 @@ impl<'self> StrSlice<'self> for &'self str {
     /// This function can be used to iterate over a unicode string in reverse.
     ///
     /// Returns 0 for next index if called on start index 0.
+    #[inline]
     fn char_range_at_reverse(&self, start: uint) -> CharRange {
         let mut prev = start;
 
-        // while there is a previous byte == 10......
-        while prev > 0u && self[prev - 1u] & 192u8 == TAG_CONT_U8 {
-            prev -= 1u;
-        }
+        prev = prev.saturating_sub(1);
+        if self[prev] < 128 { return CharRange{ch: self[prev] as char, next: prev} }
 
-        // now refer to the initial byte of previous char
-        if prev > 0u {
-            prev -= 1u;
-        } else {
-            prev = 0u;
-        }
+        // Multibyte case is a fn to allow char_range_at_reverse to inline cleanly
+        fn multibyte_char_range_at_rev(s: &str, mut i: uint) -> CharRange {
+            // while there is a previous byte == 10......
+            while i > 0 && s[i] & 192u8 == TAG_CONT_U8 {
+                i -= 1u;
+            }
+
+            let mut val = s[i] as uint;
+            let w = UTF8_CHAR_WIDTH[val] as uint;
+            assert!((w != 0));
+
+            val = utf8_first_byte!(val, w);
+            val = utf8_acc_cont_byte!(val, s[i + 1]);
+            if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
+            if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
 
+            return CharRange {ch: val as char, next: i};
+        }
 
-        let ch = self.char_at(prev);
-        return CharRange {ch:ch, next:prev};
+        return multibyte_char_range_at_rev(*self, prev);
     }
 
     /// Plucks the character ending at the `i`th byte of a string
@@ -1836,8 +1908,6 @@ impl<'self> StrSlice<'self> for &'self str {
     }
 
     /// Work with the byte buffer of a string as a byte slice.
-    ///
-    /// The byte slice does not include the null terminator.
     fn as_bytes(&self) -> &'self [u8] {
         unsafe { cast::transmute(*self) }
     }
@@ -1854,10 +1924,8 @@ impl<'self> StrSlice<'self> for &'self str {
                 if search.matches(b as char) { return Some(i) }
             }
         } else {
-            let mut index = 0;
-            for c in self.iter() {
+            for (index, c) in self.char_offset_iter() {
                 if search.matches(c) { return Some(index); }
-                index += c.len_utf8_bytes();
             }
         }
 
@@ -1871,15 +1939,14 @@ impl<'self> StrSlice<'self> for &'self str {
     /// `Some` containing the byte index of the last matching character
     /// or `None` if there is no match
     fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
-        let mut index = self.len();
         if search.only_ascii() {
+            let mut index = self.len();
             for b in self.byte_rev_iter() {
                 index -= 1;
                 if search.matches(b as char) { return Some(index); }
             }
         } else {
-            for c in self.rev_iter() {
-                index -= c.len_utf8_bytes();
+            for (index, c) in self.char_offset_rev_iter() {
                 if search.matches(c) { return Some(index); }
             }
         }
@@ -2020,10 +2087,7 @@ impl<'self> StrSlice<'self> for &'self str {
 
     /// Work with the byte buffer and length of a slice.
     ///
-    /// The given length is one byte longer than the 'official' indexable
-    /// length of the string. This is to permit probing the byte past the
-    /// indexable area for a null byte, as is the case in slices pointing
-    /// to full strings, or suffixes of them.
+    /// The buffer does not have a null terminator.
     #[inline]
     fn as_imm_buf<T>(&self, f: &fn(*u8, uint) -> T) -> T {
         let v: &[u8] = unsafe { cast::transmute(*self) };
@@ -2043,15 +2107,15 @@ pub trait OwnedStr {
     fn reserve(&mut self, n: uint);
     fn reserve_at_least(&mut self, n: uint);
     fn capacity(&self) -> uint;
+    fn truncate(&mut self, len: uint);
+    fn into_bytes(self) -> ~[u8];
 
     /// Work with the mutable byte buffer and length of a slice.
     ///
-    /// The given length is one byte longer than the 'official' indexable
-    /// length of the string. This is to permit probing the byte past the
-    /// indexable area for a null byte, as is the case in slices pointing
-    /// to full strings, or suffixes of them.
+    /// The buffer does not have a null terminator.
     ///
-    /// Make sure any mutations to this buffer keep this string valid UTF8.
+    /// The caller must make sure any mutations to this buffer keep the string
+    /// valid UTF-8!
     fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T;
 }
 
@@ -2152,12 +2216,10 @@ impl OwnedStr for ~str {
         new_str
     }
 
-    /// Reserves capacity for exactly `n` bytes in the given string, not including
-    /// the null terminator.
+    /// Reserves capacity for exactly `n` bytes in the given string.
     ///
     /// Assuming single-byte characters, the resulting string will be large
-    /// enough to hold a string of length `n`. To account for the null terminator,
-    /// the underlying buffer will have the size `n` + 1.
+    /// enough to hold a string of length `n`.
     ///
     /// If the capacity for `s` is already equal to or greater than the requested
     /// capacity, then no action is taken.
@@ -2177,8 +2239,7 @@ impl OwnedStr for ~str {
     /// Reserves capacity for at least `n` bytes in the given string.
     ///
     /// Assuming single-byte characters, the resulting string will be large
-    /// enough to hold a string of length `n`. To account for the null terminator,
-    /// the underlying buffer will have the size `n` + 1.
+    /// enough to hold a string of length `n`.
     ///
     /// This function will over-allocate in order to amortize the allocation costs
     /// in scenarios where the caller may need to repeatedly reserve additional
@@ -2205,6 +2266,22 @@ impl OwnedStr for ~str {
         }
     }
 
+    /// Shorten a string to the specified length (which must be <= the current length)
+    #[inline]
+    fn truncate(&mut self, len: uint) {
+        assert!(len <= self.len());
+        assert!(self.is_char_boundary(len));
+        unsafe { raw::set_len(self, len); }
+    }
+
+    /// Consumes the string, returning the underlying byte buffer.
+    ///
+    /// The buffer does not have a null terminator.
+    #[inline]
+    fn into_bytes(self) -> ~[u8] {
+        unsafe { cast::transmute(self) }
+    }
+
     #[inline]
     fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T {
         let v: &mut ~[u8] = unsafe { cast::transmute(self) };
@@ -2287,7 +2364,7 @@ mod tests {
     use ptr;
     use str::*;
     use vec;
-    use vec::{ImmutableVector, CopyableVector};
+    use vec::{Vector, ImmutableVector, CopyableVector};
     use cmp::{TotalOrd, Less, Equal, Greater};
 
     #[test]
@@ -2392,7 +2469,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_pop_char_fail() {
         let mut data = ~"";
         let _cc3 = data.pop_char();
@@ -2457,6 +2533,13 @@ mod tests {
     }
 
     #[test]
+    fn test_into_bytes() {
+        let data = ~"asdf";
+        let buf = data.into_bytes();
+        assert_eq!(bytes!("asdf"), buf.as_slice());
+    }
+
+    #[test]
     fn test_find_str() {
         // byte positions
         assert_eq!("".find_str(""), Some(0u));
@@ -2708,7 +2791,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_slice_fail() {
         "中华Việt Nam".slice(0u, 2u);
     }
@@ -2874,7 +2956,6 @@ mod tests {
 
 
     #[test]
-    #[ignore(cfg(windows))]
     fn test_from_bytes_fail() {
         use str::not_utf8::cond;
 
@@ -2924,7 +3005,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))]
     #[should_fail]
     fn test_as_bytes_fail() {
         // Don't double free. (I'm not sure if this exercises the
@@ -3211,6 +3291,14 @@ mod tests {
     }
 
     #[test]
+    fn test_iterator_clone() {
+        let s = "ศไทย中华Việt Nam";
+        let mut it = s.iter();
+        it.next();
+        assert!(it.zip(it.clone()).all(|(x,y)| x == y));
+    }
+
+    #[test]
     fn test_byte_iterator() {
         let s = ~"ศไทย中华Việt Nam";
         let v = [
@@ -3419,12 +3507,100 @@ mod tests {
         assert_eq!(5, sum_len([~"01", ~"2", ~"34", ~""]));
         assert_eq!(5, sum_len([s.as_slice()]));
     }
+
+    #[test]
+    fn test_str_truncate() {
+        let mut s = ~"12345";
+        s.truncate(5);
+        assert_eq!(s.as_slice(), "12345");
+        s.truncate(3);
+        assert_eq!(s.as_slice(), "123");
+        s.truncate(0);
+        assert_eq!(s.as_slice(), "");
+
+        let mut s = ~"12345";
+        let p = s.as_imm_buf(|p,_| p);
+        s.truncate(3);
+        s.push_str("6");
+        let p_ = s.as_imm_buf(|p,_| p);
+        assert_eq!(p_, p);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_str_truncate_invalid_len() {
+        let mut s = ~"12345";
+        s.truncate(6);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_str_truncate_split_codepoint() {
+        let mut s = ~"\u00FC"; // ü
+        s.truncate(1);
+    }
 }
 
 #[cfg(test)]
 mod bench {
     use extra::test::BenchHarness;
     use super::*;
+    use prelude::*;
+
+    #[bench]
+    fn char_iterator(bh: &mut BenchHarness) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        do bh.iter {
+            assert_eq!(s.iter().len(), len);
+        }
+    }
+
+    #[bench]
+    fn char_iterator_ascii(bh: &mut BenchHarness) {
+        let s = "Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        do bh.iter {
+            assert_eq!(s.iter().len(), len);
+        }
+    }
+
+    #[bench]
+    fn char_iterator_rev(bh: &mut BenchHarness) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        do bh.iter {
+            assert_eq!(s.rev_iter().len(), len);
+        }
+    }
+
+    #[bench]
+    fn char_offset_iterator(bh: &mut BenchHarness) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        do bh.iter {
+            assert_eq!(s.char_offset_iter().len(), len);
+        }
+    }
+
+    #[bench]
+    fn char_offset_iterator_rev(bh: &mut BenchHarness) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        do bh.iter {
+            assert_eq!(s.char_offset_rev_iter().len(), len);
+        }
+    }
 
     #[bench]
     fn is_utf8_100_ascii(bh: &mut BenchHarness) {
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index 0d2e62a7700..e76b81a904d 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -543,7 +543,7 @@ pub fn deschedule() {
     use rt::local::Local;
     use rt::sched::Scheduler;
 
-    // XXX: What does yield really mean in newsched?
+    // FIXME #6842: What does yield really mean in newsched?
     // FIXME(#7544): Optimize this, since we know we won't block.
     let sched = Local::take::<Scheduler>();
     do sched.deschedule_running_task_and_then |sched, task| {
@@ -616,7 +616,7 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_kill_unkillable_task() {
     use rt::test::*;
 
@@ -637,7 +637,7 @@ fn test_kill_unkillable_task() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_kill_rekillable_task() {
     use rt::test::*;
 
@@ -658,7 +658,7 @@ fn test_kill_rekillable_task() {
     }
 }
 
-#[test] #[should_fail] #[ignore(cfg(windows))]
+#[test] #[should_fail]
 fn test_cant_dup_task_builder() {
     let mut builder = task();
     builder.unlinked();
@@ -679,7 +679,7 @@ fn test_cant_dup_task_builder() {
 fn block_forever() { let (po, _ch) = stream::<()>(); po.recv(); }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -698,7 +698,7 @@ fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -706,7 +706,7 @@ fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -716,7 +716,7 @@ fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_unlinked_sup_fail_down() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -729,7 +729,7 @@ fn test_spawn_unlinked_sup_fail_down() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -750,7 +750,7 @@ fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -767,7 +767,7 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -780,7 +780,7 @@ fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -793,7 +793,7 @@ fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
     }
 }
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -812,7 +812,7 @@ fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails
 // when the middle task exits successfully early before kill signals are sent.
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_failure_propagate_grandchild() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -829,7 +829,7 @@ fn test_spawn_failure_propagate_grandchild() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_failure_propagate_secondborn() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -846,7 +846,7 @@ fn test_spawn_failure_propagate_secondborn() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_failure_propagate_nephew_or_niece() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -863,7 +863,7 @@ fn test_spawn_failure_propagate_nephew_or_niece() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_linked_sup_propagate_sibling() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -941,7 +941,6 @@ fn test_add_wrapper() {
 }
 
 #[test]
-#[ignore(cfg(windows))]
 fn test_future_result() {
     let mut result = None;
     let mut builder = task();
@@ -959,7 +958,7 @@ fn test_future_result() {
     assert_eq!(result.unwrap().recv(), Failure);
 }
 
-#[test] #[should_fail] #[ignore(cfg(windows))]
+#[test] #[should_fail]
 fn test_back_to_the_future_result() {
     let mut builder = task();
     builder.future_result(util::ignore);
@@ -977,7 +976,6 @@ fn test_try_success() {
 }
 
 #[test]
-#[ignore(cfg(windows))]
 fn test_try_fail() {
     match do try {
         fail!()
@@ -1159,7 +1157,6 @@ fn test_avoid_copying_the_body_unlinked() {
 
 #[ignore(reason = "linked failure")]
 #[test]
-#[ignore(cfg(windows))]
 #[should_fail]
 fn test_unkillable() {
     let (po, ch) = stream();
@@ -1195,7 +1192,6 @@ fn test_unkillable() {
 
 #[ignore(reason = "linked failure")]
 #[test]
-#[ignore(cfg(windows))]
 #[should_fail]
 fn test_unkillable_nested() {
     let (po, ch) = comm::stream();
@@ -1261,7 +1257,7 @@ fn test_simple_newsched_spawn() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_spawn_watched() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
@@ -1284,7 +1280,7 @@ fn test_spawn_watched() {
 }
 
 #[ignore(reason = "linked failure")]
-#[test] #[ignore(cfg(windows))]
+#[test]
 fn test_indestructible() {
     use rt::test::run_in_newsched_task;
     do run_in_newsched_task {
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index e0efc14a887..980141d29c3 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -446,8 +446,7 @@ fn taskgroup_key() -> local_data::Key<@@mut Taskgroup> {
 // Transitionary.
 struct RuntimeGlue;
 impl RuntimeGlue {
-    fn kill_task(handle: KillHandle) {
-        let mut handle = handle;
+    fn kill_task(mut handle: KillHandle) {
         do handle.kill().map_move |killed_task| {
             let killed_task = Cell::new(killed_task);
             do Local::borrow::<Scheduler, ()> |sched| {
@@ -457,44 +456,38 @@ impl RuntimeGlue {
     }
 
     fn with_task_handle_and_failing(blk: &fn(&KillHandle, bool)) {
-        if in_green_task_context() {
-            unsafe {
-                // Can't use safe borrow, because the taskgroup destructor needs to
-                // access the scheduler again to send kill signals to other tasks.
-                let me = Local::unsafe_borrow::<Task>();
-                blk((*me).death.kill_handle.get_ref(), (*me).unwinder.unwinding)
-            }
-        } else {
-            rtabort!("task dying in bad context")
+        rtassert!(in_green_task_context());
+        unsafe {
+            // Can't use safe borrow, because the taskgroup destructor needs to
+            // access the scheduler again to send kill signals to other tasks.
+            let me = Local::unsafe_borrow::<Task>();
+            blk((*me).death.kill_handle.get_ref(), (*me).unwinder.unwinding)
         }
     }
 
     fn with_my_taskgroup<U>(blk: &fn(&Taskgroup) -> U) -> U {
-        if in_green_task_context() {
-            unsafe {
-                // Can't use safe borrow, because creating new hashmaps for the
-                // tasksets requires an rng, which needs to borrow the sched.
-                let me = Local::unsafe_borrow::<Task>();
-                blk(match (*me).taskgroup {
-                    None => {
-                        // First task in its (unlinked/unsupervised) taskgroup.
-                        // Lazily initialize.
-                        let mut members = TaskSet::new();
-                        let my_handle = (*me).death.kill_handle.get_ref().clone();
-                        members.insert(my_handle);
-                        let tasks = Exclusive::new(Some(TaskGroupData {
-                            members: members,
-                            descendants: TaskSet::new(),
-                        }));
-                        let group = Taskgroup(tasks, AncestorList(None), None);
-                        (*me).taskgroup = Some(group);
-                        (*me).taskgroup.get_ref()
-                    }
-                    Some(ref group) => group,
-                })
-            }
-        } else {
-            rtabort!("spawning in bad context")
+        rtassert!(in_green_task_context());
+        unsafe {
+            // Can't use safe borrow, because creating new hashmaps for the
+            // tasksets requires an rng, which needs to borrow the sched.
+            let me = Local::unsafe_borrow::<Task>();
+            blk(match (*me).taskgroup {
+                None => {
+                    // First task in its (unlinked/unsupervised) taskgroup.
+                    // Lazily initialize.
+                    let mut members = TaskSet::new();
+                    let my_handle = (*me).death.kill_handle.get_ref().clone();
+                    members.insert(my_handle);
+                    let tasks = Exclusive::new(Some(TaskGroupData {
+                        members: members,
+                        descendants: TaskSet::new(),
+                    }));
+                    let group = Taskgroup(tasks, AncestorList(None), None);
+                    (*me).taskgroup = Some(group);
+                    (*me).taskgroup.get_ref()
+                }
+                Some(ref group) => group,
+            })
         }
     }
 }
@@ -567,17 +560,11 @@ fn enlist_many(child: &KillHandle, child_arc: &TaskGroupArc,
     result
 }
 
-pub fn spawn_raw(opts: TaskOpts, f: ~fn()) {
-    if in_green_task_context() {
-        spawn_raw_newsched(opts, f)
-    } else {
-        fail!("can't spawn from this context")
-    }
-}
-
-fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
+pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
     use rt::sched::*;
 
+    rtassert!(in_green_task_context());
+
     let child_data = Cell::new(gen_child_taskgroup(opts.linked, opts.supervised));
     let indestructible = opts.indestructible;
 
@@ -722,7 +709,6 @@ fn test_spawn_raw_simple() {
 }
 
 #[test]
-#[ignore(cfg(windows))]
 fn test_spawn_raw_unsupervise() {
     let opts = task::TaskOpts {
         linked: false,
@@ -736,7 +722,6 @@ fn test_spawn_raw_unsupervise() {
 }
 
 #[test]
-#[ignore(cfg(windows))]
 fn test_spawn_raw_notify_success() {
     let (notify_po, notify_ch) = comm::stream();
 
@@ -750,7 +735,6 @@ fn test_spawn_raw_notify_success() {
 }
 
 #[test]
-#[ignore(cfg(windows))]
 fn test_spawn_raw_notify_failure() {
     // New bindings for these
     let (notify_po, notify_ch) = comm::stream();
diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs
index 83c12f0af5e..f2cfd114349 100644
--- a/src/libstd/unstable/extfmt.rs
+++ b/src/libstd/unstable/extfmt.rs
@@ -441,14 +441,12 @@ pub mod ct {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_parse_type_missing() {
         parse_type("", 0, 0, die);
     }
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_parse_type_unknown() {
         parse_type("!", 0, 1, die);
     }
diff --git a/src/libstd/unstable/finally.rs b/src/libstd/unstable/finally.rs
index 7fbe9179f75..42820aaaa95 100644
--- a/src/libstd/unstable/finally.rs
+++ b/src/libstd/unstable/finally.rs
@@ -83,7 +83,6 @@ fn test_success() {
 }
 
 #[test]
-#[ignore(cfg(windows))]
 #[should_fail]
 fn test_fail() {
     let mut i = 0;
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index 29be094121c..6fa0e0eb8c1 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -281,20 +281,24 @@ impl<T> Drop for UnsafeAtomicRcBox<T>{
  */
 // FIXME(#8140) should not be pub
 pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
-    use rt::task::Task;
+    use rt::task::{Task, GreenTask, SchedTask};
     use rt::local::Local;
-    use rt::in_green_task_context;
-
-    if in_green_task_context() {
-        let t = Local::unsafe_borrow::<Task>();
-        do (|| {
-            (*t).death.inhibit_deschedule();
-            f()
-        }).finally {
-            (*t).death.allow_deschedule();
+
+    match Local::try_unsafe_borrow::<Task>() {
+        Some(t) => {
+            match (*t).task_type {
+                GreenTask(_) => {
+                    do (|| {
+                        (*t).death.inhibit_deschedule();
+                        f()
+                    }).finally {
+                        (*t).death.allow_deschedule();
+                    }
+                }
+                SchedTask => f()
+            }
         }
-    } else {
-        f()
+        None => f()
     }
 }
 
@@ -481,7 +485,7 @@ mod tests {
         }
     }
 
-    #[test] #[should_fail] #[ignore(cfg(windows))]
+    #[test] #[should_fail]
     fn exclusive_new_poison() {
         unsafe {
             // Tests that if one task fails inside of an Exclusive::new, subsequent
@@ -599,7 +603,7 @@ mod tests {
         res.unwrap().recv();
     }
 
-    #[test] #[should_fail] #[ignore(cfg(windows))]
+    #[test] #[should_fail]
     fn exclusive_new_unwrap_conflict() {
         let x = Exclusive::new(~~"hello");
         let x2 = Cell::new(x.clone());
@@ -615,7 +619,7 @@ mod tests {
         assert!(res.unwrap().recv() == task::Success);
     }
 
-    #[test] #[ignore(cfg(windows))]
+    #[test]
     fn exclusive_new_unwrap_deadlock() {
         // This is not guaranteed to get to the deadlock before being killed,
         // but it will show up sometimes, and if the deadlock were not there,
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 01e7e053cf5..b743a17b472 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1401,7 +1401,7 @@ impl<T> OwnedVector<T> for ~[T] {
         let self_len = self.len();
         let rhs_len = rhs.len();
         let new_len = self_len + rhs_len;
-        self.reserve(new_len);
+        self.reserve_at_least(new_len);
         unsafe { // Note: infallible.
             let self_p = vec::raw::to_mut_ptr(*self);
             let rhs_p = vec::raw::to_ptr(rhs);
@@ -2521,7 +2521,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_head_empty() {
         let a: ~[int] = ~[];
         a.head();
@@ -2547,7 +2546,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_tail_empty() {
         let a: ~[int] = ~[];
         a.tail();
@@ -2563,7 +2561,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_tailn_empty() {
         let a: ~[int] = ~[];
         a.tailn(2);
@@ -2579,7 +2576,6 @@ mod tests {
 
     #[init]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_init_empty() {
         let a: ~[int] = ~[];
         a.init();
@@ -2595,7 +2591,6 @@ mod tests {
 
     #[init]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_initn_empty() {
         let a: ~[int] = ~[];
         a.initn(2);
@@ -2611,7 +2606,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_last_empty() {
         let a: ~[int] = ~[];
         a.last();
@@ -3079,7 +3073,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))]
     #[should_fail]
     fn test_insert_oob() {
         let mut a = ~[1, 2, 3];
@@ -3102,7 +3095,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))]
     #[should_fail]
     fn test_remove_oob() {
         let mut a = ~[1, 2, 3];
@@ -3130,7 +3122,6 @@ mod tests {
 
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_from_fn_fail() {
         do from_fn(100) |v| {
@@ -3140,7 +3131,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_build_fail() {
         do build |push| {
@@ -3153,7 +3143,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_grow_fn_fail() {
         let mut v = ~[];
@@ -3166,7 +3155,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_map_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3175,13 +3163,12 @@ mod tests {
             if i == 2 {
                 fail!()
             }
-            i += 0;
+            i += 1;
             ~[(~0, @0)]
         };
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_flat_map_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3190,13 +3177,12 @@ mod tests {
             if i == 2 {
                 fail!()
             }
-            i += 0;
+            i += 1;
             ~[(~0, @0)]
         };
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_rposition_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3205,13 +3191,12 @@ mod tests {
             if i == 2 {
                 fail!()
             }
-            i += 0;
+            i += 1;
             false
         };
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_permute_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3220,13 +3205,12 @@ mod tests {
             if i == 2 {
                 fail!()
             }
-            i += 0;
+            i += 1;
             true
         };
     }
 
     #[test]
-    #[ignore(windows)]
     #[should_fail]
     fn test_as_imm_buf_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3236,7 +3220,6 @@ mod tests {
     }
 
     #[test]
-    #[ignore(cfg(windows))]
     #[should_fail]
     fn test_as_mut_buf_fail() {
         let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3247,7 +3230,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_copy_memory_oob() {
         unsafe {
             let mut a = [1, 2, 3, 4];
@@ -3469,7 +3451,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_window_iterator_0() {
         let v = &[1i,2,3,4];
         let _it = v.window_iter(0);
@@ -3494,7 +3475,6 @@ mod tests {
 
     #[test]
     #[should_fail]
-    #[ignore(cfg(windows))]
     fn test_chunk_iterator_0() {
         let v = &[1i,2,3,4];
         let _it = v.chunk_iter(0);