Implement init/deinit of inotify system
Use RAII to handle inotify resource lifetime, i.e. initialize with actor creation and deinitialize with actor deletion.
This commit is contained in:
@@ -22,9 +22,11 @@ let package = Package(
|
|||||||
.package(url: "https://github.com/tuist/Noora", from: "0.55.1")
|
.package(url: "https://github.com/tuist/Noora", from: "0.55.1")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
|
.systemLibrary(name: "CInotify"),
|
||||||
.target(
|
.target(
|
||||||
name: "Inotify",
|
name: "Inotify",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
"CInotify",
|
||||||
.product(name: "Logging", package: "swift-log"),
|
.product(name: "Logging", package: "swift-log"),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
|||||||
24
Sources/CInotify/cinotify.h
Normal file
24
Sources/CInotify/cinotify.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef CINOTIFY_H
|
||||||
|
#define CINOTIFY_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
static inline int cinotify_deinit(int fd) {
|
||||||
|
return close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int cinotify_get_errno(void) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char* get_error_message() {
|
||||||
|
int error_number = errno;
|
||||||
|
errno = 0;
|
||||||
|
char* error_message = strerror(error_number);
|
||||||
|
if (errno > 0) return NULL;
|
||||||
|
return error_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
4
Sources/CInotify/module.modulemap
Normal file
4
Sources/CInotify/module.modulemap
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
module CInotify [system] {
|
||||||
|
header "cinotify.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
@@ -1,2 +1,16 @@
|
|||||||
actor Inotify {
|
import CInotify
|
||||||
|
|
||||||
|
public actor Inotify {
|
||||||
|
private let fd: Int32
|
||||||
|
|
||||||
|
public init() throws {
|
||||||
|
self.fd = inotify_init1(Int32(IN_NONBLOCK | IN_CLOEXEC))
|
||||||
|
guard self.fd >= 0 else {
|
||||||
|
throw InotifyError.initFailed(errno: cinotify_get_errno())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
cinotify_deinit(self.fd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
Sources/Inotify/InotifyError.swift
Normal file
19
Sources/Inotify/InotifyError.swift
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import CInotify
|
||||||
|
|
||||||
|
public enum InotifyError: Error, Sendable, CustomStringConvertible {
|
||||||
|
case initFailed(errno: Int32)
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
switch self {
|
||||||
|
case .initFailed(let code):
|
||||||
|
"inotify_init1 failed: \(readableErrno(code))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func readableErrno(_ code: Int32) -> String {
|
||||||
|
if let cStr = get_error_message() {
|
||||||
|
return String(cString: cStr) + " (errno \(code))"
|
||||||
|
}
|
||||||
|
return "errno \(code)"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,6 @@ import Testing
|
|||||||
@Suite("Initialisation")
|
@Suite("Initialisation")
|
||||||
struct InitTests {
|
struct InitTests {
|
||||||
@Test func createsCleanly() async throws {
|
@Test func createsCleanly() async throws {
|
||||||
let _ = Inotify()
|
let _ = try Inotify()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user