33extern crate chrono;
44extern crate clap;
55extern crate env_logger;
6+ extern crate failure;
67extern crate itm;
78#[ macro_use]
89extern crate log;
910
1011use clap:: { App , Arg , ArgMatches } ;
11- use itm:: error:: { Error , ErrorKind , Result , ResultExt } ;
12- use itm:: { packet, Decoder } ;
12+ use itm:: { packet, Decoder , Error } ;
1313use log:: { LogLevelFilter , LogRecord } ;
1414use std:: fs:: File ;
1515use std:: io:: Write ;
@@ -33,31 +33,14 @@ fn main() {
3333 . init ( )
3434 . unwrap ( ) ;
3535
36- fn show_backtrace ( ) -> bool {
37- env:: var ( "RUST_BACKTRACE" ) . as_ref ( ) . map ( |s| & s[ ..] ) == Ok ( "1" )
38- }
39-
4036 if let Err ( e) = run ( ) {
41- let stderr = io:: stderr ( ) ;
42- let mut stderr = stderr. lock ( ) ;
43-
44- writeln ! ( stderr, "{}" , e) . unwrap ( ) ;
45-
46- for e in e. iter ( ) . skip ( 1 ) {
47- writeln ! ( stderr, "caused by: {}" , e) . unwrap ( ) ;
48- }
49-
50- if show_backtrace ( ) {
51- if let Some ( backtrace) = e. backtrace ( ) {
52- writeln ! ( stderr, "{:?}" , backtrace) . unwrap ( ) ;
53- }
54- }
37+ eprintln ! ( "{}" , e) ;
5538
5639 process:: exit ( 1 )
5740 }
5841}
5942
60- fn run ( ) -> Result < ( ) > {
43+ fn run ( ) -> Result < ( ) , failure :: Error > {
6144 let matches = App :: new ( "itmdump" )
6245 . version ( concat ! (
6346 env!( "CARGO_PKG_VERSION" ) ,
@@ -117,41 +100,39 @@ fn run() -> Result<()> {
117100 }
118101 _ => ( ) ,
119102 } ,
120- Err ( e @ Error ( ErrorKind :: UnknownHeader ( _) , _) ) => {
121- // We don't know this header type; warn and continue.
122- debug ! ( "{}" , e) ;
123- }
124- Err ( Error ( ErrorKind :: EofBeforePacket , _) ) => {
125- if follow {
126- // NOTE 10 ms let us achieve 60 FPS in the worst case scenario
127- thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
103+ Err ( fe) => {
104+ if let Some ( ie) = fe. downcast_ref :: < Error > ( ) . cloned ( ) {
105+ match ie {
106+ Error :: UnknownHeader { byte } => {
107+ // We don't know this header type; warn and continue.
108+ debug ! ( "unknown header byte: {:x}" , byte) ;
109+ }
110+ Error :: EofBeforePacket => {
111+ if follow {
112+ // NOTE 10 ms let us achieve 60 FPS in the worst case scenario
113+ thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
114+ } else {
115+ // !follow and EOF. Exit.
116+ return Ok ( ( ) ) ;
117+ }
118+ }
119+ _ => return Err ( fe. into ( ) ) ,
120+ }
128121 } else {
129- // !follow and EOF. Exit.
130- return Ok ( ( ) ) ;
122+ return Err ( fe) ;
131123 }
132124 }
133-
134- // FIXME: If in follow mode, we may try to read a packet
135- // but reach the end of the file in the middle. Currently
136- // we'd just return an error and hence exit. When we
137- // receive an error, we've already read and discarded some
138- // data, so we can't just go around this loop again.
139- //
140- // We could make a file following wrapper around `read`
141- // that blocks in a loop retrying the read and sleeping if
142- // there's no data.
143- Err ( e) => return Err ( e) ,
144125 }
145126 } // end of read loop
146127
147128 // Unreachable.
148129}
149130
150- fn open_read ( matches : & ArgMatches ) -> Result < Box < io:: Read + ' static > > {
131+ fn open_read ( matches : & ArgMatches ) -> Result < Box < io:: Read + ' static > , io :: Error > {
151132 let path = matches. value_of ( "file" ) ;
152133 Ok ( match path {
153134 Some ( path) => {
154- let f = File :: open ( path) . chain_err ( || format ! ( "Couldn't open source file '{}'" , path ) ) ?;
135+ let f = File :: open ( path) ?;
155136 Box :: new ( f) as Box < io:: Read + ' static >
156137 }
157138 None => Box :: new ( io:: stdin ( ) ) as Box < io:: Read + ' static > ,
0 commit comments