update for 0.13.0
This commit is contained in:
parent
2bc8566022
commit
85cbf31b95
7 changed files with 181 additions and 49 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
||||||
/zig-cache
|
/.zig-cache
|
||||||
/zig-out
|
/zig-out
|
||||||
|
|
10
build.zig
10
build.zig
|
@ -6,19 +6,19 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
_ = b.addModule("journalz", .{
|
_ = b.addModule("journalz", .{
|
||||||
.root_source_file = .{ .path = "src/root.zig" },
|
.root_source_file = b.path("src/root.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
const lib_unit_tests = b.addTest(.{
|
const unit_tests = b.addTest(.{
|
||||||
.root_source_file = .{ .path = "src/root.zig" },
|
.root_source_file = b.path("src/root.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
const run_unit_tests = b.addRunArtifact(unit_tests);
|
||||||
|
|
||||||
const test_step = b.step("test", "Run unit tests");
|
const test_step = b.step("test", "Run unit tests");
|
||||||
test_step.dependOn(&run_lib_unit_tests.step);
|
test_step.dependOn(&run_unit_tests.step);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
.dependencies = .{},
|
.dependencies = .{},
|
||||||
|
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"",
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
60
flake.lock
Normal file
60
flake.lock
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1726560853,
|
||||||
|
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1727122398,
|
||||||
|
"narHash": "sha256-o8VBeCWHBxGd4kVMceIayf5GApqTavJbTa44Xcg5Rrk=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "30439d93eb8b19861ccbe3e581abf97bdc91b093",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
34
flake.nix
Normal file
34
flake.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs = {
|
||||||
|
url = "nixpkgs/nixos-unstable";
|
||||||
|
};
|
||||||
|
flake-utils = {
|
||||||
|
url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
nixpkgs,
|
||||||
|
flake-utils,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
flake-utils.lib.eachDefaultSystem (
|
||||||
|
system: let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
devShells = {
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.zig_0_13
|
||||||
|
];
|
||||||
|
shellHook = ''
|
||||||
|
export name=journalz
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -43,5 +43,5 @@ pub fn cmsghdr(comptime T: type) type {
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
std.testing.refAllDecls(cmsghdr([3]std.os.fd_t));
|
std.testing.refAllDecls(cmsghdr([3]std.os.linux.fd_t));
|
||||||
}
|
}
|
||||||
|
|
118
src/root.zig
118
src/root.zig
|
@ -35,7 +35,7 @@ pub const Priority = enum(u3) {
|
||||||
DEBUG = 7,
|
DEBUG = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
const JOURNAL_SOCKET: []const u8 = "/run/systemd/journal/socket";
|
const JOURNAL_SOCKET: [:0]const u8 = "/run/systemd/journal/socket";
|
||||||
|
|
||||||
const SCM_RIGHTS = 1;
|
const SCM_RIGHTS = 1;
|
||||||
|
|
||||||
|
@ -54,55 +54,74 @@ pub const Logger = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
identifier: ?[]const u8,
|
identifier: ?[]const u8,
|
||||||
socket: std.os.socket_t,
|
socket: std.os.linux.socket_t,
|
||||||
path: std.os.sockaddr.un = undefined,
|
path: std.os.linux.sockaddr.un = undefined,
|
||||||
|
|
||||||
pub fn init(identifier: ?[]const u8) !Logger {
|
pub fn init(identifier: ?[]const u8) !Logger {
|
||||||
var logger = Logger{
|
var logger = Logger{
|
||||||
.identifier = identifier,
|
.identifier = identifier,
|
||||||
.socket = try std.os.socket(std.os.AF.UNIX, std.os.SOCK.DGRAM | std.os.SOCK.CLOEXEC, 0),
|
.socket = socket: {
|
||||||
|
const rc = std.os.linux.socket(
|
||||||
|
std.os.linux.AF.UNIX,
|
||||||
|
std.os.linux.SOCK.DGRAM | std.os.linux.SOCK.CLOEXEC,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
switch (std.posix.errno(rc)) {
|
||||||
|
.SUCCESS => break :socket @intCast(rc),
|
||||||
|
else => return error.Failed,
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
errdefer std.os.close(logger.socket);
|
|
||||||
|
|
||||||
logger.path.family = std.os.AF.UNIX;
|
std.debug.assert(logger.path.path.len > JOURNAL_SOCKET.len);
|
||||||
@memset(logger.path.path[0..logger.path.path.len], 0);
|
|
||||||
|
errdefer _ = std.os.linux.close(logger.socket);
|
||||||
|
|
||||||
|
logger.path.family = std.os.linux.AF.UNIX;
|
||||||
@memcpy(logger.path.path[0..JOURNAL_SOCKET.len], JOURNAL_SOCKET);
|
@memcpy(logger.path.path[0..JOURNAL_SOCKET.len], JOURNAL_SOCKET);
|
||||||
|
logger.path.path[JOURNAL_SOCKET.len] = 0;
|
||||||
|
|
||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: Self) void {
|
pub fn deinit(self: Self) void {
|
||||||
std.os.close(self.socket);
|
_ = std.os.linux.close(self.socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Message = struct {
|
const Message = struct {
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
priority: Priority,
|
priority: Priority,
|
||||||
memfd: std.os.fd_t,
|
memfd: std.os.linux.fd_t,
|
||||||
|
|
||||||
fn _writeString(self: Message, str: []const u8) !void {
|
fn writeBytes(self: Message, str: []const u8) !void {
|
||||||
const len = try std.os.write(self.memfd, str);
|
const rc = std.os.linux.write(self.memfd, str.ptr, str.len);
|
||||||
if (len != str.len) return error.ShortWrite;
|
switch (std.posix.errno(rc)) {
|
||||||
|
.SUCCESS => {
|
||||||
|
if (rc != str.len) return error.ShortWrite;
|
||||||
|
},
|
||||||
|
else => return error.Failed,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _writeU64(self: Message, native: u64) !void {
|
fn writeU64(self: Message, native: u64) !void {
|
||||||
const le = std.mem.nativeToLittle(u64, native);
|
const le = std.mem.nativeToLittle(u64, native);
|
||||||
const msg = std.mem.asBytes(&le);
|
const msg = std.mem.asBytes(&le);
|
||||||
try self._writeString(msg);
|
try self.writeBytes(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string(self: Message, key: []const u8, value: []const u8) !void {
|
pub fn string(self: Message, key: []const u8, value: []const u8) !void {
|
||||||
try self._writeString(key);
|
try self.writeBytes(key);
|
||||||
try self._writeString("\n");
|
try self.writeBytes("\n");
|
||||||
try self._writeU64(value.len);
|
try self.writeU64(value.len);
|
||||||
try self._writeString(value);
|
try self.writeBytes(value);
|
||||||
try self._writeString("\n");
|
try self.writeBytes("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int(self: Message, key: []const u8, value: anytype) !void {
|
pub fn int(self: Message, key: []const u8, value: anytype) !void {
|
||||||
if (@typeInfo(@TypeOf(value)) != .Int) @compileError("type " ++ @typeName(@TypeOf(value)) ++ " is not an integer type");
|
if (@typeInfo(@TypeOf(value)) != .Int)
|
||||||
|
@compileError("type " ++ @typeName(@TypeOf(value)) ++ " is not an integer type");
|
||||||
|
|
||||||
var buf: [32]u8 = undefined;
|
var buf: [64]u8 = undefined;
|
||||||
var fbs = std.io.fixedBufferStream(&buf);
|
var fbs = std.io.fixedBufferStream(&buf);
|
||||||
const writer = fbs.writer();
|
const writer = fbs.writer();
|
||||||
try std.fmt.formatInt(value, 10, .lower, .{}, writer);
|
try std.fmt.formatInt(value, 10, .lower, .{}, writer);
|
||||||
|
@ -124,21 +143,27 @@ pub const Logger = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(self: *const Message) !void {
|
pub fn send(self: *const Message) !void {
|
||||||
_ = try std.os.fcntl(
|
{
|
||||||
self.memfd,
|
const rc = std.os.linux.fcntl(
|
||||||
F_ADD_SEALS,
|
self.memfd,
|
||||||
F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_EXEC,
|
F_ADD_SEALS,
|
||||||
);
|
F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_EXEC,
|
||||||
|
);
|
||||||
|
switch (std.posix.errno(rc)) {
|
||||||
|
.SUCCESS => {},
|
||||||
|
else => return error.Failed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var cmsg = cmsghdr.cmsghdr(std.os.fd_t).init(
|
var cmsg = cmsghdr.cmsghdr(std.os.linux.fd_t).init(
|
||||||
.{
|
.{
|
||||||
.level = std.os.SOL.SOCKET,
|
.level = std.os.linux.SOL.SOCKET,
|
||||||
.type = SCM_RIGHTS,
|
.type = SCM_RIGHTS,
|
||||||
.data = self.memfd,
|
.data = self.memfd,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
var msghdr = std.os.msghdr_const{
|
var msghdr = std.os.linux.msghdr_const{
|
||||||
.name = @ptrCast(&self.logger.path),
|
.name = @ptrCast(&self.logger.path),
|
||||||
.namelen = @sizeOf(@TypeOf(self.logger.path)),
|
.namelen = @sizeOf(@TypeOf(self.logger.path)),
|
||||||
.iov = undefined,
|
.iov = undefined,
|
||||||
|
@ -148,27 +173,38 @@ pub const Logger = struct {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = try std.os.sendmsg(
|
{
|
||||||
self.logger.socket,
|
const rc = std.os.linux.sendmsg(
|
||||||
&msghdr,
|
self.logger.socket,
|
||||||
0,
|
&msghdr,
|
||||||
);
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
std.debug.assert(result == 0);
|
switch (std.posix.errno(rc)) {
|
||||||
|
.SUCCESS => {},
|
||||||
|
else => return error.Failed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std.os.close(self.memfd);
|
_ = std.os.linux.close(self.memfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel(self: Message) void {
|
pub fn cancel(self: Message) void {
|
||||||
std.os.close(self.memfd);
|
_ = std.os.linux.close(self.memfd);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn message(self: Logger, priority: Priority) !Message {
|
fn message(self: Logger, priority: Priority) !Message {
|
||||||
const memfd = try std.os.memfd_create(
|
const memfd: std.os.linux.fd_t = memfd: {
|
||||||
"zig",
|
const rc = std.os.linux.memfd_create(
|
||||||
std.os.MFD.CLOEXEC | std.os.MFD.ALLOW_SEALING | MFD_NOEXEC_SEAL,
|
"zig",
|
||||||
);
|
std.os.linux.MFD.CLOEXEC | std.os.linux.MFD.ALLOW_SEALING | MFD_NOEXEC_SEAL,
|
||||||
|
);
|
||||||
|
switch (std.posix.errno(rc)) {
|
||||||
|
.SUCCESS => break :memfd @intCast(rc),
|
||||||
|
else => return error.Failed,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const msg = Message{
|
const msg = Message{
|
||||||
.logger = self,
|
.logger = self,
|
||||||
|
|
Loading…
Reference in a new issue