@@ -9,7 +9,7 @@ use std::collections::HashMap;
99use std:: fmt;
1010use std:: fs:: { File , OpenOptions } ;
1111use std:: io:: { Error , ErrorKind , Read , Result , Write } ;
12- use std:: path:: Path ;
12+ use std:: path:: { Path , PathBuf } ;
1313use std:: process:: { Command , Stdio } ;
1414use std:: sync:: Mutex ;
1515
@@ -20,7 +20,7 @@ pub struct CmdEnv {
2020 stderr : CmdOut ,
2121 args : Vec < String > ,
2222 vars : HashMap < String , String > ,
23- current_dir : String ,
23+ current_dir : PathBuf ,
2424}
2525impl CmdEnv {
2626 /// Returns the arguments for this command
@@ -34,7 +34,7 @@ impl CmdEnv {
3434 }
3535
3636 /// Returns the current working directory for this command
37- pub fn current_dir ( & self ) -> & str {
37+ pub fn current_dir ( & self ) -> & Path {
3838 & self . current_dir
3939 }
4040
@@ -88,7 +88,7 @@ pub fn set_pipefail(enable: bool) {
8888#[ derive( Default ) ]
8989pub struct GroupCmds {
9090 group_cmds : Vec < ( Cmds , Option < Cmds > ) > , // (cmd, orCmd) pairs
91- current_dir : String ,
91+ current_dir : PathBuf ,
9292}
9393
9494impl GroupCmds {
@@ -169,7 +169,7 @@ impl Cmds {
169169 & self . full_cmds
170170 }
171171
172- fn spawn ( & mut self , current_dir : & mut String ) -> Result < CmdChildren > {
172+ fn spawn ( & mut self , current_dir : & mut PathBuf ) -> Result < CmdChildren > {
173173 if std:: env:: var ( "CMD_LIB_DEBUG" ) == Ok ( "1" . into ( ) ) {
174174 debug ! ( "Running {} ..." , self . get_full_cmds( ) ) ;
175175 }
@@ -195,41 +195,41 @@ impl Cmds {
195195 Ok ( CmdChildren :: from ( children) )
196196 }
197197
198- fn run_cmd ( & mut self , current_dir : & mut String ) -> CmdResult {
198+ fn run_cmd ( & mut self , current_dir : & mut PathBuf ) -> CmdResult {
199199 self . spawn ( current_dir) ?. wait_cmd_result_nolog ( )
200200 }
201201
202- fn run_fun ( & mut self , current_dir : & mut String ) -> FunResult {
202+ fn run_fun ( & mut self , current_dir : & mut PathBuf ) -> FunResult {
203203 self . spawn ( current_dir) ?. wait_fun_result_nolog ( )
204204 }
205205}
206206
207207#[ doc( hidden) ]
208208pub enum Redirect {
209- FileToStdin ( String ) ,
209+ FileToStdin ( PathBuf ) ,
210210 StdoutToStderr ,
211211 StderrToStdout ,
212- StdoutToFile ( String , bool ) ,
213- StderrToFile ( String , bool ) ,
212+ StdoutToFile ( PathBuf , bool ) ,
213+ StderrToFile ( PathBuf , bool ) ,
214214}
215215impl fmt:: Debug for Redirect {
216216 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
217217 match self {
218- Redirect :: FileToStdin ( path) => f. write_str ( & format ! ( "< {}" , path) ) ,
218+ Redirect :: FileToStdin ( path) => f. write_str ( & format ! ( "< {}" , path. display ( ) ) ) ,
219219 Redirect :: StdoutToStderr => f. write_str ( ">&2" ) ,
220220 Redirect :: StderrToStdout => f. write_str ( "2>&1" ) ,
221221 Redirect :: StdoutToFile ( path, append) => {
222222 if * append {
223- f. write_str ( & format ! ( "1>> {}" , path) )
223+ f. write_str ( & format ! ( "1>> {}" , path. display ( ) ) )
224224 } else {
225- f. write_str ( & format ! ( "1> {}" , path) )
225+ f. write_str ( & format ! ( "1> {}" , path. display ( ) ) )
226226 }
227227 }
228228 Redirect :: StderrToFile ( path, append) => {
229229 if * append {
230- f. write_str ( & format ! ( "2>> {}" , path) )
230+ f. write_str ( & format ! ( "2>> {}" , path. display ( ) ) )
231231 } else {
232- f. write_str ( & format ! ( "2> {}" , path) )
232+ f. write_str ( & format ! ( "2> {}" , path. display ( ) ) )
233233 }
234234 }
235235 }
@@ -335,7 +335,7 @@ impl Cmd {
335335 self
336336 }
337337
338- fn spawn ( mut self , current_dir : & mut String ) -> Result < CmdChild > {
338+ fn spawn ( mut self , current_dir : & mut PathBuf ) -> Result < CmdChild > {
339339 let arg0 = self . arg0 ( ) ;
340340 let full_cmd = self . debug_str ( ) ;
341341 if arg0 == "cd" {
@@ -350,7 +350,11 @@ impl Cmd {
350350 let mut env = CmdEnv {
351351 args : self . args ,
352352 vars : self . vars ,
353- current_dir : current_dir. clone ( ) ,
353+ current_dir : if current_dir. as_os_str ( ) . is_empty ( ) {
354+ std:: env:: current_dir ( ) ?
355+ } else {
356+ current_dir. clone ( )
357+ } ,
354358 stdin : if let Some ( redirect_in) = self . stdin_redirect . take ( ) {
355359 redirect_in
356360 } else {
@@ -390,7 +394,7 @@ impl Cmd {
390394 let mut cmd = self . std_cmd . take ( ) . unwrap ( ) ;
391395
392396 // setup current_dir
393- if !current_dir. is_empty ( ) {
397+ if !current_dir. as_os_str ( ) . is_empty ( ) {
394398 cmd. current_dir ( current_dir. clone ( ) ) ;
395399 }
396400
@@ -421,7 +425,7 @@ impl Cmd {
421425 }
422426 }
423427
424- fn run_cd_cmd ( & self , current_dir : & mut String ) -> CmdResult {
428+ fn run_cd_cmd ( & self , current_dir : & mut PathBuf ) -> CmdResult {
425429 if self . args . len ( ) == 1 {
426430 return Err ( Error :: new ( ErrorKind :: Other , "cd: missing directory" ) ) ;
427431 } else if self . args . len ( ) > 2 {
@@ -441,11 +445,11 @@ impl Cmd {
441445 return Err ( e) ;
442446 }
443447
444- * current_dir = dir . clone ( ) ;
448+ * current_dir = PathBuf :: from ( dir ) ;
445449 Ok ( ( ) )
446450 }
447451
448- fn open_file ( path : & str , read_only : bool , append : bool ) -> Result < File > {
452+ fn open_file ( path : & Path , read_only : bool , append : bool ) -> Result < File > {
449453 if read_only {
450454 OpenOptions :: new ( ) . read ( true ) . open ( path)
451455 } else {
@@ -484,7 +488,7 @@ impl Cmd {
484488 for redirect in self . redirects . iter ( ) {
485489 match redirect {
486490 Redirect :: FileToStdin ( path) => {
487- self . stdin_redirect = Some ( if path == "/dev/null" {
491+ self . stdin_redirect = Some ( if path == Path :: new ( "/dev/null" ) {
488492 CmdIn :: CmdNull
489493 } else {
490494 CmdIn :: CmdFile ( Self :: open_file ( path, true , false ) ?)
@@ -505,14 +509,14 @@ impl Cmd {
505509 }
506510 }
507511 Redirect :: StdoutToFile ( path, append) => {
508- self . stdout_redirect = Some ( if path == "/dev/null" {
512+ self . stdout_redirect = Some ( if path == Path :: new ( "/dev/null" ) {
509513 CmdOut :: CmdNull
510514 } else {
511515 CmdOut :: CmdFile ( Self :: open_file ( path, false , * append) ?)
512516 } ) ;
513517 }
514518 Redirect :: StderrToFile ( path, append) => {
515- self . stderr_redirect = Some ( if path == "/dev/null" {
519+ self . stderr_redirect = Some ( if path == Path :: new ( "/dev/null" ) {
516520 CmdOut :: CmdNull
517521 } else {
518522 CmdOut :: CmdFile ( Self :: open_file ( path, false , * append) ?)
@@ -530,7 +534,7 @@ mod tests {
530534
531535 #[ test]
532536 fn test_run_piped_cmds ( ) {
533- let mut current_dir = String :: new ( ) ;
537+ let mut current_dir = PathBuf :: new ( ) ;
534538 assert ! ( Cmds :: default ( )
535539 . pipe( Cmd :: default ( ) . add_args( vec![ "echo" . into( ) , "rust" . into( ) ] ) )
536540 . pipe( Cmd :: default ( ) . add_args( vec![ "wc" . into( ) ] ) )
@@ -540,7 +544,7 @@ mod tests {
540544
541545 #[ test]
542546 fn test_run_piped_funs ( ) {
543- let mut current_dir = String :: new ( ) ;
547+ let mut current_dir = PathBuf :: new ( ) ;
544548 assert_eq ! (
545549 Cmds :: default ( )
546550 . pipe( Cmd :: default ( ) . add_args( vec![ "echo" . into( ) , "rust" . into( ) ] ) )
@@ -562,10 +566,10 @@ mod tests {
562566
563567 #[ test]
564568 fn test_stdout_redirect ( ) {
565- let mut current_dir = String :: new ( ) ;
569+ let mut current_dir = PathBuf :: new ( ) ;
566570 let tmp_file = "/tmp/file_echo_rust" ;
567571 let mut write_cmd = Cmd :: default ( ) . add_args ( vec ! [ "echo" . into( ) , "rust" . into( ) ] ) ;
568- write_cmd = write_cmd. add_redirect ( Redirect :: StdoutToFile ( tmp_file . to_string ( ) , false ) ) ;
572+ write_cmd = write_cmd. add_redirect ( Redirect :: StdoutToFile ( PathBuf :: from ( tmp_file ) , false ) ) ;
569573 assert ! ( Cmds :: default ( )
570574 . pipe( write_cmd)
571575 . run_cmd( & mut current_dir)
0 commit comments