1
1
use anyhow:: Result ;
2
2
3
- use cap_std:: fs:: { Dir , File , Permissions , PermissionsExt } ;
3
+ #[ cfg( unix) ]
4
+ use cap_std:: fs:: PermissionsExt ;
5
+ use cap_std:: fs:: { Dir , File , Permissions } ;
6
+ use cap_std_ext:: cap_std;
7
+ #[ cfg( not( windows) ) ]
4
8
use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
5
9
use cap_std_ext:: dirext:: { CapStdExtDirExt , WalkConfiguration } ;
6
- use cap_std_ext:: { cap_std, RootDir } ;
10
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
11
+ use cap_std_ext:: RootDir ;
12
+ #[ cfg( unix) ]
7
13
use rustix:: path:: DecInt ;
8
14
use std:: cmp:: Ordering ;
9
15
use std:: ffi:: OsStr ;
@@ -13,6 +19,7 @@ use std::path::{Path, PathBuf};
13
19
use std:: { process:: Command , sync:: Arc } ;
14
20
15
21
#[ test]
22
+ #[ cfg( not( windows) ) ]
16
23
fn take_fd ( ) -> Result < ( ) > {
17
24
let mut c = Command :: new ( "/bin/bash" ) ;
18
25
c. arg ( "-c" ) ;
@@ -31,6 +38,7 @@ fn take_fd() -> Result<()> {
31
38
}
32
39
33
40
#[ test]
41
+ #[ cfg( not( windows) ) ]
34
42
fn fchdir ( ) -> Result < ( ) > {
35
43
static CONTENTS : & [ u8 ] = b"hello world" ;
36
44
@@ -108,20 +116,23 @@ fn ensuredir() -> Result<()> {
108
116
td. write ( p, "some file contents" ) ?;
109
117
assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
110
118
111
- // Broken symlinks aren't followed and are errors
112
- let p = Path :: new ( "linksrc" ) ;
113
- td. symlink ( "linkdest" , p) ?;
114
- assert ! ( td. metadata( p) . is_err( ) ) ;
115
- assert ! ( td
116
- . symlink_metadata_optional( p)
117
- . unwrap( )
118
- . unwrap( )
119
- . is_symlink( ) ) ;
120
- // Non-broken symlinks are also an error
121
- assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
122
- td. create_dir ( "linkdest" ) ?;
123
- assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
124
- assert ! ( td. metadata_optional( p) . unwrap( ) . unwrap( ) . is_dir( ) ) ;
119
+ #[ cfg( not( windows) ) ]
120
+ {
121
+ // Broken symlinks aren't followed and are errors
122
+ let p = Path :: new ( "linksrc" ) ;
123
+ td. symlink ( "linkdest" , p) ?;
124
+ assert ! ( td. metadata( p) . is_err( ) ) ;
125
+ assert ! ( td
126
+ . symlink_metadata_optional( p)
127
+ . unwrap( )
128
+ . unwrap( )
129
+ . is_symlink( ) ) ;
130
+ // Non-broken symlinks are also an error
131
+ assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
132
+ td. create_dir ( "linkdest" ) ?;
133
+ assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
134
+ assert ! ( td. metadata_optional( p) . unwrap( ) . unwrap( ) . is_dir( ) ) ;
135
+ }
125
136
126
137
Ok ( ( ) )
127
138
}
@@ -142,12 +153,15 @@ fn test_remove_all_optional() -> Result<()> {
142
153
td. write ( p, "test" ) ?;
143
154
assert ! ( td. remove_all_optional( p) . unwrap( ) ) ;
144
155
145
- // symlinks; broken and not
146
- let p = Path :: new ( "linksrc" ) ;
147
- td. symlink ( "linkdest" , p) ?;
148
- assert ! ( td. remove_all_optional( p) . unwrap( ) ) ;
149
- td. symlink ( "linkdest" , p) ?;
150
- assert ! ( td. remove_all_optional( p) . unwrap( ) ) ;
156
+ #[ cfg( not( windows) ) ]
157
+ {
158
+ // symlinks; broken and not
159
+ let p = Path :: new ( "linksrc" ) ;
160
+ td. symlink ( "linkdest" , p) ?;
161
+ assert ! ( td. remove_all_optional( p) . unwrap( ) ) ;
162
+ td. symlink ( "linkdest" , p) ?;
163
+ assert ! ( td. remove_all_optional( p) . unwrap( ) ) ;
164
+ }
151
165
152
166
Ok ( ( ) )
153
167
}
@@ -198,50 +212,55 @@ fn link_tempfile_with() -> Result<()> {
198
212
) ;
199
213
assert_eq ! ( td. metadata( p) ?. permissions( ) , default_perms) ;
200
214
201
- td. atomic_write_with_perms ( p, "atomic replacement 3\n " , Permissions :: from_mode ( 0o700 ) )
202
- . unwrap ( ) ;
203
- assert_eq ! (
204
- td. read_to_string( p) . unwrap( ) . as_str( ) ,
205
- "atomic replacement 3\n "
206
- ) ;
207
- assert_eq ! ( td. metadata( p) ?. permissions( ) . mode( ) & 0o777 , 0o700 ) ;
208
-
209
- // Ensure we preserve the executable bit on an existing file
210
- assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o700 , 0o700 ) ;
211
- td. atomic_write ( p, "atomic replacement 4\n " ) . unwrap ( ) ;
212
- assert_eq ! (
213
- td. read_to_string( p) . unwrap( ) . as_str( ) ,
214
- "atomic replacement 4\n "
215
- ) ;
216
- assert_eq ! ( td. metadata( p) ?. permissions( ) . mode( ) & 0o777 , 0o700 ) ;
217
-
218
- // But we should ignore permissions on a symlink (both existing and broken)
219
- td. remove_file ( p) ?;
220
- let p2 = Path :: new ( "bar" ) ;
221
- td. atomic_write_with_perms ( p2, "link target" , Permissions :: from_mode ( 0o755 ) )
222
- . unwrap ( ) ;
223
- td. symlink ( p2, p) ?;
224
- td. atomic_write ( p, "atomic replacement symlink\n " ) . unwrap ( ) ;
225
- assert_eq ! ( td. metadata( p) ?. permissions( ) , default_perms) ;
226
- // And break the link
227
- td. remove_file ( p2) ?;
228
- td. atomic_write ( p, "atomic replacement symlink\n " ) . unwrap ( ) ;
229
- assert_eq ! ( td. metadata( p) ?. permissions( ) , default_perms) ;
215
+ #[ cfg( unix) ]
216
+ {
217
+ td. atomic_write_with_perms ( p, "atomic replacement 3\n " , Permissions :: from_mode ( 0o700 ) )
218
+ . unwrap ( ) ;
219
+ assert_eq ! (
220
+ td. read_to_string( p) . unwrap( ) . as_str( ) ,
221
+ "atomic replacement 3\n "
222
+ ) ;
223
+ assert_eq ! ( td. metadata( p) ?. permissions( ) . mode( ) & 0o777 , 0o700 ) ;
224
+
225
+ // Ensure we preserve the executable bit on an existing file
226
+ assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o700 , 0o700 ) ;
227
+ td. atomic_write ( p, "atomic replacement 4\n " ) . unwrap ( ) ;
228
+ assert_eq ! (
229
+ td. read_to_string( p) . unwrap( ) . as_str( ) ,
230
+ "atomic replacement 4\n "
231
+ ) ;
232
+ assert_eq ! ( td. metadata( p) ?. permissions( ) . mode( ) & 0o777 , 0o700 ) ;
233
+
234
+ // But we should ignore permissions on a symlink (both existing and broken)
235
+ td. remove_file ( p) ?;
236
+ let p2 = Path :: new ( "bar" ) ;
237
+ td. atomic_write_with_perms ( p2, "link target" , Permissions :: from_mode ( 0o755 ) )
238
+ . unwrap ( ) ;
239
+ td. symlink ( p2, p) ?;
240
+ td. atomic_write ( p, "atomic replacement symlink\n " ) . unwrap ( ) ;
241
+ assert_eq ! ( td. metadata( p) ?. permissions( ) , default_perms) ;
242
+ // And break the link
243
+ td. remove_file ( p2) ?;
244
+ td. atomic_write ( p, "atomic replacement symlink\n " ) . unwrap ( ) ;
245
+ assert_eq ! ( td. metadata( p) ?. permissions( ) , default_perms) ;
246
+
247
+ // Also test with mode 0600
248
+ td. atomic_write_with_perms ( p, "self-only file" , Permissions :: from_mode ( 0o600 ) )
249
+ . unwrap ( ) ;
250
+ assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o777 , 0o600 ) ;
251
+ td. atomic_write ( p, "self-only file v2" ) . unwrap ( ) ;
252
+ assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o777 , 0o600 ) ;
253
+ // But we can override
254
+ td. atomic_write_with_perms ( p, "self-only file v3" , Permissions :: from_mode ( 0o640 ) )
255
+ . unwrap ( ) ;
256
+ assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o777 , 0o640 ) ;
257
+ }
230
258
231
- // Also test with mode 0600
232
- td. atomic_write_with_perms ( p, "self-only file" , Permissions :: from_mode ( 0o600 ) )
233
- . unwrap ( ) ;
234
- assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o777 , 0o600 ) ;
235
- td. atomic_write ( p, "self-only file v2" ) . unwrap ( ) ;
236
- assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o777 , 0o600 ) ;
237
- // But we can override
238
- td. atomic_write_with_perms ( p, "self-only file v3" , Permissions :: from_mode ( 0o640 ) )
239
- . unwrap ( ) ;
240
- assert_eq ! ( td. metadata( p) . unwrap( ) . permissions( ) . mode( ) & 0o777 , 0o640 ) ;
241
259
Ok ( ( ) )
242
260
}
243
261
244
262
#[ test]
263
+ #[ cfg( unix) ]
245
264
fn test_timestamps ( ) -> Result < ( ) > {
246
265
let td = cap_tempfile:: tempdir ( cap_std:: ambient_authority ( ) ) ?;
247
266
let p = Path :: new ( "foo" ) ;
@@ -292,20 +311,23 @@ fn ensuredir_utf8() -> Result<()> {
292
311
td. write ( p, "some file contents" ) ?;
293
312
assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
294
313
295
- // Broken symlinks aren't followed and are errors
296
- let p = Utf8Path :: new ( "linksrc" ) ;
297
- td. symlink ( "linkdest" , p) ?;
298
- assert ! ( td. metadata( p) . is_err( ) ) ;
299
- assert ! ( td
300
- . symlink_metadata_optional( p)
301
- . unwrap( )
302
- . unwrap( )
303
- . is_symlink( ) ) ;
304
- // Non-broken symlinks are also an error
305
- assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
306
- td. create_dir ( "linkdest" ) ?;
307
- assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
308
- assert ! ( td. metadata_optional( p) . unwrap( ) . unwrap( ) . is_dir( ) ) ;
314
+ #[ cfg( not( windows) ) ]
315
+ {
316
+ // Broken symlinks aren't followed and are errors
317
+ let p = Utf8Path :: new ( "linksrc" ) ;
318
+ td. symlink ( "linkdest" , p) ?;
319
+ assert ! ( td. metadata( p) . is_err( ) ) ;
320
+ assert ! ( td
321
+ . symlink_metadata_optional( p)
322
+ . unwrap( )
323
+ . unwrap( )
324
+ . is_symlink( ) ) ;
325
+ // Non-broken symlinks are also an error
326
+ assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
327
+ td. create_dir ( "linkdest" ) ?;
328
+ assert ! ( td. ensure_dir_with( p, b) . is_err( ) ) ;
329
+ assert ! ( td. metadata_optional( p) . unwrap( ) . unwrap( ) . is_dir( ) ) ;
330
+ }
309
331
310
332
Ok ( ( ) )
311
333
}
@@ -345,6 +367,7 @@ fn filenames_utf8() -> Result<()> {
345
367
}
346
368
347
369
#[ test]
370
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
348
371
fn test_rootdir_open ( ) -> Result < ( ) > {
349
372
let td = & cap_tempfile:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
350
373
let root = RootDir :: new ( td, "." ) . unwrap ( ) ;
@@ -373,6 +396,7 @@ fn test_rootdir_open() -> Result<()> {
373
396
}
374
397
375
398
#[ test]
399
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
376
400
fn test_rootdir_entries ( ) -> Result < ( ) > {
377
401
let td = & cap_tempfile:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
378
402
let root = RootDir :: new ( td, "." ) . unwrap ( ) ;
@@ -389,6 +413,7 @@ fn test_rootdir_entries() -> Result<()> {
389
413
}
390
414
391
415
#[ test]
416
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
392
417
fn test_mountpoint ( ) -> Result < ( ) > {
393
418
let root = & Dir :: open_ambient_dir ( "/" , cap_std:: ambient_authority ( ) ) ?;
394
419
assert_eq ! ( root. is_mountpoint( "." ) . unwrap( ) , Some ( true ) ) ;
@@ -413,7 +438,7 @@ fn test_open_noxdev() -> Result<()> {
413
438
// This hard requires the host setup to have /usr/bin on the same filesystem as /
414
439
let usr = Dir :: open_ambient_dir ( "/usr" , cap_std:: ambient_authority ( ) ) ?;
415
440
assert ! ( usr. open_dir_noxdev( "bin" ) . unwrap( ) . is_some( ) ) ;
416
- // Requires a mounted /proc, but that also seems ane .
441
+ // Requires a mounted /proc, but that also seems sane .
417
442
assert ! ( root. open_dir_noxdev( "proc" ) . unwrap( ) . is_none( ) ) ;
418
443
// Test an error case
419
444
let td = cap_tempfile:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
@@ -433,10 +458,13 @@ fn test_walk() -> std::io::Result<()> {
433
458
td. write ( "usr/bin/true" , b"true" ) ?;
434
459
td. write ( "usr/lib/foo/libfoo.so" , b"libfoo" ) ?;
435
460
td. write ( "usr/lib/libbar.so" , b"libbar" ) ?;
436
- // Broken link
437
- td. symlink ( "usr/share/timezone" , "usr/share/EST" ) ?;
438
- // Symlink to self
439
- td. symlink ( "." , "usr/bin/selflink" ) ?;
461
+ #[ cfg( not( windows) ) ]
462
+ {
463
+ // Broken link
464
+ td. symlink ( "usr/share/timezone" , "usr/share/EST" ) ?;
465
+ // Symlink to self
466
+ td. symlink ( "." , "usr/bin/selflink" ) ?;
467
+ }
440
468
td. write ( "etc/foo.conf" , b"fooconf" ) ?;
441
469
td. write ( "etc/blah.conf" , b"blahconf" ) ?;
442
470
@@ -466,6 +494,7 @@ fn test_walk() -> std::io::Result<()> {
466
494
} )
467
495
. unwrap ( ) ;
468
496
assert_eq ! ( n_dirs, 4 ) ;
497
+ #[ cfg( not( windows) ) ]
469
498
assert_eq ! ( n_symlinks, 2 ) ;
470
499
assert_eq ! ( n_regfiles, 4 ) ;
471
500
}
@@ -488,6 +517,7 @@ fn test_walk() -> std::io::Result<()> {
488
517
}
489
518
490
519
#[ test]
520
+ #[ cfg( unix) ]
491
521
fn test_walk_sorted ( ) -> Result < ( ) > {
492
522
let td = cap_tempfile:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
493
523
@@ -536,6 +566,7 @@ fn test_walk_sorted() -> Result<()> {
536
566
}
537
567
538
568
#[ test]
569
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
539
570
fn test_walk_noxdev ( ) -> Result < ( ) > {
540
571
let rootfs = Dir :: open_ambient_dir ( "/" , cap_std:: ambient_authority ( ) ) ?;
541
572
0 commit comments