Support arbitrary stdout/stderr/logger handles

This will allow capturing of common things like logging messages, stdout prints
(using stdio println), and failure messages (printed to stderr).  Any new prints
added to libstd should be funneled through these task handles to allow capture
as well.

Additionally, this commit redirects logging back through a `Logger` trait so the
log level can be usefully consumed by an arbitrary logger.

This commit also introduces methods to set the task-local stdout handles:

* std::io::stdio::set_stdout
* std::io::stdio::set_stderr
* std::io::logging::set_logger

These methods all return the previous logger just in case it needs to be used
for inspection.

I plan on using this infrastructure for extra::test soon, but we don't quite
have the primitives that I'd like to use for it, so it doesn't migrate
extra::test at this time.

Closes #6369
This commit is contained in:
Alex Crichton
2014-01-06 10:26:11 -08:00
parent a6d3e57dca
commit ac2a24ecc9
10 changed files with 330 additions and 160 deletions

View File

@@ -34,7 +34,7 @@ pub mod io;
pub mod task;
// XXX: this should not exist here
#[cfg(stage0)]
#[cfg(stage0, nativestart)]
#[lang = "start"]
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
use std::cast;

View File

@@ -55,11 +55,15 @@ pub fn spawn(f: proc()) {
pub fn spawn_opts(opts: TaskOpts, f: proc()) {
let TaskOpts {
watched: _watched,
notify_chan, name, stack_size
notify_chan, name, stack_size,
logger, stderr, stdout,
} = opts;
let mut task = ~Task::new();
task.name = name;
task.logger = logger;
task.stderr = stderr;
task.stdout = stdout;
match notify_chan {
Some(chan) => {
let on_exit = proc(task_result) { chan.send(task_result) };