mirror of
https://github.com/apple/swift-foundation.git
synced 2025-05-23 22:13:35 +08:00
* (120741818) Port FileManager to swift-foundation * (120741818) Fix linux test failures * (120741818) Fix build failures
114 lines
3.9 KiB
Swift
114 lines
3.9 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2023 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#if canImport(Darwin)
|
|
import Darwin
|
|
#elseif canImport(Glibc)
|
|
import Glibc
|
|
#endif
|
|
|
|
extension _FileManagerImpl {
|
|
func createSymbolicLink(
|
|
at url: URL,
|
|
withDestinationURL destURL: URL
|
|
) throws {
|
|
guard url.isFileURL else {
|
|
throw CocoaError.errorWithFilePath(.fileReadUnsupportedScheme, url)
|
|
}
|
|
|
|
// If there's no scheme, then this is probably a relative URL.
|
|
if destURL.scheme != nil && !destURL.isFileURL {
|
|
throw CocoaError.errorWithFilePath(.fileWriteUnsupportedScheme, destURL)
|
|
}
|
|
|
|
let path = url.path
|
|
let destPath = destURL.path
|
|
guard !path.isEmpty else {
|
|
throw CocoaError.errorWithFilePath(.fileNoSuchFile, url)
|
|
}
|
|
guard !destPath.isEmpty else {
|
|
throw CocoaError.errorWithFilePath(.fileNoSuchFile, destURL)
|
|
}
|
|
|
|
try createSymbolicLink(atPath: path, withDestinationPath: destPath)
|
|
}
|
|
|
|
func createSymbolicLink(
|
|
atPath path: String,
|
|
withDestinationPath destPath: String
|
|
) throws {
|
|
try fileManager.withFileSystemRepresentation(for: path) { srcRep in
|
|
guard let srcRep else {
|
|
throw CocoaError.errorWithFilePath(.fileReadUnknown, path)
|
|
}
|
|
|
|
try fileManager.withFileSystemRepresentation(for: destPath) { destRep in
|
|
guard let destRep else {
|
|
throw CocoaError.errorWithFilePath(.fileReadUnknown, destPath)
|
|
}
|
|
|
|
if symlink(destRep, srcRep) != 0 {
|
|
throw CocoaError.errorWithFilePath(path, errno: errno, reading: false)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func linkItem(
|
|
at srcURL: URL,
|
|
to dstURL: URL
|
|
) throws {
|
|
guard srcURL.isFileURL else {
|
|
throw CocoaError.errorWithFilePath(.fileReadUnsupportedScheme, srcURL)
|
|
}
|
|
|
|
guard dstURL.isFileURL else {
|
|
throw CocoaError.errorWithFilePath(.fileWriteUnsupportedScheme, dstURL)
|
|
}
|
|
|
|
let srcPath = srcURL.path
|
|
let dstPath = dstURL.path
|
|
guard !srcPath.isEmpty else {
|
|
throw CocoaError.errorWithFilePath(.fileNoSuchFile, srcURL)
|
|
}
|
|
guard !dstPath.isEmpty else {
|
|
throw CocoaError.errorWithFilePath(.fileNoSuchFile, dstURL)
|
|
}
|
|
|
|
try linkItem(atPath: srcPath, toPath: dstPath)
|
|
}
|
|
|
|
func linkItem(
|
|
atPath srcPath: String,
|
|
toPath dstPath: String
|
|
) throws {
|
|
try _FileOperations.linkFile(srcPath, to: dstPath, with: fileManager)
|
|
}
|
|
|
|
func destinationOfSymbolicLink(atPath path: String) throws -> String {
|
|
try fileManager.withFileSystemRepresentation(for: path) { rep in
|
|
guard let rep else {
|
|
throw CocoaError.errorWithFilePath(.fileReadUnknown, path)
|
|
}
|
|
|
|
return try withUnsafeTemporaryAllocation(of: CChar.self, capacity: FileManager.MAX_PATH_SIZE) { buffer in
|
|
let charsReturned = readlink(rep, buffer.baseAddress!, FileManager.MAX_PATH_SIZE)
|
|
guard charsReturned >= 0 else {
|
|
throw CocoaError.errorWithFilePath(path, errno: errno, reading: true)
|
|
}
|
|
|
|
return fileManager.string(withFileSystemRepresentation: buffer.baseAddress!, length: charsReturned)
|
|
}
|
|
}
|
|
}
|
|
}
|