@@ -362,7 +362,6 @@ class LocalFS: FSProxy, @unchecked Sendable {
362
362
/// Check whether a given path is a symlink.
363
363
/// - parameter destinationExists: If the path is a symlink, then this `inout` parameter will be set to `true` if the destination exists. Otherwise it will be set to `false`.
364
364
func isSymlink( _ path: Path , _ destinationExists: inout Bool ) -> Bool {
365
- #if os(Windows)
366
365
do {
367
366
let destination = try fileManager. destinationOfSymbolicLink ( atPath: path. str)
368
367
destinationExists = exists ( ( path. isAbsolute ? path. dirname : Path . currentDirectory) . join ( destination) )
@@ -371,22 +370,6 @@ class LocalFS: FSProxy, @unchecked Sendable {
371
370
destinationExists = false
372
371
return false
373
372
}
374
- #else
375
- destinationExists = false
376
- var statBuf = stat ( )
377
- if lstat ( path. str, & statBuf) < 0 {
378
- return false
379
- }
380
- guard createFileInfo ( statBuf) . isSymlink else {
381
- return false
382
- }
383
- statBuf = stat ( )
384
- if stat ( path. str, & statBuf) < 0 {
385
- return true
386
- }
387
- destinationExists = true
388
- return true
389
- #endif
390
373
}
391
374
392
375
func listdir( _ path: Path ) throws -> [ String ] {
@@ -397,70 +380,11 @@ class LocalFS: FSProxy, @unchecked Sendable {
397
380
/// - parameter recursive: If `false`, then the parent directory at `path` must already exist in order to create the directory. If it doesn't, then it will return without creating the directory (it will not throw an exception). If `true`, then the directory hierarchy of `path` will be created if possible.
398
381
func createDirectory( _ path: Path , recursive: Bool ) throws {
399
382
// Try to create the directory.
400
- #if os(Windows)
401
383
do {
402
384
return try fileManager. createDirectory ( atPath: path. str, withIntermediateDirectories: recursive)
403
385
} catch {
404
386
throw StubError . error ( " Could not create directory at path ' \( path. str) ': \( error) " )
405
387
}
406
- #else
407
- let result = mkdir ( path. str, S_IRWXU | S_IRWXG | S_IRWXO)
408
-
409
- // If it succeeded, we are done.
410
- if result == 0 {
411
- return
412
- }
413
-
414
- // If the failure was because something exists at this path, then we examine it to see whether it means we're okay.
415
- if errno == EEXIST {
416
- var destinationExists = false
417
- if isDirectory ( path) {
418
- // If the item at the path is a directory, then we're good. This includes if it's a symlink which points to a directory.
419
- return
420
- }
421
- else if isSymlink ( path, & destinationExists) {
422
- // If the item at the path is a symlink, then we check whether it's a broken symlink or points to something that is not a directory.
423
- if destinationExists {
424
- // The destination does exist, so it's not a directory.
425
- throw StubError . error ( " File is a symbolic link which references a path which is not a directory: \( path. str) " )
426
- }
427
- else {
428
- // The destination does not exist - throw an exception because we have a broken symlink.
429
- throw StubError . error ( " File is a broken symbolic link: \( path. str) " )
430
- }
431
- }
432
- else {
433
- /// The path exists but is not a directory
434
- throw StubError . error ( " File exists but is not a directory: \( path. str) " )
435
- }
436
- }
437
-
438
- // If we are recursive and not the root path, then...
439
- if recursive && !path. isRoot {
440
- // If it failed due to ENOENT (e.g., a missing parent), then attempt to create the parent and retry.
441
- if errno == ENOENT {
442
- // Attempt to create the parent.
443
- guard path. isAbsolute else {
444
- throw StubError . error ( " Cannot recursively create directory at non-absolute path: \( path. str) " )
445
- }
446
- try createDirectory ( path. dirname, recursive: true )
447
-
448
- // Re-attempt creation, non-recursively.
449
- try createDirectory ( path)
450
-
451
- // We are done.
452
- return
453
- }
454
-
455
- // If our parent is not a directory, then report that.
456
- if !isDirectory( path. dirname) {
457
- throw StubError . error ( " File exists but is not a directory: \( path. dirname. str) " )
458
- }
459
- }
460
-
461
- // Otherwise, we failed due to some other error. Report it.
462
- throw POSIXError ( errno, context: " mkdir " , path. str, " S_IRWXU | S_IRWXG | S_IRWXO " )
463
- #endif
464
388
}
465
389
466
390
func createTemporaryDirectory( parent: Path ) throws -> Path {
@@ -562,24 +486,12 @@ class LocalFS: FSProxy, @unchecked Sendable {
562
486
}
563
487
564
488
func remove( _ path: Path ) throws {
565
- guard unlink ( path. str) == 0 else {
566
- throw POSIXError ( errno, context: " unlink " , path. str)
567
- }
489
+ try fileManager. removeItem ( atPath: path. str)
568
490
}
569
491
570
492
func removeDirectory( _ path: Path ) throws {
571
493
if isDirectory ( path) {
572
- #if os(Windows)
573
494
try fileManager. removeItem ( atPath: path. str)
574
- #else
575
- var paths = [ path]
576
- try traverse ( path) { paths. append ( $0) }
577
- for path in paths. reversed ( ) {
578
- guard SWBLibc . remove ( path. str) == 0 else {
579
- throw POSIXError ( errno, context: " remove " , path. str)
580
- }
581
- }
582
- #endif
583
495
}
584
496
}
585
497
@@ -608,69 +520,11 @@ class LocalFS: FSProxy, @unchecked Sendable {
608
520
}
609
521
610
522
func touch( _ path: Path ) throws {
611
- #if os(Windows)
612
- let handle : HANDLE = path. withPlatformString {
613
- CreateFileW ( $0, DWORD ( GENERIC_WRITE) , DWORD ( FILE_SHARE_READ) , nil ,
614
- DWORD ( OPEN_EXISTING) , DWORD ( FILE_FLAG_BACKUP_SEMANTICS) , nil )
615
- }
616
- if handle == INVALID_HANDLE_VALUE {
617
- throw StubError . error ( " Failed to update file time " )
618
- }
619
- try handle. closeAfter {
620
- var ft = FILETIME ( )
621
- var st = SYSTEMTIME ( )
622
- GetSystemTime ( & st)
623
- SystemTimeToFileTime ( & st, & ft)
624
- if !SetFileTime( handle, nil , & ft, & ft) {
625
- throw StubError . error ( " Failed to update file time " )
626
- }
627
- }
628
- #else
629
- try eintrLoop {
630
- guard utimensat ( AT_FDCWD, path. str, nil , 0 ) == 0 else {
631
- throw POSIXError ( errno, context: " utimensat " , " AT_FDCWD " , path. str)
632
- }
633
- }
634
- #endif
523
+ try fileManager. setAttributes ( [ . modificationDate: Date ( ) ] , ofItemAtPath: path. str)
635
524
}
636
525
637
526
func setFileTimestamp( _ path: Path , timestamp: Int ) throws {
638
- #if os(Windows)
639
- let handle : HANDLE = path. withPlatformString {
640
- CreateFileW ( $0, DWORD ( GENERIC_WRITE) , DWORD ( FILE_SHARE_READ) , nil ,
641
- DWORD ( OPEN_EXISTING) , DWORD ( FILE_FLAG_BACKUP_SEMANTICS) , nil )
642
- }
643
- if handle == INVALID_HANDLE_VALUE {
644
- throw StubError . error ( " Failed to update file time " )
645
- }
646
- try handle. closeAfter {
647
- // Number of 100ns intervals between 1601 and 1970 epochs
648
- let delta = 116444736000000000
649
-
650
- let ll = UInt64 ( ( timestamp * 10000000 ) + delta)
651
-
652
- var timeInt = ULARGE_INTEGER ( )
653
- timeInt. QuadPart = ll
654
-
655
- var ft = FILETIME ( )
656
- ft. dwLowDateTime = timeInt. LowPart
657
- ft. dwHighDateTime = timeInt. HighPart
658
- if !SetFileTime( handle, nil , & ft, & ft) {
659
- throw StubError . error ( " Failed to update file time " )
660
- }
661
- }
662
- #else
663
- try eintrLoop {
664
- #if os(Linux) || os(Android)
665
- let UTIME_OMIT = 1073741822
666
- #endif
667
- let atime = timespec ( tv_sec: 0 , tv_nsec: Int ( UTIME_OMIT) )
668
- let mtime = timespec ( tv_sec: timestamp, tv_nsec: 0 )
669
- guard utimensat ( AT_FDCWD, path. str, [ atime, mtime] , 0 ) == 0 else {
670
- throw POSIXError ( errno, context: " utimensat " , " AT_FDCWD " , path. str, String ( timestamp) )
671
- }
672
- }
673
- #endif
527
+ try fileManager. setAttributes ( [ . modificationDate: Date ( timeIntervalSince1970: Double ( timestamp) ) ] , ofItemAtPath: path. str)
674
528
}
675
529
676
530
func getFileInfo( _ path: Path ) throws -> FileInfo {
@@ -711,7 +565,7 @@ class LocalFS: FSProxy, @unchecked Sendable {
711
565
#if os(Windows)
712
566
try eintrLoop {
713
567
guard stat ( path. str, & buf) == 0 else {
714
- throw POSIXError ( errno, context: " lstat " , path. str)
568
+ throw POSIXError ( errno, context: " stat " , path. str)
715
569
}
716
570
}
717
571
0 commit comments