@@ -53,6 +53,8 @@ use ptr::RawPtr;
53
53
54
54
#[ cfg( unix) ]
55
55
use c_str:: ToCStr ;
56
+ #[ cfg( windows) ]
57
+ use str:: OwnedStr ;
56
58
57
59
/// Delegates to the libc close() function, returning the same return value.
58
60
pub fn close ( fd : int ) -> int {
@@ -158,10 +160,23 @@ fn with_env_lock<T>(f: || -> T) -> T {
158
160
159
161
/// Returns a vector of (variable, value) pairs for all the environment
160
162
/// variables of the current process.
163
+ ///
164
+ /// Invalid UTF-8 bytes are replaced with \uFFFD. See `str::from_utf8_lossy()`
165
+ /// for details.
161
166
pub fn env ( ) -> ~[ ( ~str , ~str ) ] {
167
+ env_as_bytes ( ) . move_iter ( ) . map ( |( k, v) | {
168
+ let k = str:: from_utf8_lossy ( k) . into_owned ( ) ;
169
+ let v = str:: from_utf8_lossy ( v) . into_owned ( ) ;
170
+ ( k, v)
171
+ } ) . collect ( )
172
+ }
173
+
174
+ /// Returns a vector of (variable, value) byte-vector pairs for all the
175
+ /// environment variables of the current process.
176
+ pub fn env_as_bytes ( ) -> ~[ ( ~[ u8 ] , ~[ u8 ] ) ] {
162
177
unsafe {
163
178
#[ cfg( windows) ]
164
- unsafe fn get_env_pairs ( ) -> ~[ ~str ] {
179
+ unsafe fn get_env_pairs ( ) -> ~[ ~[ u8 ] ] {
165
180
use c_str;
166
181
use str:: StrSlice ;
167
182
@@ -176,13 +191,15 @@ pub fn env() -> ~[(~str,~str)] {
176
191
}
177
192
let mut result = ~[ ] ;
178
193
c_str:: from_c_multistring ( ch as * c_char , None , |cstr| {
179
- result. push ( cstr. as_str ( ) . unwrap ( ) . to_owned ( ) ) ;
194
+ result. push ( cstr. as_bytes_no_nul ( ) . to_owned ( ) ) ;
180
195
} ) ;
181
196
FreeEnvironmentStringsA ( ch) ;
182
197
result
183
198
}
184
199
#[ cfg( unix) ]
185
- unsafe fn get_env_pairs ( ) -> ~[ ~str ] {
200
+ unsafe fn get_env_pairs ( ) -> ~[ ~[ u8 ] ] {
201
+ use c_str:: CString ;
202
+
186
203
extern {
187
204
fn rust_env_pairs ( ) -> * * c_char ;
188
205
}
@@ -193,20 +210,19 @@ pub fn env() -> ~[(~str,~str)] {
193
210
}
194
211
let mut result = ~[ ] ;
195
212
ptr:: array_each ( environ, |e| {
196
- let env_pair = str:: raw:: from_c_str ( e) ;
197
- debug ! ( "get_env_pairs: {}" , env_pair) ;
213
+ let env_pair = CString :: new ( e, false ) . as_bytes_no_nul ( ) . to_owned ( ) ;
198
214
result. push ( env_pair) ;
199
215
} ) ;
200
216
result
201
217
}
202
218
203
- fn env_convert ( input : ~[ ~str ] ) -> ~[ ( ~str , ~str ) ] {
219
+ fn env_convert ( input : ~[ ~[ u8 ] ] ) -> ~[ ( ~[ u8 ] , ~[ u8 ] ) ] {
204
220
let mut pairs = ~[ ] ;
205
221
for p in input. iter ( ) {
206
- let vs: ~[ & str ] = p. splitn ( '=' , 1 ) . collect ( ) ;
207
- debug ! ( "splitting: len: {}" , vs. len ( ) ) ;
208
- assert_eq ! ( vs. len( ) , 2 ) ;
209
- pairs. push ( ( vs [ 0 ] . to_owned ( ) , vs [ 1 ] . to_owned ( ) ) ) ;
222
+ let vs: ~[ & [ u8 ] ] = p. splitn ( 1 , |b| * b == '=' as u8 ) . collect ( ) ;
223
+ let key = vs[ 0 ] . to_owned ( ) ;
224
+ let val = ( if vs. len ( ) < 2 { ~ [ ] } else { vs [ 1 ] . to_owned ( ) } ) ;
225
+ pairs. push ( ( key , val ) ) ;
210
226
}
211
227
pairs
212
228
}
@@ -220,14 +236,34 @@ pub fn env() -> ~[(~str,~str)] {
220
236
#[ cfg( unix) ]
221
237
/// Fetches the environment variable `n` from the current process, returning
222
238
/// None if the variable isn't set.
239
+ ///
240
+ /// Any invalid UTF-8 bytes in the value are replaced by \uFFFD. See
241
+ /// `str::from_utf8_lossy()` for details.
242
+ ///
243
+ /// # Failure
244
+ ///
245
+ /// Fails if `n` has any interior NULs.
223
246
pub fn getenv ( n : & str ) -> Option < ~str > {
247
+ getenv_as_bytes ( n) . map ( |v| str:: from_utf8_lossy ( v) . into_owned ( ) )
248
+ }
249
+
250
+ #[ cfg( unix) ]
251
+ /// Fetches the environment variable `n` byte vector from the current process,
252
+ /// returning None if the variable isn't set.
253
+ ///
254
+ /// # Failure
255
+ ///
256
+ /// Fails if `n` has any interior NULs.
257
+ pub fn getenv_as_bytes ( n : & str ) -> Option < ~[ u8 ] > {
258
+ use c_str:: CString ;
259
+
224
260
unsafe {
225
261
with_env_lock ( || {
226
262
let s = n. with_c_str ( |buf| libc:: getenv ( buf) ) ;
227
263
if s. is_null ( ) {
228
264
None
229
265
} else {
230
- Some ( str :: raw :: from_c_str ( s ) )
266
+ Some ( CString :: new ( s , false ) . as_bytes_no_nul ( ) . to_owned ( ) )
231
267
}
232
268
} )
233
269
}
@@ -249,10 +285,21 @@ pub fn getenv(n: &str) -> Option<~str> {
249
285
}
250
286
}
251
287
288
+ #[ cfg( windows) ]
289
+ /// Fetches the environment variable `n` byte vector from the current process,
290
+ /// returning None if the variable isn't set.
291
+ pub fn getenv_as_bytes ( n : & str ) -> Option < ~[ u8 ] > {
292
+ getenv ( n) . map ( |s| s. into_bytes ( ) )
293
+ }
294
+
252
295
253
296
#[ cfg( unix) ]
254
297
/// Sets the environment variable `n` to the value `v` for the currently running
255
298
/// process
299
+ ///
300
+ /// # Failure
301
+ ///
302
+ /// Fails if `n` or `v` have any interior NULs.
256
303
pub fn setenv ( n : & str , v : & str ) {
257
304
unsafe {
258
305
with_env_lock ( || {
@@ -283,6 +330,10 @@ pub fn setenv(n: &str, v: &str) {
283
330
}
284
331
285
332
/// Remove a variable from the environment entirely
333
+ ///
334
+ /// # Failure
335
+ ///
336
+ /// Fails (on unix) if `n` has any interior NULs.
286
337
pub fn unsetenv ( n : & str ) {
287
338
#[ cfg( unix) ]
288
339
fn _unsetenv ( n : & str ) {
@@ -722,10 +773,12 @@ pub fn get_exit_status() -> int {
722
773
}
723
774
724
775
#[ cfg( target_os = "macos" ) ]
725
- unsafe fn load_argc_and_argv ( argc : int , argv : * * c_char ) -> ~[ ~str ] {
776
+ unsafe fn load_argc_and_argv ( argc : int , argv : * * c_char ) -> ~[ ~[ u8 ] ] {
777
+ use c_str:: CString ;
778
+
726
779
let mut args = ~[ ] ;
727
780
for i in range ( 0 u, argc as uint ) {
728
- args. push ( str :: raw :: from_c_str ( * argv. offset ( i as int ) ) ) ;
781
+ args. push ( CString :: new ( * argv. offset ( i as int ) , false ) . as_bytes_no_nul ( ) . to_owned ( ) )
729
782
}
730
783
args
731
784
}
@@ -736,7 +789,7 @@ unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> ~[~str] {
736
789
* Returns a list of the command line arguments.
737
790
*/
738
791
#[ cfg( target_os = "macos" ) ]
739
- fn real_args ( ) -> ~[ ~str ] {
792
+ fn real_args_as_bytes ( ) -> ~[ ~[ u8 ] ] {
740
793
unsafe {
741
794
let ( argc, argv) = ( * _NSGetArgc ( ) as int ,
742
795
* _NSGetArgv ( ) as * * c_char ) ;
@@ -747,7 +800,7 @@ fn real_args() -> ~[~str] {
747
800
#[ cfg( target_os = "linux" ) ]
748
801
#[ cfg( target_os = "android" ) ]
749
802
#[ cfg( target_os = "freebsd" ) ]
750
- fn real_args ( ) -> ~[ ~str ] {
803
+ fn real_args_as_bytes ( ) -> ~[ ~[ u8 ] ] {
751
804
use rt;
752
805
753
806
match rt:: args:: clone ( ) {
@@ -756,6 +809,11 @@ fn real_args() -> ~[~str] {
756
809
}
757
810
}
758
811
812
+ #[ cfg( not( windows) ) ]
813
+ fn real_args ( ) -> ~[ ~str ] {
814
+ real_args_as_bytes ( ) . move_iter ( ) . map ( |v| str:: from_utf8_lossy ( v) . into_owned ( ) ) . collect ( )
815
+ }
816
+
759
817
#[ cfg( windows) ]
760
818
fn real_args ( ) -> ~[ ~str ] {
761
819
use vec;
@@ -786,6 +844,11 @@ fn real_args() -> ~[~str] {
786
844
return args;
787
845
}
788
846
847
+ #[ cfg( windows) ]
848
+ fn real_args_as_bytes ( ) -> ~[ ~[ u8 ] ] {
849
+ real_args ( ) . move_iter ( ) . map ( |s| s. into_bytes ( ) ) . collect ( )
850
+ }
851
+
789
852
type LPCWSTR = * u16 ;
790
853
791
854
#[ cfg( windows) ]
@@ -803,10 +866,19 @@ extern "system" {
803
866
804
867
/// Returns the arguments which this program was started with (normally passed
805
868
/// via the command line).
869
+ ///
870
+ /// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
871
+ /// See `str::from_utf8_lossy` for details.
806
872
pub fn args ( ) -> ~[ ~str ] {
807
873
real_args ( )
808
874
}
809
875
876
+ /// Returns the arguments which this program was started with (normally passed
877
+ /// via the command line) as byte vectors.
878
+ pub fn args_as_bytes ( ) -> ~[ ~[ u8 ] ] {
879
+ real_args_as_bytes ( )
880
+ }
881
+
810
882
#[ cfg( target_os = "macos" ) ]
811
883
extern {
812
884
// These functions are in crt_externs.h.
0 commit comments