探索标准 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 许可证下发布。