1
1
use std:: fs:: { self , File } ;
2
- use std:: os:: unix:: fs:: { symlink, PermissionsExt } ;
2
+ use std:: os:: unix:: fs:: { symlink, PermissionsExt , MetadataExt , FileTypeExt } ;
3
3
use std:: os:: unix:: prelude:: AsRawFd ;
4
4
use std:: time:: { Duration , UNIX_EPOCH } ;
5
5
use std:: path:: Path ;
@@ -9,7 +9,7 @@ use libc::{S_IFMT, S_IFLNK, mode_t};
9
9
10
10
use nix:: { fcntl, Error } ;
11
11
use nix:: errno:: { Errno } ;
12
- use nix:: sys:: stat:: { self , fchmod, fchmodat, futimens, stat, utimes, utimensat, mkdirat} ;
12
+ use nix:: sys:: stat:: { self , fchmod, fchmodat, futimens, stat, utimes, utimensat, mkdirat, makedev , mknod , mknodat } ;
13
13
#[ cfg( any( target_os = "linux" ,
14
14
target_os = "haiku" ,
15
15
target_os = "ios" ,
@@ -294,3 +294,150 @@ fn test_mkdirat_fail() {
294
294
let result = mkdirat ( dirfd, filename, Mode :: S_IRWXU ) . unwrap_err ( ) ;
295
295
assert_eq ! ( result, Error :: Sys ( Errno :: ENOTDIR ) ) ;
296
296
}
297
+
298
+ #[ test]
299
+ fn test_mknod_success_path ( ) {
300
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
301
+ let path = & tempdir. path ( ) . join ( "test_node_name" ) ;
302
+ assert ! ( mknod( path, stat:: SFlag :: empty( ) , stat:: Mode :: empty( ) , 0 ) . is_ok( ) ) ;
303
+ assert ! ( Path :: exists( path) ) ;
304
+ }
305
+
306
+ #[ test]
307
+ fn test_mknod_success_sflag ( ) {
308
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
309
+ let path = & tempdir. path ( ) . join ( "test_node_name" ) ;
310
+ assert ! ( mknod( path, stat:: SFlag :: S_IFIFO , stat:: Mode :: empty( ) , 0 ) . is_ok( ) ) ;
311
+ let result = fs:: metadata ( path) . unwrap ( ) . file_type ( ) ;
312
+ assert ! ( result. is_fifo( ) ) ;
313
+ }
314
+
315
+ #[ test]
316
+ fn test_mknod_success_mode ( ) {
317
+ let expected_bits = stat:: SFlag :: S_IFCHR . bits ( ) | stat:: Mode :: S_IRWXU . bits ( ) ;
318
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
319
+ let path = & tempdir. path ( ) . join ( "test_node_name" ) ;
320
+ assert ! ( mknod( path, stat:: SFlag :: S_IFCHR , stat:: Mode :: S_IRWXU , 0 ) . is_ok( ) ) ;
321
+ let permissions = fs:: metadata ( path) . unwrap ( ) . permissions ( ) ;
322
+ let mode = permissions. mode ( ) ;
323
+ assert_eq ! ( mode as mode_t, expected_bits)
324
+ }
325
+
326
+ #[ test]
327
+ fn test_mknod_success_dev ( ) {
328
+ let expected_dev_t = makedev ( 109 , 234 ) ;
329
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
330
+ let path = & tempdir. path ( ) . join ( "test_node_name" ) ;
331
+ assert ! ( mknod(
332
+ path,
333
+ stat:: SFlag :: S_IFBLK ,
334
+ stat:: Mode :: empty( ) ,
335
+ expected_dev_t
336
+ )
337
+ . is_ok( ) ) ;
338
+ let result = fs:: metadata ( path) . unwrap ( ) . rdev ( ) ;
339
+ assert_eq ! ( result, expected_dev_t) ;
340
+ }
341
+
342
+ #[ test]
343
+ fn test_mknod_fail ( ) {
344
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
345
+ let path = & tempdir. path ( ) . join ( "not_existing" ) . join ( "test_node_name" ) ;
346
+ let result = mknod ( path, stat:: SFlag :: empty ( ) , stat:: Mode :: empty ( ) , 0 ) . unwrap_err ( ) ;
347
+ assert_eq ! ( result, Error :: Sys ( Errno :: ENOENT ) ) ;
348
+ }
349
+
350
+ #[ test]
351
+ #[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
352
+ fn test_mknodat_success_path ( ) {
353
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
354
+ let dirfd = fcntl:: open ( tempdir. path ( ) , fcntl:: OFlag :: empty ( ) , stat:: Mode :: empty ( ) ) . unwrap ( ) ;
355
+ let path = "test_node_name" ;
356
+ assert ! ( mknodat(
357
+ Some ( dirfd) ,
358
+ path,
359
+ stat:: SFlag :: empty( ) ,
360
+ stat:: Mode :: empty( ) ,
361
+ 0
362
+ )
363
+ . is_ok( ) ) ;
364
+ assert ! ( Path :: exists( & tempdir. path( ) . join( path) ) ) ;
365
+ }
366
+
367
+ #[ test]
368
+ #[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
369
+ fn test_mknodat_success_sflag ( ) {
370
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
371
+ let dirfd = fcntl:: open ( tempdir. path ( ) , fcntl:: OFlag :: empty ( ) , stat:: Mode :: empty ( ) ) . unwrap ( ) ;
372
+ let path = "test_node_name" ;
373
+ assert ! ( mknodat(
374
+ Some ( dirfd) ,
375
+ path,
376
+ stat:: SFlag :: S_IFIFO ,
377
+ stat:: Mode :: empty( ) ,
378
+ 0
379
+ )
380
+ . is_ok( ) ) ;
381
+ let result = fs:: metadata ( & tempdir. path ( ) . join ( path) )
382
+ . unwrap ( )
383
+ . file_type ( ) ;
384
+ assert ! ( result. is_fifo( ) ) ;
385
+ }
386
+
387
+ #[ test]
388
+ #[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
389
+ fn test_mknodat_success_mode ( ) {
390
+ let expected_bits = stat:: SFlag :: S_IFCHR . bits ( ) | stat:: Mode :: S_IRWXU . bits ( ) ;
391
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
392
+ let dirfd = fcntl:: open ( tempdir. path ( ) , fcntl:: OFlag :: empty ( ) , stat:: Mode :: empty ( ) ) . unwrap ( ) ;
393
+ let path = "test_node_name" ;
394
+ assert ! ( mknodat(
395
+ Some ( dirfd) ,
396
+ path,
397
+ stat:: SFlag :: S_IFCHR ,
398
+ stat:: Mode :: S_IRWXU ,
399
+ 0
400
+ )
401
+ . is_ok( ) ) ;
402
+ let permissions = fs:: metadata ( & tempdir. path ( ) . join ( path) )
403
+ . unwrap ( )
404
+ . permissions ( ) ;
405
+ let mode = permissions. mode ( ) ;
406
+ assert_eq ! ( mode as mode_t, expected_bits)
407
+ }
408
+
409
+ #[ test]
410
+ #[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
411
+ fn test_mknodat_success_dev ( ) {
412
+ let expected_dev_t = makedev ( 206 , 197 ) ;
413
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
414
+ let dirfd = fcntl:: open ( tempdir. path ( ) , fcntl:: OFlag :: empty ( ) , stat:: Mode :: empty ( ) ) . unwrap ( ) ;
415
+ let path = "test_node_name" ;
416
+ assert ! ( mknodat(
417
+ Some ( dirfd) ,
418
+ path,
419
+ stat:: SFlag :: S_IFBLK ,
420
+ stat:: Mode :: empty( ) ,
421
+ expected_dev_t
422
+ )
423
+ . is_ok( ) ) ;
424
+ let result = fs:: metadata ( & tempdir. path ( ) . join ( path) ) . unwrap ( ) . rdev ( ) ;
425
+ assert_eq ! ( result, expected_dev_t) ;
426
+ }
427
+
428
+ #[ test]
429
+ #[ cfg( not( any( target_os = "ios" , target_os = "macos" ) ) ) ]
430
+ fn test_mknodat_fail ( ) {
431
+ let tempdir = tempfile:: tempdir ( ) . unwrap ( ) ;
432
+ let dirfd = fcntl:: open ( tempdir. path ( ) , fcntl:: OFlag :: empty ( ) , stat:: Mode :: empty ( ) ) . unwrap ( ) ;
433
+ let path = Path :: new ( "not_existing" ) . join ( "test_node_name" ) ;
434
+ let result = mknodat (
435
+ Some ( dirfd) ,
436
+ & path,
437
+ stat:: SFlag :: empty ( ) ,
438
+ stat:: Mode :: empty ( ) ,
439
+ 0 ,
440
+ )
441
+ . unwrap_err ( ) ;
442
+ assert_eq ! ( result, Error :: Sys ( Errno :: ENOENT ) ) ;
443
+ }
0 commit comments