@@ -38,7 +38,7 @@ pub use self::MapError::*;
3838use clone:: Clone ;
3939use error:: { FromError , Error } ;
4040use fmt;
41- use io:: IoResult ;
41+ use io:: { IoResult , IoError } ;
4242use iter:: Iterator ;
4343use libc:: { c_void, c_int} ;
4444use libc;
@@ -76,72 +76,83 @@ pub fn num_cpus() -> uint {
7676pub const TMPBUF_SZ : uint = 1000 u;
7777const BUF_BYTES : uint = 2048 u;
7878
79- /// Returns the current working directory as a Path.
79+ /// Returns the current working directory as a ` Path` .
8080///
81- /// # Failure
81+ /// # Errors
8282///
83- /// Fails if the current working directory value is invalid:
83+ /// Returns an `Err` if the current working directory value is invalid.
8484/// Possible cases:
8585///
8686/// * Current directory does not exist.
8787/// * There are insufficient permissions to access the current directory.
88+ /// * The internal buffer is not large enough to hold the path.
8889///
8990/// # Example
9091///
9192/// ```rust
9293/// use std::os;
9394///
9495/// // We assume that we are in a valid directory like "/home".
95- /// let current_working_directory = os::getcwd();
96+ /// let current_working_directory = os::getcwd().unwrap() ;
9697/// println!("The current directory is {}", current_working_directory.display());
9798/// // /home
9899/// ```
99100#[ cfg( unix) ]
100- pub fn getcwd ( ) -> Path {
101+ pub fn getcwd ( ) -> IoResult < Path > {
101102 use c_str:: CString ;
102103
103104 let mut buf = [ 0 as c_char , ..BUF_BYTES ] ;
104105 unsafe {
105106 if libc:: getcwd ( buf. as_mut_ptr ( ) , buf. len ( ) as libc:: size_t ) . is_null ( ) {
106- panic ! ( )
107+ Err ( IoError :: last_error ( ) )
108+ } else {
109+ Ok ( Path :: new ( CString :: new ( buf. as_ptr ( ) , false ) ) )
107110 }
108- Path :: new ( CString :: new ( buf. as_ptr ( ) , false ) )
109111 }
110112}
111113
112- /// Returns the current working directory as a Path.
114+ /// Returns the current working directory as a ` Path` .
113115///
114- /// # Failure
116+ /// # Errors
115117///
116- /// Fails if the current working directory value is invalid.
117- /// Possibles cases:
118+ /// Returns an `Err` if the current working directory value is invalid.
119+ /// Possible cases:
118120///
119121/// * Current directory does not exist.
120122/// * There are insufficient permissions to access the current directory.
123+ /// * The internal buffer is not large enough to hold the path.
121124///
122125/// # Example
123126///
124127/// ```rust
125128/// use std::os;
126129///
127130/// // We assume that we are in a valid directory like "C:\\Windows".
128- /// let current_working_directory = os::getcwd();
131+ /// let current_working_directory = os::getcwd().unwrap() ;
129132/// println!("The current directory is {}", current_working_directory.display());
130133/// // C:\\Windows
131134/// ```
132135#[ cfg( windows) ]
133- pub fn getcwd ( ) -> Path {
136+ pub fn getcwd ( ) -> IoResult < Path > {
134137 use libc:: DWORD ;
135138 use libc:: GetCurrentDirectoryW ;
139+ use io:: OtherIoError ;
136140
137141 let mut buf = [ 0 as u16 , ..BUF_BYTES ] ;
138142 unsafe {
139143 if libc:: GetCurrentDirectoryW ( buf. len ( ) as DWORD , buf. as_mut_ptr ( ) ) == 0 as DWORD {
140- panic ! ( ) ;
144+ return Err ( IoError :: last_error ( ) ) ;
141145 }
142146 }
143- Path :: new ( String :: from_utf16 ( :: str:: truncate_utf16_at_nul ( & buf) )
144- . expect ( "GetCurrentDirectoryW returned invalid UTF-16" ) )
147+
148+ match String :: from_utf16 ( :: str:: truncate_utf16_at_nul ( & buf) ) {
149+ Some ( ref cwd) => Ok ( Path :: new ( cwd) ) ,
150+ None => Err ( IoError {
151+ kind : OtherIoError ,
152+ desc : "GetCurrentDirectoryW returned invalid UTF-16" ,
153+ detail : None ,
154+ } ) ,
155+ }
145156}
146157
147158#[ cfg( windows) ]
@@ -411,7 +422,9 @@ pub fn setenv<T: BytesContainer>(n: &str, v: T) {
411422 with_env_lock ( || {
412423 n. with_c_str ( |nbuf| {
413424 v. with_c_str ( |vbuf| {
414- libc:: funcs:: posix01:: unistd:: setenv ( nbuf, vbuf, 1 ) ;
425+ if libc:: funcs:: posix01:: unistd:: setenv ( nbuf, vbuf, 1 ) != 0 {
426+ panic ! ( IoError :: last_error( ) ) ;
427+ }
415428 } )
416429 } )
417430 } )
@@ -427,7 +440,9 @@ pub fn setenv<T: BytesContainer>(n: &str, v: T) {
427440
428441 unsafe {
429442 with_env_lock ( || {
430- libc:: SetEnvironmentVariableW ( n. as_ptr ( ) , v. as_ptr ( ) ) ;
443+ if libc:: SetEnvironmentVariableW ( n. as_ptr ( ) , v. as_ptr ( ) ) == 0 {
444+ panic ! ( IoError :: last_error( ) ) ;
445+ }
431446 } )
432447 }
433448 }
@@ -442,7 +457,9 @@ pub fn unsetenv(n: &str) {
442457 unsafe {
443458 with_env_lock ( || {
444459 n. with_c_str ( |nbuf| {
445- libc:: funcs:: posix01:: unistd:: unsetenv ( nbuf) ;
460+ if libc:: funcs:: posix01:: unistd:: unsetenv ( nbuf) != 0 {
461+ panic ! ( IoError :: last_error( ) ) ;
462+ }
446463 } )
447464 } )
448465 }
@@ -454,11 +471,14 @@ pub fn unsetenv(n: &str) {
454471 n. push ( 0 ) ;
455472 unsafe {
456473 with_env_lock ( || {
457- libc:: SetEnvironmentVariableW ( n. as_ptr ( ) , ptr:: null ( ) ) ;
474+ if libc:: SetEnvironmentVariableW ( n. as_ptr ( ) , ptr:: null ( ) ) == 0 {
475+ panic ! ( IoError :: last_error( ) ) ;
476+ }
458477 } )
459478 }
460479 }
461- _unsetenv ( n) ;
480+
481+ _unsetenv ( n)
462482}
463483
464484/// Parses input according to platform conventions for the `PATH`
@@ -829,20 +849,21 @@ pub fn tmpdir() -> Path {
829849///
830850/// // Assume we're in a path like /home/someuser
831851/// let rel_path = Path::new("..");
832- /// let abs_path = os::make_absolute(&rel_path);
852+ /// let abs_path = os::make_absolute(&rel_path).unwrap() ;
833853/// println!("The absolute path is {}", abs_path.display());
834854/// // Prints "The absolute path is /home"
835855/// ```
836856// NB: this is here rather than in path because it is a form of environment
837857// querying; what it does depends on the process working directory, not just
838858// the input paths.
839- pub fn make_absolute ( p : & Path ) -> Path {
859+ pub fn make_absolute ( p : & Path ) -> IoResult < Path > {
840860 if p. is_absolute ( ) {
841- p. clone ( )
861+ Ok ( p. clone ( ) )
842862 } else {
843- let mut ret = getcwd ( ) ;
844- ret. push ( p) ;
845- ret
863+ getcwd ( ) . map ( |mut cwd| {
864+ cwd. push ( p) ;
865+ cwd
866+ } )
846867 }
847868}
848869
@@ -855,32 +876,33 @@ pub fn make_absolute(p: &Path) -> Path {
855876/// use std::path::Path;
856877///
857878/// let root = Path::new("/");
858- /// assert!(os::change_dir(&root));
879+ /// assert!(os::change_dir(&root).is_ok() );
859880/// println!("Successfully changed working directory to {}!", root.display());
860881/// ```
861- pub fn change_dir ( p : & Path ) -> bool {
882+ pub fn change_dir ( p : & Path ) -> IoResult < ( ) > {
862883 return chdir ( p) ;
863884
864885 #[ cfg( windows) ]
865- fn chdir ( p : & Path ) -> bool {
866- let p = match p. as_str ( ) {
867- Some ( s) => {
868- let mut p = s. utf16_units ( ) . collect :: < Vec < u16 > > ( ) ;
869- p. push ( 0 ) ;
870- p
871- }
872- None => return false ,
873- } ;
886+ fn chdir ( p : & Path ) -> IoResult < ( ) > {
887+ let mut p = p. as_str ( ) . unwrap ( ) . utf16_units ( ) . collect :: < Vec < u16 > > ( ) ;
888+ p. push ( 0 ) ;
889+
874890 unsafe {
875- libc:: SetCurrentDirectoryW ( p. as_ptr ( ) ) != ( 0 as libc:: BOOL )
891+ match libc:: SetCurrentDirectoryW ( p. as_ptr ( ) ) != ( 0 as libc:: BOOL ) {
892+ true => Ok ( ( ) ) ,
893+ false => Err ( IoError :: last_error ( ) ) ,
894+ }
876895 }
877896 }
878897
879898 #[ cfg( unix) ]
880- fn chdir ( p : & Path ) -> bool {
899+ fn chdir ( p : & Path ) -> IoResult < ( ) > {
881900 p. with_c_str ( |buf| {
882901 unsafe {
883- libc:: chdir ( buf) == ( 0 as c_int )
902+ match libc:: chdir ( buf) == ( 0 as c_int ) {
903+ true => Ok ( ( ) ) ,
904+ false => Err ( IoError :: last_error ( ) ) ,
905+ }
884906 }
885907 } )
886908 }
@@ -1881,11 +1903,11 @@ mod tests {
18811903 fn test ( ) {
18821904 assert ! ( ( !Path :: new( "test-path" ) . is_absolute( ) ) ) ;
18831905
1884- let cwd = getcwd ( ) ;
1906+ let cwd = getcwd ( ) . unwrap ( ) ;
18851907 debug ! ( "Current working directory: {}" , cwd. display( ) ) ;
18861908
1887- debug ! ( "{}" , make_absolute( & Path :: new( "test-path" ) ) . display( ) ) ;
1888- debug ! ( "{}" , make_absolute( & Path :: new( "/usr/bin" ) ) . display( ) ) ;
1909+ debug ! ( "{}" , make_absolute( & Path :: new( "test-path" ) ) . unwrap ( ) . display( ) ) ;
1910+ debug ! ( "{}" , make_absolute( & Path :: new( "/usr/bin" ) ) . unwrap ( ) . display( ) ) ;
18891911 }
18901912
18911913 #[ test]
0 commit comments