Sources/Pathman/Errors/ErrNo.swift
import ErrNo
// swiftlint:disable file_length
/// The Error type used by anything that throws in this library
public protocol PathmanError: Error, Equatable, CaseIterable, ExpressibleByIntegerLiteral
where AllCases == [Self],
IntegerLiteralType == ErrNo.RawValue {
var errors: [ErrNo] { get set }
init(error: ErrNo?)
}
extension ErrNo {
static var EIRRELEVANT: ErrNo { return ErrNo(rawValue: -1000) }
static var EIRRELEVANT2: ErrNo { return ErrNo(rawValue: -1001) }
}
public extension PathmanError {
static var accessDenied: Self { return Self(error: .EACCES) }
static var permissionDenied: Self { return Self(error: .EPERM) }
static var quotaReached: Self { return Self(error: .EDQUOT) }
static var segFault: Self { return Self(error: .EFAULT) }
static var interruptedBySignal: Self { return Self(error: .EINTR) }
static var noProcessFileDescriptors: Self { return Self(error: .EMFILE) }
static var noSystemFileDescriptors: Self { return Self(error: .ENFILE) }
static var pathnameTooLong: Self { return Self(error: .ENAMETOOLONG) }
static var noDevice: Self { return Self(error: .ENODEV) }
static var noKernelMemory: Self { return Self(error: .ENOMEM) }
static var deviceFull: Self { return Self(error: .ENOSPC) }
static var pathComponentNotDirectory: Self { return Self(error: .ENOTDIR) }
static var readOnlyFileSystem: Self { return Self(error: .EROFS) }
static var wouldBlock: Self { return Self(errors: .EWOULDBLOCK, .EAGAIN) }
static var ioError: Self { return Self(error: .EIO) }
static var badFileDescriptor: Self { return Self(error: .EBADF) }
static var tooManySymlinks: Self { return Self(error: .ELOOP) }
static var noRouteToPath: Self { return Self(error: .ENOENT) }
static var operationNotSupported: Self { return Self(error: .EOPNOTSUPP) }
static var isDirectory: Self { return Self(error: .EISDIR) }
static var notASocket: Self { return Self(error: .ENOTSOCK) }
static var addressInUse: Self { return Self(error: .EADDRINUSE) }
static var unknown: Self { return Self(error: ErrNo(rawValue: -42)) }
init(integerLiteral value: ErrNo.RawValue) {
let error = ErrNo(rawValue: value)
self.init(error: error)
}
init(errors: [ErrNo]) {
self.init(error: errors.first)
self.errors += errors.dropFirst()
}
init(errors: ErrNo...) {
self.init(errors: errors)
}
func contains(_ error: ErrNo) -> Bool { return errors.contains(error) }
/// A function used to return the Error based on the ErrNo
static func getError() -> Self {
return (Self.allCases + Self.knownErrors()).filter { $0.contains(ErrNo.lastError) }.first ?? .unknown
}
static func ~= (lhs: Self, rhs: Error) -> Bool {
guard let selfError = rhs as? Self else { return false }
return selfError == lhs
}
static func knownErrors() -> [Self] {
return [
Self.accessDenied, Self.permissionDenied, Self.quotaReached,
Self.segFault, Self.interruptedBySignal,
Self.noProcessFileDescriptors, Self.noSystemFileDescriptors,
Self.pathnameTooLong, Self.noDevice, Self.noKernelMemory,
Self.deviceFull, Self.pathComponentNotDirectory,
Self.readOnlyFileSystem, Self.wouldBlock, Self.ioError,
Self.badFileDescriptor, Self.tooManySymlinks, Self.noRouteToPath,
Self.operationNotSupported, Self.isDirectory, Self.notASocket,
Self.addressInUse
]
}
}
// Creating files uses the open(2) call so it's errors are the same
/// Errors thrown when a FilePath is created (see open(2))
public typealias CreateFileError = OpenFileError
/// Errors thrown when a FilePath is opened (see open(2))
public struct OpenFileError: PathmanError {
public var errors: [ErrNo]
public static let wouldBlock = OpenFileError(error: .EWOULDBLOCK)
public static let fileTooLarge = OpenFileError(error: .EFBIG)
public static let improperUseOfDirectory = OpenFileError(error: .EISDIR)
public static let invalidPermissions = OpenFileError(error: .EIRRELEVANT)
public static let createWithoutMode = OpenFileError(error: .EIRRELEVANT2)
public static let invalidMode = OpenFileError(error: .EINVAL)
public static let deviceNotOpened = OpenFileError(error: .ENXIO)
public static let pathBusy = OpenFileError(error: .ETXTBSY)
public static let pathExists = OpenFileError(error: .EEXIST)
#if os(macOS)
public static let lockedDevice = OpenFileError(error: .EAGAIN)
#endif
public static let allCases: [OpenFileError] = {
var cases: [OpenFileError] = [
.accessDenied, .quotaReached, .pathExists, .segFault, .fileTooLarge,
.interruptedBySignal, .invalidMode, .improperUseOfDirectory,
.tooManySymlinks, .noProcessFileDescriptors, .pathnameTooLong,
.noSystemFileDescriptors, .noDevice, .noRouteToPath, .noKernelMemory,
.deviceFull, .pathComponentNotDirectory, .deviceNotOpened,
.permissionDenied, .readOnlyFileSystem, .pathBusy, .wouldBlock,
.operationNotSupported
]
#if os(macOS)
cases += [.lockedDevice, .ioError]
#endif
return cases
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a FilePath is closed (see close(2))
public struct CloseFileError: PathmanError {
public var errors: [ErrNo]
public static let allCases: [CloseFileError] = {
[
.badFileDescriptor, .interruptedBySignal, .ioError
]
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a FilePath is deleted
public typealias DeleteFileError = UnlinkError
/// Errors thrown when a path is unlinked (see unlink(2))
public struct UnlinkError: PathmanError {
public var errors: [ErrNo]
public static let pathInUse = UnlinkError(error: .EBUSY)
public static let allCases: [UnlinkError] = [
.accessDenied, .permissionDenied, .pathInUse, .segFault, .ioError,
.isDirectory, .tooManySymlinks, .pathnameTooLong, .noRouteToPath,
.pathComponentNotDirectory, .noKernelMemory, .readOnlyFileSystem
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a path is linked (see link(2))
public struct LinkError: PathmanError {
public var errors: [ErrNo]
public static let alreadyExists = LinkError(error: .EEXIST)
public static let pathTypeMismatch = LinkError(error: .EIRRELEVANT)
public static let linkLimitReached = LinkError(error: .EMLINK)
public static let pathsOnDifferentFileSystems = LinkError(error: .EXDEV)
public static let allCases: [LinkError] = [
.accessDenied, .quotaReached, .alreadyExists, .segFault, .ioError,
.tooManySymlinks, .linkLimitReached, .pathnameTooLong, .noRouteToPath,
.noKernelMemory, .deviceFull, .pathComponentNotDirectory,
.operationNotSupported, .readOnlyFileSystem
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a path is symlinked (see symlink(2))
public struct SymlinkError: PathmanError {
public var errors: [ErrNo]
public static let alreadyExists = SymlinkError(error: .EEXIST)
public static let allCases: [SymlinkError] = [
.accessDenied, .quotaReached, .alreadyExists, .segFault, .ioError,
.tooManySymlinks, .pathnameTooLong, .noRouteToPath, .noKernelMemory,
.deviceFull, .pathComponentNotDirectory, .operationNotSupported,
.readOnlyFileSystem
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a DirectoryPath is opened (see opendir(3))
public struct OpenDirectoryError: PathmanError {
public var errors: [ErrNo]
public static let pathNotDirectory = OpenDirectoryError(error: .ENOTDIR)
public static let allCases: [OpenDirectoryError] = [
.noRouteToPath, .pathNotDirectory
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a DirectoryPath is closed (see closedir(3))
public struct CloseDirectoryError: PathmanError {
public var errors: [ErrNo]
public static let invalidDirectoryStream = CloseDirectoryError(error: .EBADF)
public static let allCases: [CloseDirectoryError] = [
.invalidDirectoryStream
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a DirectoryPath is created (see mkdir(2))
public struct CreateDirectoryError: PathmanError {
public var errors: [ErrNo]
public static let tooManySymlinks = CreateDirectoryError(error: .ELOOP)
public static let tooManyLinks = CreateDirectoryError(error: .EMLINK)
public static let pathExists = CreateDirectoryError(error: .EEXIST)
#if os(macOS)
public static let pathIsRootDirectory = CreateDirectoryError(error: .EISDIR)
#endif
public static let allCases: [CreateDirectoryError] = {
var cases: [CreateDirectoryError] = [
.accessDenied, .permissionDenied, .quotaReached, .pathExists, .segFault,
.tooManySymlinks, .tooManyLinks, .pathnameTooLong, .noRouteToPath,
.noKernelMemory, .deviceFull, .pathComponentNotDirectory, .readOnlyFileSystem
]
#if os(macOS)
cases.append(.pathIsRootDirectory)
#endif
return cases
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown when a DirectoryPath is deleted (see rmdir(2))
public struct DeleteDirectoryError: PathmanError {
public var errors: [ErrNo]
public static let directoryInUse = DeleteDirectoryError(error: .EBUSY)
public static let relativePath = DeleteDirectoryError(error: .EINVAL)
public static let directoryNotEmpty = DeleteDirectoryError(error: .ENOTEMPTY)
public static let allCases: [DeleteDirectoryError] = [
.accessDenied, .permissionDenied, .directoryInUse, .segFault,
.relativePath, .tooManySymlinks, .pathnameTooLong, .noRouteToPath,
.pathComponentNotDirectory, .noKernelMemory, .directoryNotEmpty,
.readOnlyFileSystem, .ioError
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown getting path information (see stat(2))
public struct StatError: PathmanError {
public var errors: [ErrNo]
public static let fileTooLarge = StatError(error: .EOVERFLOW)
public static let allCases: [StatError] = [
.accessDenied, .badFileDescriptor, .segFault, .tooManySymlinks,
.pathnameTooLong, .noRouteToPath, .noKernelMemory,
.pathComponentNotDirectory, .fileTooLarge, .ioError
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown while getting information about a user (see getpwnam(2) or getpwuid(2))
public struct UserInfoError: PathmanError {
public var errors: [ErrNo]
public static let userDoesNotExist = UserInfoError(errors: ErrNo(rawValue: 0), .ENOENT, .ESRCH, .EBADF, .EPERM)
public static let invalidHomeDirectory = UserInfoError(error: .EIRRELEVANT)
public static let allCases: [UserInfoError] = [
.userDoesNotExist, .interruptedBySignal, .ioError, noProcessFileDescriptors,
.noSystemFileDescriptors, .noKernelMemory
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown while getting information about a group (see getgrnam(2) or getgrgid(2))
public struct GroupInfoError: PathmanError {
public var errors: [ErrNo]
public static let groupDoesNotExist = GroupInfoError(errors: ErrNo(rawValue: 0), .ENOENT, .ESRCH, .EBADF, .EPERM)
public static let allCases: [GroupInfoError] = [
.groupDoesNotExist, .interruptedBySignal, .ioError, noProcessFileDescriptors,
.noSystemFileDescriptors, .noKernelMemory
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown by trying to read a fileDescriptor (see read(2))
public struct ReadError: PathmanError {
public var errors: [ErrNo]
public static let cannotReadFileDescriptor = ReadError(error: .EINVAL)
public static let cannotReadFileStream = ReadError(error: .EINVAL)
#if os(macOS)
public static let bufferAllocationFailed = ReadError(error: .ENOBUFS)
public static let deviceError = ReadError(error: .ENXIO)
public static let connectionReset = ReadError(error: .ECONNRESET)
public static let notConnected = ReadError(error: .ENOTCONN)
public static let timeout = ReadError(error: .ETIMEDOUT)
#endif
public static let allCases: [ReadError] = {
var cases: [ReadError] = [
.wouldBlock, .badFileDescriptor, .segFault, .interruptedBySignal,
.cannotReadFileDescriptor, .ioError, .isDirectory
]
#if os(macOS)
cases += [
.bufferAllocationFailed, .deviceError, .connectionReset,
.notConnected, .timeout
]
#endif
return cases
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
public init() { errors = [] }
}
/// Errors thrown by trying to seek to an offset for a fileDescriptor (see seek(2))
public struct SeekError: PathmanError {
public var errors: [ErrNo]
public static let unknownOffsetType = SeekError(error: .EIRRELEVANT)
public static let fileDescriptorIsNotOpen = SeekError(error: .EBADF)
public static let invalidOffset = SeekError(error: .EINVAL)
public static let offsetTooLarge = SeekError(error: .EOVERFLOW)
public static let fileDescriptorIsPipe = SeekError(error: .ESPIPE)
#if os(macOS)
public static let noData = SeekError(error: .ENXIO)
#endif
public static let allCases: [SeekError] = {
var cases: [SeekError] = [
.fileDescriptorIsNotOpen, .invalidOffset, .offsetTooLarge, .fileDescriptorIsPipe
]
#if os(macOS)
cases.append(.noData)
#endif
return cases
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown while expanding relative paths or symlinks (see realpath(3))
public struct RealPathError: PathmanError {
public var errors: [ErrNo]
public static let emptyPath = RealPathError(error: .EINVAL)
public static let pathComponentTooLong = RealPathError(error: .EIRRELEVANT)
public static let allCases: [RealPathError] = [
.accessDenied, .emptyPath, .ioError, .tooManySymlinks, .pathnameTooLong,
.noKernelMemory, .noRouteToPath, .pathComponentNotDirectory
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown by trying to write to a fileDescriptor (see write(2))
public struct WriteError: PathmanError {
public var errors: [ErrNo]
public static let unconnectedSocket = WriteError(error: .EDESTADDRREQ)
public static let fileTooLarge = WriteError(error: .EFBIG)
public static let cannotWriteToFileDescriptor = WriteError(error: .EINVAL)
public static let cannotWriteToFileStream = WriteError(error: .EINVAL)
public static let pipeOrSocketClosed = WriteError(error: .EPIPE)
#if os(macOS)
public static let notConnected = WriteError(error: .ECONNRESET)
public static let networkDown = WriteError(error: .ENETDOWN)
public static let networkUnreachable = WriteError(error: .ENETUNREACH)
public static let deviceError = WriteError(error: .ENXIO)
#endif
public static let allCases: [WriteError] = {
var cases: [WriteError] = [
.wouldBlock, .badFileDescriptor, .unconnectedSocket, .quotaReached,
.segFault, .fileTooLarge, .interruptedBySignal, .cannotWriteToFileDescriptor,
.ioError, .deviceFull, .permissionDenied, .pipeOrSocketClosed
]
#if os(macOS)
cases += [
.notConnected, .networkDown, .networkUnreachable, .deviceError
]
#endif
return cases
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
public init() { errors = [] }
}
/// Errors thrown while changing Path ownership (see chown(2))
public struct ChangeOwnershipError: PathmanError {
public var errors: [ErrNo]
public static let allCases: [ChangeOwnershipError] = [
.accessDenied, .permissionDenied, .segFault, .tooManySymlinks,
.pathnameTooLong, .noRouteToPath, .noKernelMemory,
.pathComponentNotDirectory, .readOnlyFileSystem, .badFileDescriptor,
.ioError
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown while changing the permissions on a Path (see chmod(2))
public struct ChangePermissionsError: PathmanError {
public var errors: [ErrNo]
public static let allCases: [ChangePermissionsError] = [
.accessDenied, .permissionDenied, .segFault, .ioError, .tooManySymlinks,
.pathnameTooLong, .noRouteToPath, .noKernelMemory,
.pathComponentNotDirectory, .readOnlyFileSystem, .badFileDescriptor
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown by moving or renaming a Path (see rename(2))
public struct MoveError: PathmanError {
public var errors: [ErrNo]
public static let pathInUse = MoveError(error: .EBUSY)
public static let invalidNewPath = MoveError(error: .EINVAL)
public static let newPathIsDirectoryButOldPathIsNot = MoveError(error: .EISDIR)
public static let symlinkLimitReached = MoveError(error: .EMLINK)
public static let newPathIsNonEmptyDirectory = MoveError(errors: .ENOTEMPTY, .EEXIST)
public static let pathsOnDifferentDevices = MoveError(error: .EXDEV)
public static let moveToDifferentPathType = MoveError(error: .EIRRELEVANT)
public static let allCases: [MoveError] = [
.accessDenied, .permissionDenied, .pathInUse, .quotaReached, .segFault,
.invalidNewPath, .newPathIsDirectoryButOldPathIsNot, .tooManySymlinks,
.symlinkLimitReached, .pathnameTooLong, .noRouteToPath, .noKernelMemory,
.deviceFull, .pathComponentNotDirectory, .newPathIsNonEmptyDirectory,
.readOnlyFileSystem, .pathsOnDifferentDevices
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
/// Errors thrown by creating/opening a temporary file/directory (see mkstemp(3)/mkdtemp(3))
public typealias MakeTemporaryError = CreateFileError
public struct ChDirError: PathmanError {
public var errors: [ErrNo]
public static let allCases: [ChDirError] = [
.accessDenied, .segFault, .ioError, .tooManySymlinks, .pathnameTooLong,
.noRouteToPath, .noKernelMemory, .pathComponentNotDirectory
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct CWDError: PathmanError {
public var errors: [ErrNo]
public static let unlinkedCWD = CWDError(error: .ENOENT)
public static let allCases: [CWDError] = [
.accessDenied, .segFault, .pathnameTooLong, .noKernelMemory, .unlinkedCWD
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct SocketError: PathmanError {
public var errors: [ErrNo]
public static let unsupportedDomain = SocketError(error: .EAFNOSUPPORT)
public static let domainNotAvailable = SocketError(error: .EINVAL)
public static let noKernelMemory = SocketError(errors: .ENOBUFS, .ENOMEM)
public static let unsupportedProtocol = SocketError(error: .EPROTONOSUPPORT)
#if os(macOS)
public static let unsupportedType = SocketError(error: .EPROTOTYPE)
#endif
public static let allCases: [SocketError] = {
var cases: [SocketError] = [
.accessDenied, .unsupportedDomain, .domainNotAvailable, .noProcessFileDescriptors,
.noSystemFileDescriptors, .noKernelMemory, .unsupportedProtocol
]
#if os(macOS)
cases.append(unsupportedType)
#endif
return cases
}()
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public typealias CloseSocketError = CloseFileError
public struct ShutdownError: PathmanError {
public var errors: [ErrNo]
public static let notConnected = ShutdownError(error: .ENOTCONN)
public static let allCases: [ShutdownError] = [
.badFileDescriptor, .notConnected, .notASocket
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct ConnectionError: PathmanError {
public var errors: [ErrNo]
public static let addressUnavailable = ConnectionError(error: .EADDRNOTAVAIL)
public static let invalidAddressForDomain = ConnectionError(error: .EAFNOSUPPORT)
public static let noRouteInCache = ConnectionError(error: .EAGAIN)
public static let wouldBlock = ConnectionError(error: .EALREADY)
public static let connectionRefused = ConnectionError(error: .ECONNREFUSED)
public static let previousConnectionInProgress = ConnectionError(error: .EINPROGRESS)
public static let alreadyConnected = ConnectionError(error: .EISCONN)
public static let networkUnreachable = ConnectionError(error: .ENETUNREACH)
public static let invalidTypeForDomain = ConnectionError(error: .EPROTOTYPE)
public static let timedOut = ConnectionError(error: .ETIMEDOUT)
public static let allCases: [ConnectionError] = [
.accessDenied, .permissionDenied, .addressInUse, .addressUnavailable,
.invalidAddressForDomain, .noRouteInCache, .wouldBlock,
.badFileDescriptor, .connectionRefused, .segFault,
.previousConnectionInProgress, .interruptedBySignal, .alreadyConnected,
.networkUnreachable, .notASocket, .invalidTypeForDomain, .timedOut
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct BindError: PathmanError {
public var errors: [ErrNo]
public static let socketAlreadyBound = BindError(error: .EINVAL)
public static let nonexistentInterfaceOrAddress = BindError(error: .EADDRNOTAVAIL)
public static let allCases: [BindError] = [
.accessDenied, .addressInUse, .badFileDescriptor, .socketAlreadyBound,
.notASocket, .nonexistentInterfaceOrAddress, .segFault,
.tooManySymlinks, .pathnameTooLong, .noRouteToPath, .noKernelMemory,
.pathComponentNotDirectory, .readOnlyFileSystem
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct ListenError: PathmanError {
public var errors: [ErrNo]
public static let socketCannotListen = ListenError(error: .EOPNOTSUPP)
public static let allCases: [ListenError] = [
.addressInUse, .badFileDescriptor, .notASocket, .socketCannotListen
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct AcceptError: PathmanError {
public var errors: [ErrNo]
public static let connectionAborted = AcceptError(error: .ECONNABORTED)
public static let notListening = AcceptError(error: .EINVAL)
public static let noKernelMemory = AcceptError(errors: .ENOBUFS, .ENOMEM)
public static let invalidSocketType = AcceptError(error: .EOPNOTSUPP)
public static let protocolError = AcceptError(error: .EPROTO)
public static let allCases: [AcceptError] = [
.wouldBlock, .badFileDescriptor, .connectionAborted, .segFault,
.interruptedBySignal, .notListening, .noProcessFileDescriptors,
.noSystemFileDescriptors, .noKernelMemory, .notASocket,
.invalidSocketType, .protocolError, .permissionDenied
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct SendError: PathmanError {
public var errors: [ErrNo]
public static let connectionReset = SendError(error: .ECONNRESET)
public static let missingDestination = SendError(error: .EDESTADDRREQ)
public static let invalidFlags = SendError(error: .EINVAL)
public static let alreadyConnected = SendError(error: .EISCONN)
public static let notConnected = SendError(error: .ENOTCONN)
public static let invalidMessageSize = SendError(error: .EMSGSIZE)
public static let connectionShutdown = SendError(error: .EPIPE)
public static let allCases: [SendError] = [
.accessDenied, .wouldBlock, .badFileDescriptor, .connectionReset,
.missingDestination, .segFault, .interruptedBySignal, .invalidFlags,
.alreadyConnected, .notConnected, .invalidMessageSize, .noKernelMemory,
.notASocket, .connectionShutdown
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}
public struct SyncError: PathmanError {
public var errors: [ErrNo]
public static let cannotSyncSpecialFile = SyncError(errors: .EROFS, .EINVAL)
public static let noSpace = SyncError(errors: .ENOSPC, .EDQUOT)
public static let allCases: [SyncError] = [
.badFileDescriptor, .ioError, .cannotSyncSpecialFile, .noSpace
]
public init(error: ErrNo?) { errors = error == nil ? [] : [error!] }
}