11
11
use prelude:: v1:: * ;
12
12
use io:: prelude:: * ;
13
13
14
+ use cell:: RefCell ;
14
15
use cmp;
15
16
use fmt;
16
17
use io:: lazy:: Lazy ;
17
18
use io:: { self , BufReader , LineWriter } ;
18
19
use sync:: { Arc , Mutex , MutexGuard } ;
19
20
use sys:: stdio;
20
21
22
+ /// Stdout used by print! and println! macroses
23
+ thread_local ! {
24
+ static LOCAL_STDOUT : RefCell <Option <Box <Write + Send >>> = {
25
+ RefCell :: new( None )
26
+ }
27
+ }
28
+
21
29
/// A handle to a raw instance of the standard input stream of this process.
22
30
///
23
31
/// This handle is not synchronized or buffered in any fashion. Constructed via
24
- /// the `std::io::stdin_raw` function.
25
- pub struct StdinRaw ( stdio:: Stdin ) ;
32
+ /// the `std::io::stdio:: stdin_raw` function.
33
+ struct StdinRaw ( stdio:: Stdin ) ;
26
34
27
35
/// A handle to a raw instance of the standard output stream of this process.
28
36
///
29
37
/// This handle is not synchronized or buffered in any fashion. Constructed via
30
- /// the `std::io::stdout_raw` function.
31
- pub struct StdoutRaw ( stdio:: Stdout ) ;
38
+ /// the `std::io::stdio:: stdout_raw` function.
39
+ struct StdoutRaw ( stdio:: Stdout ) ;
32
40
33
41
/// A handle to a raw instance of the standard output stream of this process.
34
42
///
35
43
/// This handle is not synchronized or buffered in any fashion. Constructed via
36
- /// the `std::io::stderr_raw` function.
37
- pub struct StderrRaw ( stdio:: Stderr ) ;
44
+ /// the `std::io::stdio:: stderr_raw` function.
45
+ struct StderrRaw ( stdio:: Stderr ) ;
38
46
39
47
/// Construct a new raw handle to the standard input of this process.
40
48
///
@@ -43,7 +51,7 @@ pub struct StderrRaw(stdio::Stderr);
43
51
/// handles is **not** available to raw handles returned from this function.
44
52
///
45
53
/// The returned handle has no external synchronization or buffering.
46
- pub fn stdin_raw ( ) -> StdinRaw { StdinRaw ( stdio:: Stdin :: new ( ) ) }
54
+ fn stdin_raw ( ) -> StdinRaw { StdinRaw ( stdio:: Stdin :: new ( ) ) }
47
55
48
56
/// Construct a new raw handle to the standard input stream of this process.
49
57
///
@@ -54,7 +62,7 @@ pub fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
54
62
///
55
63
/// The returned handle has no external synchronization or buffering layered on
56
64
/// top.
57
- pub fn stdout_raw ( ) -> StdoutRaw { StdoutRaw ( stdio:: Stdout :: new ( ) ) }
65
+ fn stdout_raw ( ) -> StdoutRaw { StdoutRaw ( stdio:: Stdout :: new ( ) ) }
58
66
59
67
/// Construct a new raw handle to the standard input stream of this process.
60
68
///
@@ -63,7 +71,7 @@ pub fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
63
71
///
64
72
/// The returned handle has no external synchronization or buffering layered on
65
73
/// top.
66
- pub fn stderr_raw ( ) -> StderrRaw { StderrRaw ( stdio:: Stderr :: new ( ) ) }
74
+ fn stderr_raw ( ) -> StderrRaw { StderrRaw ( stdio:: Stderr :: new ( ) ) }
67
75
68
76
impl Read for StdinRaw {
69
77
fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > { self . 0 . read ( buf) }
@@ -109,9 +117,6 @@ pub struct StdinLock<'a> {
109
117
/// The `Read` trait is implemented for the returned value but the `BufRead`
110
118
/// trait is not due to the global nature of the standard input stream. The
111
119
/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
112
- ///
113
- /// To avoid locking and buffering altogether, it is recommended to use the
114
- /// `stdin_raw` constructor.
115
120
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
116
121
pub fn stdin ( ) -> Stdin {
117
122
static INSTANCE : Lazy < Mutex < BufReader < StdinRaw > > > = lazy_init ! ( stdin_init) ;
@@ -224,9 +229,6 @@ pub struct StdoutLock<'a> {
224
229
/// provided via the `lock` method.
225
230
///
226
231
/// The returned handle implements the `Write` trait.
227
- ///
228
- /// To avoid locking and buffering altogether, it is recommended to use the
229
- /// `stdout_raw` constructor.
230
232
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
231
233
pub fn stdout ( ) -> Stdout {
232
234
static INSTANCE : Lazy < Mutex < LineWriter < StdoutRaw > > > = lazy_init ! ( stdout_init) ;
@@ -297,9 +299,6 @@ pub struct StderrLock<'a> {
297
299
/// this function. No handles are buffered, however.
298
300
///
299
301
/// The returned handle implements the `Write` trait.
300
- ///
301
- /// To avoid locking altogether, it is recommended to use the `stderr_raw`
302
- /// constructor.
303
302
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
304
303
pub fn stderr ( ) -> Stderr {
305
304
static INSTANCE : Lazy < Mutex < StderrRaw > > = lazy_init ! ( stderr_init) ;
@@ -347,15 +346,15 @@ impl<'a> Write for StderrLock<'a> {
347
346
fn flush ( & mut self ) -> io:: Result < ( ) > { self . inner . flush ( ) }
348
347
}
349
348
350
- /// Resets the task-local stdout handle to the specified writer
349
+ /// Resets the task-local stderr handle to the specified writer
351
350
///
352
- /// This will replace the current task's stdout handle, returning the old
353
- /// handle. All future calls to `print ` and friends will emit their output to
351
+ /// This will replace the current task's stderr handle, returning the old
352
+ /// handle. All future calls to `panic! ` and friends will emit their output to
354
353
/// this specified handle.
355
354
///
356
355
/// Note that this does not need to be called for all new tasks; the default
357
- /// output handle is to the process's stdout stream.
358
- #[ unstable( feature = "set_panic " ,
356
+ /// output handle is to the process's stderr stream.
357
+ #[ unstable( feature = "set_stdio " ,
359
358
reason = "this function may disappear completely or be replaced \
360
359
with a more general mechanism") ]
361
360
#[ doc( hidden) ]
@@ -369,3 +368,37 @@ pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
369
368
Some ( s)
370
369
} )
371
370
}
371
+
372
+ /// Resets the task-local stdout handle to the specified writer
373
+ ///
374
+ /// This will replace the current task's stdout handle, returning the old
375
+ /// handle. All future calls to `print!` and friends will emit their output to
376
+ /// this specified handle.
377
+ ///
378
+ /// Note that this does not need to be called for all new tasks; the default
379
+ /// output handle is to the process's stdout stream.
380
+ #[ unstable( feature = "set_stdio" ,
381
+ reason = "this function may disappear completely or be replaced \
382
+ with a more general mechanism") ]
383
+ #[ doc( hidden) ]
384
+ pub fn set_print ( sink : Box < Write + Send > ) -> Option < Box < Write + Send > > {
385
+ use mem;
386
+ LOCAL_STDOUT . with ( move |slot| {
387
+ mem:: replace ( & mut * slot. borrow_mut ( ) , Some ( sink) )
388
+ } ) . and_then ( |mut s| {
389
+ let _ = s. flush ( ) ;
390
+ Some ( s)
391
+ } )
392
+ }
393
+
394
+ #[ unstable( feature = "print" ,
395
+ reason = "implementation detail which may disappear or be replaced at any time" ) ]
396
+ #[ doc( hidden) ]
397
+ pub fn _print ( args : fmt:: Arguments ) {
398
+ if let Err ( e) = LOCAL_STDOUT . with ( |s| match s. borrow_mut ( ) . as_mut ( ) {
399
+ Some ( w) => w. write_fmt ( args) ,
400
+ None => stdout ( ) . write_fmt ( args)
401
+ } ) {
402
+ panic ! ( "failed printing to stdout: {}" , e) ;
403
+ }
404
+ }
0 commit comments