ErrNo

探索标准 C 错误代码的类型安全包装器。

支持 macOS 和 Linux (Ubuntu)。使用标准 ErrNo,以及平台特定的 ErrNo。

允许在使用 Swift C API 包装器时轻松检查错误代码

安装

需要 Swift 5,并通过包管理器使用 swift build 构建。

将此包含在您的 Package.swift 依赖项中

.package(url: "https://github.com/Ponyboy47/ErrNo.swift", .upToNextMinor(from: "0.5.2"))

对于 Swift 4,请使用 0.4.x 版本

用法

我本想使用枚举(就像在主分支中一样),但为了使其与 macOS 和 Linux 兼容(它们对一些相同的错误使用不同的值),这变得不可能。 所以,取而代之的是,它使用了一个带有静态常量 `let` 的结构体,以便它仍然可以像枚举一样运行,但允许扩展以添加平台特定的错误编号

import ErrNo

#if !os(linux)
import Darwin.C
#else
import Glibc
#endif

let fileDescriptor = open("/path/to/a/file.txt", 0)

// Could show you how to use ErrNo here, but there are 30+ different errnos
that could be set and I'm too lazy to demonstrate each of them
guard fileDescriptor != -1 else { exit(EXIT_FAILURE) }

// A buffer for storing a C string (array of characters)
var buffer = UnsafeMutablePointer<CChar>()

// A simple C api to read from an open file descriptor
// Returns the number of bytes that were read and put into the buffer, or -1 if
// an error occurred
guard read(fileDescriptor, &buffer, 1000) >= 0 else {
    switch ErrNo.lastError {
    case .EAGAIN:
        print("The file descriptor fd refers to a file other than a socket and has been marked nonblocking, and the read would block.")
    case .EBADF:
        print("fd is not a valid file descriptor or is not open for reading.")
    case .EFAULT:
        print("buf is outside your accessible address space.")
    case .EINTR:
        print("The call was interrupted by a signal before any data was read; see signal(7).")
    case .EINVAL:
        print("fd is attached to an object which is unsuitable for reading; or the file was opened with the O_DIRECT flag, and either the address specified in buf, the value specified in count, or the current file off‐set is not suitably aligned.")
    case .EIO:
        print("I/O error.")
    case .EISDIR:
        print("fd refers to a directory.")
    default:
        print("An undocumented errno is set for the C read(2) API call: \(error)")
    }
   exit(EXIT_FAILURE)
}

// Always be sure to close open file descriptors
guard close(fileDescriptor) != -1 else {
    switch ErrNo.lastError {
    case .EBADF:
        print("fd isn't a valid open file descriptor")
    case .EINTR:
        print("The close() call was interrupted by a signal; see signal(7).")
    case .EIO:
        print("An I/O error occurred.")
    default:
        print("Since switches must be exhaustive, you will always need to include a default case. Or you can make a case statement for all 100+ error numbers ;)")
    }
    exit(EXIT_FAILURE)
}

exit(EXIT_SUCCESS)

许可证

ErrNo 在 MIT 许可证下发布。