@@ -160,10 +160,23 @@ fn with_env_lock<T>(f: || -> T) -> T {
160
160
161
161
/// Returns a vector of (variable, value) pairs for all the environment
162
162
/// variables of the current process.
163
+ ///
164
+ /// Invalid UTF-8 bytes are replaced with \uFFFD. See `str::from_utf8_lossy()`
165
+ /// for details.
163
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 ] ) ] {
164
177
unsafe {
165
178
#[ cfg( windows) ]
166
- unsafe fn get_env_pairs ( ) -> ~[ ~str ] {
179
+ unsafe fn get_env_pairs ( ) -> ~[ ~[ u8 ] ] {
167
180
use c_str;
168
181
use str:: StrSlice ;
169
182
@@ -178,13 +191,15 @@ pub fn env() -> ~[(~str,~str)] {
178
191
}
179
192
let mut result = ~[ ] ;
180
193
c_str:: from_c_multistring ( ch as * c_char , None , |cstr| {
181
- result. push ( cstr. as_str ( ) . unwrap ( ) . to_owned ( ) ) ;
194
+ result. push ( cstr. as_bytes_no_nul ( ) . to_owned ( ) ) ;
182
195
} ) ;
183
196
FreeEnvironmentStringsA ( ch) ;
184
197
result
185
198
}
186
199
#[ cfg( unix) ]
187
- unsafe fn get_env_pairs ( ) -> ~[ ~str ] {
200
+ unsafe fn get_env_pairs ( ) -> ~[ ~[ u8 ] ] {
201
+ use c_str:: CString ;
202
+
188
203
extern {
189
204
fn rust_env_pairs ( ) -> * * c_char ;
190
205
}
@@ -195,20 +210,19 @@ pub fn env() -> ~[(~str,~str)] {
195
210
}
196
211
let mut result = ~[ ] ;
197
212
ptr:: array_each ( environ, |e| {
198
- let env_pair = str:: raw:: from_c_str ( e) ;
199
- debug ! ( "get_env_pairs: {}" , env_pair) ;
213
+ let env_pair = CString :: new ( e, false ) . as_bytes_no_nul ( ) . to_owned ( ) ;
200
214
result. push ( env_pair) ;
201
215
} ) ;
202
216
result
203
217
}
204
218
205
- fn env_convert ( input : ~[ ~str ] ) -> ~[ ( ~str , ~str ) ] {
219
+ fn env_convert ( input : ~[ ~[ u8 ] ] ) -> ~[ ( ~[ u8 ] , ~[ u8 ] ) ] {
206
220
let mut pairs = ~[ ] ;
207
221
for p in input. iter ( ) {
208
- let vs: ~[ & str ] = p. splitn ( '=' , 1 ) . collect ( ) ;
209
- debug ! ( "splitting: len: {}" , vs. len ( ) ) ;
210
- assert_eq ! ( vs. len( ) , 2 ) ;
211
- 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 ) ) ;
212
226
}
213
227
pairs
214
228
}
@@ -222,14 +236,34 @@ pub fn env() -> ~[(~str,~str)] {
222
236
#[ cfg( unix) ]
223
237
/// Fetches the environment variable `n` from the current process, returning
224
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.
225
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
+
226
260
unsafe {
227
261
with_env_lock ( || {
228
262
let s = n. with_c_str ( |buf| libc:: getenv ( buf) ) ;
229
263
if s. is_null ( ) {
230
264
None
231
265
} else {
232
- Some ( str :: raw :: from_c_str ( s ) )
266
+ Some ( CString :: new ( s , false ) . as_bytes_no_nul ( ) . to_owned ( ) )
233
267
}
234
268
} )
235
269
}
@@ -251,10 +285,21 @@ pub fn getenv(n: &str) -> Option<~str> {
251
285
}
252
286
}
253
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
+
254
295
255
296
#[ cfg( unix) ]
256
297
/// Sets the environment variable `n` to the value `v` for the currently running
257
298
/// process
299
+ ///
300
+ /// # Failure
301
+ ///
302
+ /// Fails if `n` or `v` have any interior NULs.
258
303
pub fn setenv ( n : & str , v : & str ) {
259
304
unsafe {
260
305
with_env_lock ( || {
@@ -285,6 +330,10 @@ pub fn setenv(n: &str, v: &str) {
285
330
}
286
331
287
332
/// Remove a variable from the environment entirely
333
+ ///
334
+ /// # Failure
335
+ ///
336
+ /// Fails (on unix) if `n` has any interior NULs.
288
337
pub fn unsetenv ( n : & str ) {
289
338
#[ cfg( unix) ]
290
339
fn _unsetenv ( n : & str ) {
0 commit comments