@@ -10,12 +10,11 @@ use std::collections::{HashMap, VecDeque};
1010use std:: ffi:: OsString ;
1111use std:: fs:: File ;
1212use std:: io:: { self , BufRead , BufReader } ;
13- use std:: path:: Path ;
1413use string_interner:: StringInterner ;
1514use string_interner:: backend:: StringBackend ;
1615use thiserror:: Error ;
1716use uucore:: display:: Quotable ;
18- use uucore:: error:: { UError , UResult , USimpleError } ;
17+ use uucore:: error:: { UError , UIoError , UResult , USimpleError } ;
1918use uucore:: { format_usage, show, translate} ;
2019
2120// short types for switching interning behavior on the fly.
@@ -60,14 +59,33 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
6059 if input == "-" {
6160 process_input ( io:: stdin ( ) . lock ( ) , & mut g) ?;
6261 } else {
62+ let file = open_file ( input) ?;
63+
64+ let reader = BufReader :: new ( file) ;
65+ process_input ( reader, & mut g) ?;
66+ }
67+
68+ g. run_tsort ( ) ;
69+ Ok ( ( ) )
70+ }
71+
72+ fn open_file ( input : & OsString ) -> Result < File , UIoError > {
73+ // Windows throws a permission denied error when trying to read a directory,
74+ // so we need to check manually beforehand.
75+ #[ cfg( windows) ]
76+ {
77+ use std:: path:: Path ;
6378 let path = Path :: new ( & input) ;
6479 if path. is_dir ( ) {
65- return Err ( TsortError :: IsDir ( input. to_string_lossy ( ) . to_string ( ) ) . into ( ) ) ;
80+ return Err ( TsortError :: IsDir ( input. to_string_lossy ( ) . to_string ( ) ) ) ;
6681 }
6782
68- let file = File :: open ( path) ?;
69-
70- // advise the OS we will access the data sequentially if available.
83+ Ok ( File :: open ( path) ?)
84+ }
85+ // advise the OS that we are going to read the file sequentially, if available.
86+ #[ cfg( not( windows) ) ]
87+ {
88+ let file = File :: open ( input) ?;
7189 #[ cfg( any(
7290 target_os = "linux" ,
7391 target_os = "android" ,
@@ -88,13 +106,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
88106 )
89107 . ok ( ) ;
90108 }
91-
92- let reader = BufReader :: new ( file) ;
93- process_input ( reader, & mut g) ?;
109+ Ok ( file)
94110 }
95-
96- g. run_tsort ( ) ;
97- Ok ( ( ) )
98111}
99112
100113pub fn uu_app ( ) -> Command {
@@ -160,7 +173,13 @@ fn process_input<R: BufRead>(reader: R, graph: &mut Graph) -> Result<(), TsortEr
160173 // with tokens separated by whitespaces
161174
162175 for line in reader. lines ( ) {
163- let line = line?;
176+ let line = line. map_err ( |e| {
177+ if e. kind ( ) == io:: ErrorKind :: IsADirectory {
178+ TsortError :: IsDir ( graph. name ( ) )
179+ } else {
180+ e. into ( )
181+ }
182+ } ) ?;
164183 for token in line. split_whitespace ( ) {
165184 // Intern the token and get a Sym
166185 let token_sym = graph. interner . get_or_intern ( token) ;
0 commit comments