14
14
// facts of which OS the user is on -- they should be given the opportunity
15
15
// to write OS-ignorant code by default.
16
16
17
- import libc:: { c_char, c_void, c_int, c_uint, size_t, mode_t, pid_t, FILE } ;
17
+ import libc:: { c_char, c_void, c_int, c_uint, size_t, ssize_t,
18
+ mode_t, pid_t, FILE } ;
18
19
import libc:: { close, fclose} ;
19
20
21
+ import option:: { some, none} ;
22
+ import option = option:: t;
23
+
20
24
import getcwd = rustrt:: rust_getcwd;
21
25
import consts:: * ;
22
26
@@ -46,15 +50,48 @@ fn env() -> [(str,str)] {
46
50
ret pairs;
47
51
}
48
52
53
+ const tmpbuf_sz : uint = 1000 u;
54
+
49
55
fn as_c_charp < T > ( s : str , f : fn ( * c_char ) -> T ) -> T {
50
56
str:: as_buf ( s) { |b| f ( b as * c_char ) }
51
57
}
52
58
53
- fn as_utf16_p < T > ( s : str , f : fn ( * u16 ) -> T ) -> T {
54
- let t = str:: to_utf16 ( s) ;
55
- // "null terminate"
56
- t += [ 0u16 ] ;
57
- vec:: as_buf ( t, f)
59
+ fn fill_charp_buf ( f : fn ( * mutable c_char , size_t ) -> bool )
60
+ -> option < str > {
61
+ let buf = vec:: to_mut ( vec:: init_elt ( tmpbuf_sz, 0u8 as c_char ) ) ;
62
+ vec:: as_mut_buf ( buf) { |b|
63
+ if f ( b, tmpbuf_sz as size_t ) {
64
+ some ( str:: from_cstr ( b as str:: sbuf ) )
65
+ } else {
66
+ none
67
+ }
68
+ }
69
+ }
70
+
71
+ #[ cfg( target_os = "win32" ) ]
72
+ mod win32 {
73
+ import dword = libc:: types:: os:: arch:: extra:: DWORD ;
74
+
75
+ fn fill_utf16_buf_and_decode ( f : fn ( * mutable u16 , dword ) -> dword )
76
+ -> option < str > {
77
+ let buf = vec:: to_mut ( vec:: init_elt ( tmpbuf_sz, 0u16 ) ) ;
78
+ vec:: as_mut_buf ( buf) { |b|
79
+ let k : dword = f ( b, tmpbuf_sz as dword ) ;
80
+ if k == ( 0 as dword ) {
81
+ none
82
+ } else {
83
+ let sub = vec:: slice ( buf, 0 u, k as uint ) ;
84
+ option:: some :: < str > ( str:: from_utf16 ( sub) )
85
+ }
86
+ }
87
+ }
88
+
89
+ fn as_utf16_p < T > ( s : str , f : fn ( * u16 ) -> T ) -> T {
90
+ let t = str:: to_utf16 ( s) ;
91
+ // Null terminate before passing on.
92
+ t += [ 0u16 ] ;
93
+ vec:: as_buf ( t, f)
94
+ }
58
95
}
59
96
60
97
@@ -74,19 +111,11 @@ fn getenv(n: str) -> option<str> unsafe {
74
111
#[ cfg( target_os = "win32" ) ]
75
112
fn getenv ( n : str ) -> option < str > unsafe {
76
113
import libc:: types:: os:: arch:: extra:: * ;
77
- import libc:: funcs:: extra:: kernel32;
114
+ import libc:: funcs:: extra:: kernel32:: * ;
115
+ import win32:: * ;
78
116
as_utf16_p ( n) { |u|
79
- let bufsize = 1023 u;
80
- let buf = vec:: to_mut ( vec:: init_elt ( bufsize, 0u16 ) ) ;
81
- vec:: as_mut_buf ( buf) { |b|
82
- let k = kernel32:: GetEnvironmentVariableW ( u, b,
83
- bufsize as DWORD ) ;
84
- if k != ( 0 as DWORD ) {
85
- let sub = vec:: slice ( buf, 0 u, k as uint ) ;
86
- option:: some :: < str > ( str:: from_utf16 ( sub) )
87
- } else {
88
- option:: none :: < str >
89
- }
117
+ fill_utf16_buf_and_decode ( ) { |buf, sz|
118
+ GetEnvironmentVariableW ( u, buf, sz)
90
119
}
91
120
}
92
121
}
@@ -99,7 +128,6 @@ fn setenv(n: str, v: str) {
99
128
100
129
// FIXME: remove this when export globs work properly.
101
130
import libc:: funcs:: posix01:: unistd:: setenv;
102
-
103
131
as_c_charp ( n) { |nbuf|
104
132
as_c_charp ( v) { |vbuf|
105
133
setenv ( nbuf, vbuf, 1i32 ) ;
@@ -111,10 +139,11 @@ fn setenv(n: str, v: str) {
111
139
#[ cfg( target_os = "win32" ) ]
112
140
fn setenv ( n : str , v : str ) {
113
141
// FIXME: remove imports when export globs work properly.
114
- import libc:: funcs:: extra:: kernel32;
142
+ import libc:: funcs:: extra:: kernel32:: * ;
143
+ import win32:: * ;
115
144
as_utf16_p ( n) { |nbuf|
116
145
as_utf16_p ( v) { |vbuf|
117
- kernel32 :: SetEnvironmentVariableW ( nbuf, vbuf) ;
146
+ SetEnvironmentVariableW ( nbuf, vbuf) ;
118
147
}
119
148
}
120
149
}
@@ -244,59 +273,57 @@ fn dll_filename(base: str) -> str {
244
273
fn pre ( ) -> str { "" }
245
274
}
246
275
247
- fn self_exe_path ( ) -> option < path > unsafe {
248
- let bufsize = 1023 u;
249
- let buf = vec:: to_mut ( vec:: init_elt ( bufsize, 0u8 as c_char ) ) ;
250
- // FIXME: This does not handle the case where the buffer is too small
251
- ret vec:: as_mut_buf ( buf) { |pbuf|
252
- if load_self ( pbuf as * mutable c_char , bufsize as c_uint ) {
253
- let path = str:: from_cstr ( pbuf as str:: sbuf ) ;
254
- option:: some ( path:: dirname ( path) + path:: path_sep ( ) )
255
- } else {
256
- option:: none
257
- }
258
- } ;
276
+
277
+ fn self_exe_path ( ) -> option < path > {
259
278
260
279
#[ cfg( target_os = "freebsd" ) ]
261
- unsafe fn load_self ( pth : * mutable c_char , plen : c_uint ) -> bool {
262
- // FIXME: remove imports when export globs work properly.
280
+ fn load_self ( ) -> option < path > unsafe {
263
281
import libc:: funcs:: bsd44:: * ;
264
282
import libc:: consts:: os:: extra:: * ;
265
- let mib = [ CTL_KERN as c_int ,
266
- KERN_PROC as c_int ,
267
- KERN_PROC_PATHNAME as c_int , -1 as c_int ] ;
268
- ret sysctl( vec:: unsafe:: to_ptr ( mib) , vec:: len ( mib) as c_uint ,
269
- pth as * mutable c_void , ptr:: mut_addr_of ( plen as size_t ) ,
270
- ptr:: null ( ) , 0 u as size_t )
271
- == ( 0 as c_int ) ;
283
+ fill_charp_buf ( ) { |buf, sz|
284
+ let mib = [ CTL_KERN as c_int ,
285
+ KERN_PROC as c_int ,
286
+ KERN_PROC_PATHNAME as c_int , -1 as c_int ] ;
287
+ sysctl ( vec:: unsafe:: to_ptr ( mib) , vec:: len ( mib) as c_uint ,
288
+ buf as * mutable c_void , ptr:: mut_addr_of ( sz) ,
289
+ ptr:: null ( ) , 0 u as size_t ) != ( 0 as c_int )
290
+ }
272
291
}
273
292
274
293
#[ cfg( target_os = "linux" ) ]
275
- unsafe fn load_self ( pth : * mutable c_char , plen : c_uint ) -> bool {
276
- // FIXME: remove imports when export globs work properly.
294
+ fn load_self ( ) -> option < path > unsafe {
277
295
import libc:: funcs:: posix01:: unistd:: readlink;
278
- as_c_charp ( "/proc/self/exe" ) { |proc_self_buf|
279
- ret readlink ( proc_self_buf, pth, plen as size_t ) != -1 ;
296
+ fill_charp_buf ( ) { |buf, sz|
297
+ as_c_charp ( "/proc/self/exe" ) { |proc_self_buf|
298
+ readlink ( proc_self_buf, buf, sz) != ( -1 as ssize_t )
299
+ }
280
300
}
281
301
}
282
302
283
- #[ cfg( target_os = "win32 " ) ]
284
- unsafe fn load_self ( pth : * mutable c_char , plen : c_uint ) -> bool {
303
+ #[ cfg( target_os = "macos " ) ]
304
+ fn load_self ( ) -> option < path > unsafe {
285
305
// FIXME: remove imports when export globs work properly.
286
- import libc:: types:: os:: arch:: extra:: * ;
287
- import libc:: funcs:: extra:: kernel32;
288
- ret kernel32:: GetModuleFileNameA ( 0 u, pth, plen) != ( 0 as DWORD ) ;
306
+ import libc:: funcs:: extra:: * ;
307
+ fill_charp_buf ( ) { |buf, sz|
308
+ _NSGetExecutablePath ( buf, ptr:: mut_addr_of ( sz as u32 ) )
309
+ == ( 0 as c_int )
310
+ }
289
311
}
290
312
291
- #[ cfg( target_os = "macos " ) ]
292
- unsafe fn load_self ( pth : * mutable c_char , plen : c_uint ) -> bool {
313
+ #[ cfg( target_os = "win32 " ) ]
314
+ fn load_self ( ) -> option < path > unsafe {
293
315
// FIXME: remove imports when export globs work properly.
294
- import libc:: funcs:: extra:: * ;
295
- let mplen = plen;
296
- ret _NSGetExecutablePath ( pth, ptr:: mut_addr_of ( mplen) )
297
- == ( 0 as c_int ) ;
316
+ import libc:: types:: os:: arch:: extra:: * ;
317
+ import libc:: funcs:: extra:: kernel32:: * ;
318
+ import win32:: * ;
319
+ fill_utf16_buf_and_decode ( ) { |buf, sz|
320
+ GetModuleFileNameW ( 0 u, buf, sz)
321
+ }
298
322
}
299
323
324
+ option:: map ( load_self ( ) ) { |pth|
325
+ path:: dirname ( pth) + path:: path_sep ( )
326
+ }
300
327
}
301
328
302
329
@@ -356,9 +383,9 @@ Function: path_is_dir
356
383
Indicates whether a path represents a directory.
357
384
*/
358
385
fn path_is_dir ( p : path ) -> bool {
359
- ret str:: as_buf ( p, { |buf|
386
+ str:: as_buf ( p) { |buf|
360
387
rustrt:: rust_path_is_dir ( buf) != 0 as c_int
361
- } ) ;
388
+ }
362
389
}
363
390
364
391
/*
@@ -367,9 +394,9 @@ Function: path_exists
367
394
Indicates whether a path exists.
368
395
*/
369
396
fn path_exists ( p : path ) -> bool {
370
- ret str:: as_buf ( p, { |buf|
397
+ str:: as_buf ( p) { |buf|
371
398
rustrt:: rust_path_exists ( buf) != 0 as c_int
372
- } ) ;
399
+ }
373
400
}
374
401
375
402
// FIXME: under Windows, we should prepend the current drive letter to paths
@@ -404,24 +431,25 @@ fn make_dir(p: path, mode: c_int) -> bool {
404
431
ret mkdir ( p, mode) ;
405
432
406
433
#[ cfg( target_os = "win32" ) ]
407
- fn mkdir ( _p : path , _mode : c_int ) -> bool unsafe {
434
+ fn mkdir ( p : path , _mode : c_int ) -> bool unsafe {
435
+ // FIXME: remove imports when export globs work properly.
436
+ import libc:: types:: os:: arch:: extra:: * ;
437
+ import libc:: funcs:: extra:: kernel32:: * ;
438
+ import win32:: * ;
408
439
// FIXME: turn mode into something useful?
409
- ret as_c_charp ( _p, { |buf|
410
- // FIXME: remove imports when export globs work properly.
411
- import libc:: types:: os:: arch:: extra:: * ;
412
- import libc:: funcs:: extra:: kernel32;
413
- kernel32:: CreateDirectoryA (
414
- buf, unsafe :: reinterpret_cast ( 0 ) ) != ( 0 as BOOL )
415
- } ) ;
440
+ as_utf16_p ( p) { |buf|
441
+ CreateDirectoryW ( buf, unsafe :: reinterpret_cast ( 0 ) )
442
+ != ( 0 as BOOL )
443
+ }
416
444
}
417
445
418
446
#[ cfg( target_os = "linux" ) ]
419
447
#[ cfg( target_os = "macos" ) ]
420
448
#[ cfg( target_os = "freebsd" ) ]
421
449
fn mkdir ( p : path , mode : c_int ) -> bool {
422
- ret as_c_charp ( p) { |c|
450
+ as_c_charp ( p) { |c|
423
451
libc:: mkdir ( c, mode as mode_t ) == ( 0 as c_int )
424
- } ;
452
+ }
425
453
}
426
454
}
427
455
@@ -468,10 +496,11 @@ fn remove_dir(p: path) -> bool {
468
496
#[ cfg( target_os = "win32" ) ]
469
497
fn rmdir ( p : path ) -> bool {
470
498
// FIXME: remove imports when export globs work properly.
471
- import libc:: funcs:: extra:: kernel32;
499
+ import libc:: funcs:: extra:: kernel32:: * ;
472
500
import libc:: types:: os:: arch:: extra:: * ;
473
- ret as_c_charp ( p) { |buf|
474
- kernel32:: RemoveDirectoryA ( buf) != ( 0 as BOOL )
501
+ import win32:: * ;
502
+ ret as_utf16_p ( p) { |buf|
503
+ RemoveDirectoryW ( buf) != ( 0 as BOOL )
475
504
} ;
476
505
}
477
506
@@ -491,10 +520,11 @@ fn change_dir(p: path) -> bool {
491
520
#[ cfg( target_os = "win32" ) ]
492
521
fn chdir ( p : path ) -> bool {
493
522
// FIXME: remove imports when export globs work properly.
494
- import libc:: funcs:: extra:: kernel32;
523
+ import libc:: funcs:: extra:: kernel32:: * ;
495
524
import libc:: types:: os:: arch:: extra:: * ;
496
- ret as_c_charp ( p) { |buf|
497
- kernel32:: SetCurrentDirectoryA ( buf) != ( 0 as BOOL )
525
+ import win32:: * ;
526
+ ret as_utf16_p ( p) { |buf|
527
+ SetCurrentDirectoryW ( buf) != ( 0 as BOOL )
498
528
} ;
499
529
}
500
530
@@ -519,10 +549,11 @@ fn remove_file(p: path) -> bool {
519
549
#[ cfg( target_os = "win32" ) ]
520
550
fn unlink ( p : path ) -> bool {
521
551
// FIXME: remove imports when export globs work properly.
522
- import libc:: funcs:: extra:: kernel32;
552
+ import libc:: funcs:: extra:: kernel32:: * ;
523
553
import libc:: types:: os:: arch:: extra:: * ;
524
- ret as_c_charp ( p) { |buf|
525
- kernel32:: DeleteFileA ( buf) != ( 0 as BOOL )
554
+ import win32:: * ;
555
+ ret as_utf16_p ( p) { |buf|
556
+ DeleteFileW ( buf) != ( 0 as BOOL )
526
557
} ;
527
558
}
528
559
0 commit comments