update for 0.13.0

This commit is contained in:
Jeffrey C. Ollie 2024-09-26 23:49:30 -05:00
parent 2bc8566022
commit 85cbf31b95
Signed by: jeff
GPG key ID: 6F86035A6D97044E
7 changed files with 181 additions and 49 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
/zig-cache /.zig-cache
/zig-out /zig-out

View file

@ -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);
} }

View file

@ -5,6 +5,8 @@
.dependencies = .{}, .dependencies = .{},
.paths = .{ .paths = .{
"", "build.zig",
"build.zig.zon",
"src",
}, },
} }

60
flake.lock Normal file
View 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
View 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
'';
};
};
}
);
}

View file

@ -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));
} }

View file

@ -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( {
const rc = std.os.linux.fcntl(
self.memfd, self.memfd,
F_ADD_SEALS, F_ADD_SEALS,
F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_EXEC, 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( {
const rc = std.os.linux.sendmsg(
self.logger.socket, self.logger.socket,
&msghdr, &msghdr,
0, 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: {
const rc = std.os.linux.memfd_create(
"zig", "zig",
std.os.MFD.CLOEXEC | std.os.MFD.ALLOW_SEALING | MFD_NOEXEC_SEAL, 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,