Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package waylock for openSUSE:Factory checked 
in at 2026-09-28 10:48:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/waylock (Old)
 and      /work/SRC/openSUSE:Factory/.waylock.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "waylock"

Mon Sep 28 10:48:23 2026 rev:11 rq:1381069 version:1.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/waylock/waylock.changes  2025-10-08 
21:53:25.841908044 +0200
+++ /work/SRC/openSUSE:Factory/.waylock.new.383539/waylock.changes      
2026-09-28 10:49:28.239539353 +0200
@@ -1,0 +2,17 @@
+Sat Sep 26 16:30:08 UTC 2026 - Andrea Manzini <[email protected]>
+
+- Update to version 1.6.0:
+  * Tracks Zig's 0.16 release; no functional changes to waylock
+    itself (upstream: "no changes to waylock's behavior are
+    intended")
+- Raise the Zig toolchain BuildRequires floor for the 0.16
+  requirement: (zig >= 0.16.0 with zig < 0.17) and
+  (zig-rpm-macros >= 0.16.0 with zig-rpm-macros < 0.17)
+- Drop add-experimental-non-llvm-zig-backend.patch: upstream's
+  build.zig now has its own -Dllvm option, defaulting to the same
+  non-LLVM backend the patch forced
+- Regenerate vendor.tar.zst: bump the vendored zig-wayland
+  dependency to 0.6.0 (zig-xkbcommon stays at 0.3.0) and rebuild it
+  for Zig 0.16's reworked package-cache layout
+
+-------------------------------------------------------------------

Old:
----
  add-experimental-non-llvm-zig-backend.patch
  waylock-1.5.0.tar.gz
  waylock-1.5.0.tar.gz.sig

New:
----
  waylock-1.6.0.tar.gz
  waylock-1.6.0.tar.gz.sig

----------(Old B)----------
  Old:  (zig-rpm-macros >= 0.16.0 with zig-rpm-macros < 0.17)
- Drop add-experimental-non-llvm-zig-backend.patch: upstream's
  build.zig now has its own -Dllvm option, defaulting to the same
----------(Old E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ waylock.spec ++++++
--- /var/tmp/diff_new_pack.360pA4/_old  2026-09-28 10:49:29.038572831 +0200
+++ /var/tmp/diff_new_pack.360pA4/_new  2026-09-28 10:49:29.040572915 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package waylock
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           waylock
-Version:        1.5.0
+Version:        1.6.0
 Release:        0
 Summary:        Small screenlocker for Wayland compositors
 License:        ISC
@@ -27,12 +27,11 @@
 Source2:        https://isaacfreund.com/public_key.txt#/%{name}.keyring
 Source3:        
https://codeberg.org/ifreund/waylock/releases/download/v%{version}/waylock-%{version}.tar.gz.sig
 Source4:        vendor.tar.zst
-Patch1:         add-experimental-non-llvm-zig-backend.patch
 BuildRequires:  pkgconfig
 BuildRequires:  scdoc >= 1.9.2
 BuildRequires:  zstd
-BuildRequires:  (zig >= 0.15.0 with zig < 0.16)
-BuildRequires:  (zig-rpm-macros >= 0.15.0 with zig-rpm-macros < 0.16)
+BuildRequires:  (zig >= 0.16.0 with zig < 0.17)
+BuildRequires:  (zig-rpm-macros >= 0.16.0 with zig-rpm-macros < 0.17)
 BuildRequires:  pkgconfig(pam)
 BuildRequires:  pkgconfig(wayland-protocols) >= 1.24
 BuildRequires:  pkgconfig(wayland-server) >= 1.20.0
@@ -45,17 +44,17 @@
 cause the session to be unlocked.)
 
 %prep
-%autosetup -a4 -p1
+%autosetup -a4
 
 # Replace with configuration that works in openSUSE
 cp %{SOURCE1} ./pam.d/waylock
 
 %build
-%global zig_opts --global-cache-dir vendor/ -Dpie -Dno-llvm
-%zig_build %{zig_opts}
+%global zig_opts --global-cache-dir vendor/ -Dpie
+%{zig_build} %{zig_opts}
 
 %install
-%zig_install %{zig_opts}
+%{zig_install} %{zig_opts}
 
 # Removes rpmlint error: filelist-forbidden-move-to-usr error
 mkdir -p %{buildroot}%{_pam_vendordir}

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/waylock/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.waylock.new.383539/vendor.tar.zst differ: char 6, 
line 1

++++++ waylock-1.5.0.tar.gz -> waylock-1.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/.builds/alpine.yml 
new/waylock-1.6.0/.builds/alpine.yml
--- old/waylock-1.5.0/.builds/alpine.yml        2025-09-10 10:24:33.000000000 
+0200
+++ new/waylock-1.6.0/.builds/alpine.yml        2026-04-27 11:40:52.000000000 
+0200
@@ -14,10 +14,10 @@
 tasks:
   - install_deps: |
       # Eat Github's resources rather than the Zig Software Foundation's 
resources!
-      wget -nv 
https://github.com/ifreund/zig-tarball-mirror/releases/download/0.15.1/zig-x86_64-linux-0.15.1.tar.xz
-      tar xf zig-x86_64-linux-0.15.1.tar.xz
-      sudo mv zig-x86_64-linux-0.15.1/zig /usr/bin/
-      sudo mv zig-x86_64-linux-0.15.1/lib /usr/lib/zig
+      wget -nv 
https://github.com/ifreund/zig-tarball-mirror/releases/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz
+      tar xf zig-x86_64-linux-0.16.0.tar.xz
+      sudo mv zig-x86_64-linux-0.16.0/zig /usr/bin/
+      sudo mv zig-x86_64-linux-0.16.0/lib /usr/lib/zig
   - build: |
       cd waylock
       zig build -Dman-pages
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/.builds/archlinux.yml 
new/waylock-1.6.0/.builds/archlinux.yml
--- old/waylock-1.5.0/.builds/archlinux.yml     2025-09-10 10:24:33.000000000 
+0200
+++ new/waylock-1.6.0/.builds/archlinux.yml     2026-04-27 11:40:52.000000000 
+0200
@@ -14,13 +14,15 @@
 tasks:
   - install_deps: |
       # Eat Github's resources rather than the Zig Software Foundation's 
resources!
-      wget -nv 
https://github.com/ifreund/zig-tarball-mirror/releases/download/0.15.1/zig-x86_64-linux-0.15.1.tar.xz
-      tar xf zig-x86_64-linux-0.15.1.tar.xz
-      sudo mv zig-x86_64-linux-0.15.1/zig /usr/bin/
-      sudo mv zig-x86_64-linux-0.15.1/lib /usr/lib/zig
+      wget -nv 
https://github.com/ifreund/zig-tarball-mirror/releases/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz
+      tar xf zig-x86_64-linux-0.16.0.tar.xz
+      sudo mv zig-x86_64-linux-0.16.0/zig /usr/bin/
+      sudo mv zig-x86_64-linux-0.16.0/lib /usr/lib/zig
   - build: |
       cd waylock
-      zig build -Dman-pages
+      # Arch's glibc version has SFrame sections in crt objects, force 
llvm/lld usage as a workaround
+      # https://codeberg.org/ziglang/zig/issues/31272
+      zig build -Dllvm -Dman-pages --summary all
   - fmt: |
       cd waylock
       zig fmt --check build.zig
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/.builds/freebsd.yml 
new/waylock-1.6.0/.builds/freebsd.yml
--- old/waylock-1.5.0/.builds/freebsd.yml       2025-09-10 10:24:33.000000000 
+0200
+++ new/waylock-1.6.0/.builds/freebsd.yml       2026-04-27 11:40:52.000000000 
+0200
@@ -12,10 +12,10 @@
 tasks:
   - install_deps: |
       # Eat Github's resources rather than the Zig Software Foundation's 
resources!
-      wget -nv 
https://github.com/ifreund/zig-tarball-mirror/releases/download/0.15.1/zig-x86_64-freebsd-0.15.1.tar.xz
-      tar xf zig-x86_64-freebsd-0.15.1.tar.xz
-      sudo mv zig-x86_64-freebsd-0.15.1/zig /usr/bin/
-      sudo mv zig-x86_64-freebsd-0.15.1/lib /usr/lib/zig
+      wget -nv 
https://github.com/ifreund/zig-tarball-mirror/releases/download/0.16.0/zig-x86_64-freebsd-0.16.0.tar.xz
+      tar xf zig-x86_64-freebsd-0.16.0.tar.xz
+      sudo mv zig-x86_64-freebsd-0.16.0/zig /usr/bin/
+      sudo mv zig-x86_64-freebsd-0.16.0/lib /usr/lib/zig
   - build: |
       cd waylock
       zig build -Dman-pages
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/.gitignore new/waylock-1.6.0/.gitignore
--- old/waylock-1.5.0/.gitignore        2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/.gitignore        2026-04-27 11:40:52.000000000 +0200
@@ -1,3 +1,3 @@
 .zig-cache
 zig-out
-/doc/waylock.1
+zig-pkg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/README.md new/waylock-1.6.0/README.md
--- old/waylock-1.5.0/README.md 2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/README.md 2026-04-27 11:40:52.000000000 +0200
@@ -21,7 +21,7 @@
 To compile waylock first ensure that you have the following dependencies
 installed:
 
-- [zig](https://ziglang.org/download/) 0.15
+- [zig](https://ziglang.org/download/) 0.16
 - wayland
 - wayland-protocols
 - xkbcommon
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/build.zig new/waylock-1.6.0/build.zig
--- old/waylock-1.5.0/build.zig 2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/build.zig 2026-04-27 11:40:52.000000000 +0200
@@ -18,6 +18,7 @@
 
     const strip = b.option(bool, "strip", "Omit debug information") orelse 
false;
     const pie = b.option(bool, "pie", "Build a Position Independent 
Executable") orelse false;
+    const use_llvm = b.option(bool, "llvm", "Force use of Zig's LLVM backend 
and the lld linker") orelse false;
 
     const man_pages = b.option(
         bool,
@@ -26,7 +27,6 @@
     ) orelse scdoc_found: {
         _ = b.findProgram(&.{"scdoc"}, &.{}) catch |err| switch (err) {
             error.FileNotFound => break :scdoc_found false,
-            else => return err,
         };
         break :scdoc_found true;
     };
@@ -38,7 +38,7 @@
         // This makes the caching work for the Workaround, and the extra 
argument is ignored by /bin/sh.
         scdoc.addFileArg(b.path("doc/waylock.1.scd"));
 
-        const stdout = scdoc.captureStdOut();
+        const stdout = scdoc.captureStdOut(.{});
         b.getInstallStep().dependOn(&b.addInstallFile(stdout, 
"share/man/man1/waylock.1").step);
     }
 
@@ -56,7 +56,7 @@
             const git_describe_long = b.runAllowFail(
                 &.{ "git", "-C", b.build_root.path orelse ".", "describe", 
"--long" },
                 &ret,
-                .Inherit,
+                .inherit,
             ) catch break :blk version;
 
             var it = mem.splitScalar(u8, mem.trim(u8, git_describe_long, 
&std.ascii.whitespace), '-');
@@ -97,20 +97,22 @@
             .root_source_file = b.path("src/main.zig"),
             .target = target,
             .optimize = optimize,
+            .link_libc = true,
+            .strip = strip,
         }),
+        .use_llvm = use_llvm,
+        .use_lld = use_llvm,
     });
     waylock.root_module.addOptions("build_options", options);
 
-    waylock.linkLibC();
-    waylock.linkSystemLibrary("pam");
+    waylock.root_module.linkSystemLibrary("pam", .{});
 
     waylock.root_module.addImport("wayland", wayland);
-    waylock.linkSystemLibrary("wayland-client");
+    waylock.root_module.linkSystemLibrary("wayland-client", .{});
 
     waylock.root_module.addImport("xkbcommon", xkbcommon);
-    waylock.linkSystemLibrary("xkbcommon");
+    waylock.root_module.linkSystemLibrary("xkbcommon", .{});
 
-    waylock.root_module.strip = strip;
     waylock.pie = pie;
 
     b.installArtifact(waylock);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/build.zig.zon 
new/waylock-1.6.0/build.zig.zon
--- old/waylock-1.5.0/build.zig.zon     2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/build.zig.zon     2026-04-27 11:40:52.000000000 +0200
@@ -1,11 +1,11 @@
 .{
     .name = .waylock,
-    .version = "1.5.0",
+    .version = "1.6.0",
     .paths = .{""},
     .dependencies = .{
         .wayland = .{
-            .url = 
"https://codeberg.org/ifreund/zig-wayland/archive/v0.4.0.tar.gz";,
-            .hash = 
"wayland-0.4.0-lQa1khbMAQAsLS2eBR7M5lofyEGPIbu2iFDmoz8lPC27",
+            .url = 
"https://codeberg.org/ifreund/zig-wayland/archive/v0.6.0.tar.gz";,
+            .hash = 
"wayland-0.6.0-lQa1kqz8AQADQmdNJsNhLoNHcnEGEUjrOaPV-dtEnEmX",
         },
         .xkbcommon = .{
             .url = 
"https://codeberg.org/ifreund/zig-xkbcommon/archive/v0.3.0.tar.gz";,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/Lock.zig 
new/waylock-1.6.0/src/Lock.zig
--- old/waylock-1.5.0/src/Lock.zig      2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/src/Lock.zig      2026-04-27 11:40:52.000000000 +0200
@@ -3,9 +3,13 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const assert = std.debug.assert;
+const Io = std.Io;
 const log = std.log;
 const mem = std.mem;
 const posix = std.posix;
+const system = std.posix.system;
+const process = std.process;
+const fatal = process.fatal;
 
 const wayland = @import("wayland");
 const wl = wayland.client.wl;
@@ -20,8 +24,6 @@
 const Seat = @import("Seat.zig");
 const PasswordBuffer = @import("PasswordBuffer.zig");
 
-const gpa = std.heap.c_allocator;
-
 pub const Color = enum {
     init,
     input,
@@ -48,6 +50,9 @@
     }
 };
 
+io: Io,
+gpa: mem.Allocator,
+
 state: enum {
     /// The session lock object has not yet been created.
     initializing,
@@ -84,8 +89,10 @@
 password: PasswordBuffer,
 auth_connection: auth.Connection,
 
-pub fn run(options: Options) void {
+pub fn run(io: Io, gpa: mem.Allocator, options: Options) void {
     var lock: Lock = .{
+        .io = io,
+        .gpa = gpa,
         .fork_on_lock = options.fork_on_lock,
         .ready_fd = options.ready_fd,
         .ignore_empty_password = options.ignore_empty_password,
@@ -98,9 +105,7 @@
         .outputs = undefined,
         .xkb_context = xkb.Context.new(.no_flags) orelse fatal_oom(),
         .password = PasswordBuffer.init(),
-        .auth_connection = auth.fork_child() catch |err| {
-            fatal("failed to fork child authentication process: {s}", 
.{@errorName(err)});
-        },
+        .auth_connection = auth.fork_child(io),
     };
     defer lock.deinit();
 
@@ -180,7 +185,7 @@
 
         if (lock.pollfds[poll_auth].revents & posix.POLL.IN != 0) {
             var byte: [1]u8 = undefined;
-            var reader = lock.auth_connection.reader();
+            var reader = lock.auth_connection.reader(lock.io);
             reader.interface.readSliceAll(&byte) catch |err| {
                 fatal("failed to read response from child authentication 
process: {s}", .{@errorName(err)});
             };
@@ -307,7 +312,7 @@
                 const wl_output = try registry.bind(ev.name, wl.Output, 3);
                 errdefer wl_output.release();
 
-                const output = try gpa.create(Output);
+                const output = try lock.gpa.create(Output);
                 errdefer output.destroy();
 
                 output.* = .{
@@ -366,12 +371,11 @@
             assert(lock.state == .locking);
             lock.state = .locked;
             if (lock.ready_fd) |ready_fd| {
-                const file = std.fs.File{ .handle = ready_fd };
-                file.writeAll("\n") catch |err| {
-                    log.err("failed to send readiness notification: {s}", 
.{@errorName(err)});
-                    posix.exit(1);
+                const file: Io.File = .{ .handle = ready_fd, .flags = .{ 
.nonblocking = false } };
+                defer file.close(lock.io);
+                file.writeStreamingAll(lock.io, "\n") catch |err| {
+                    fatal("failed to send readiness notification: {s}", 
.{@errorName(err)});
                 };
-                file.close();
                 lock.ready_fd = null;
             }
             if (lock.fork_on_lock) {
@@ -385,11 +389,11 @@
                 .locking => {
                     log.err("the wayland compositor has denied our attempt to 
lock the session, " ++
                         "is another ext-session-lock client already running?", 
.{});
-                    posix.exit(1);
+                    process.exit(1);
                 },
                 .locked => {
                     log.info("the wayland compositor has unlocked the session, 
exiting", .{});
-                    posix.exit(0);
+                    process.exit(0);
                 },
                 .exiting => unreachable,
             }
@@ -412,7 +416,7 @@
 
 fn send_password_to_auth(lock: *Lock) !void {
     defer lock.password.clear();
-    var writer = lock.auth_connection.writer();
+    var writer = lock.auth_connection.writer(lock.io);
     const len_bytes: [4]u8 = @bitCast(@as(u32, 
@intCast(lock.password.buffer.len)));
     try writer.interface.writeAll(&len_bytes);
     try writer.interface.writeAll(lock.password.buffer);
@@ -429,11 +433,6 @@
     }
 }
 
-fn fatal(comptime format: []const u8, args: anytype) noreturn {
-    log.err(format, args);
-    posix.exit(1);
-}
-
 fn fatal_oom() noreturn {
     fatal("out of memory during initialization", .{});
 }
@@ -459,25 +458,31 @@
     return buffers;
 }
 
-// TODO: Upstream this to the Zig standard library
-extern fn setsid() posix.pid_t;
-
 fn fork_to_background() void {
-    const pid = posix.fork() catch |err| fatal("fork failed: {s}", 
.{@errorName(err)});
+    const pid: system.pid_t = fork: {
+        const rc = system.fork();
+        switch (system.errno(rc)) {
+            .SUCCESS => break :fork @intCast(rc),
+            else => |err| fatal("fork failed: {}", .{err}),
+        }
+    };
     if (pid == 0) {
         // This can't fail as we are the child of a fork() and therefore not
         // a process group leader.
-        assert(setsid() != -1);
+        _ = system.setsid();
         // Ensure the working directory is on the root filesystem to avoid 
potentially
         // blocking some other filesystem from being unmounted.
-        posix.chdirZ("/") catch |err| {
-            // While this is a nice thing to do, it is not critical to the 
locking functionality
-            // and it is better to allow potentially unlocking the session 
rather than aborting
-            // and leaving the session locked if this fails.
-            log.warn("failed to change working directory to / on fork: {s}", 
.{@errorName(err)});
-        };
+        switch (system.errno(system.chdir("/"))) {
+            .SUCCESS => {},
+            else => |err| {
+                // While this is a nice thing to do, it is not critical to the 
locking functionality
+                // and it is better to allow potentially unlocking the session 
rather than aborting
+                // and leaving the session locked if this fails.
+                log.warn("failed to change working directory to / on fork: 
{}", .{err});
+            },
+        }
     } else {
         // Terminate the parent process with a clean exit code.
-        posix.exit(0);
+        process.exit(0);
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/Output.zig 
new/waylock-1.6.0/src/Output.zig
--- old/waylock-1.5.0/src/Output.zig    2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/src/Output.zig    2026-04-27 11:40:52.000000000 +0200
@@ -13,8 +13,6 @@
 
 const Lock = @import("Lock.zig");
 
-const gpa = std.heap.c_allocator;
-
 lock: *Lock,
 name: u32,
 wl_output: *wl.Output,
@@ -47,7 +45,7 @@
     if (output.surface) |surface| surface.destroy();
 
     output.link.remove();
-    gpa.destroy(output);
+    output.lock.gpa.destroy(output);
 }
 
 fn lock_surface_listener(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/PasswordBuffer.zig 
new/waylock-1.6.0/src/PasswordBuffer.zig
--- old/waylock-1.5.0/src/PasswordBuffer.zig    2025-09-10 10:24:33.000000000 
+0200
+++ new/waylock-1.6.0/src/PasswordBuffer.zig    2026-04-27 11:40:52.000000000 
+0200
@@ -6,6 +6,7 @@
 const log = std.log;
 const heap = std.heap;
 const posix = std.posix;
+const process = std.process;
 
 const auth = @import("auth.zig");
 
@@ -17,8 +18,7 @@
 pub fn init() PasswordBuffer {
     var password: PasswordBuffer = .{
         .buffer = gpa.alignedAlloc(u8, .fromByteUnits(heap.page_size_max), 
size_max) catch {
-            log.err("failed to allocate password buffer", .{});
-            posix.exit(1);
+            process.fatal("failed to allocate password buffer", .{});
         },
     };
 
@@ -79,13 +79,11 @@
             .SUCCESS => return,
             .AGAIN => continue,
             else => {
-                log.err("mlock() on password buffer failed: E{s}", 
.{@tagName(errno)});
-                posix.exit(1);
+                process.fatal("mlock() on password buffer failed: E{s}", 
.{@tagName(errno)});
             },
         }
     }
-    log.err("mlock() on password buffer failed: EAGAIN after 10 attempts", 
.{});
-    posix.exit(1);
+    process.fatal("mlock() on password buffer failed: EAGAIN after 10 
attempts", .{});
 }
 
 fn prevent_dumping_best_effort(buffer: []align(heap.page_size_max) u8) void {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/Seat.zig 
new/waylock-1.6.0/src/Seat.zig
--- old/waylock-1.5.0/src/Seat.zig      2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/src/Seat.zig      2026-04-27 11:40:52.000000000 +0200
@@ -12,8 +12,6 @@
 
 const Lock = @import("Lock.zig");
 
-const gpa = std.heap.c_allocator;
-
 lock: *Lock,
 name: u32,
 wl_seat: *wl.Seat,
@@ -24,8 +22,8 @@
 link: wl.list.Link,
 
 pub fn create(lock: *Lock, name: u32, wl_seat: *wl.Seat) !void {
-    const seat = try gpa.create(Seat);
-    errdefer gpa.destroy(seat);
+    const seat = try lock.gpa.create(Seat);
+    errdefer lock.gpa.destroy(seat);
 
     seat.* = .{
         .lock = lock,
@@ -45,7 +43,7 @@
     if (seat.xkb_state) |xkb_state| xkb_state.unref();
 
     seat.link.remove();
-    gpa.destroy(seat);
+    seat.lock.gpa.destroy(seat);
 }
 
 fn seat_listener(wl_seat: *wl.Seat, event: wl.Seat.Event, seat: *Seat) void {
@@ -98,14 +96,14 @@
             // only care about press events, not release.
         },
         .keymap => |ev| {
-            defer posix.close(ev.fd);
+            defer _ = posix.system.close(ev.fd);
 
             if (ev.format != .xkb_v1) {
                 log.err("unsupported keymap format {d}", 
.{@intFromEnum(ev.format)});
                 return;
             }
 
-            const keymap_string = posix.mmap(null, ev.size, posix.PROT.READ, 
.{ .TYPE = .PRIVATE }, ev.fd, 0) catch |err| {
+            const keymap_string = posix.mmap(null, ev.size, .{ .READ = true }, 
.{ .TYPE = .PRIVATE }, ev.fd, 0) catch |err| {
                 log.err("failed to mmap() keymap fd: {s}", .{@errorName(err)});
                 return;
             };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/auth.zig 
new/waylock-1.6.0/src/auth.zig
--- old/waylock-1.5.0/src/auth.zig      2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/src/auth.zig      2026-04-27 11:40:52.000000000 +0200
@@ -1,9 +1,12 @@
 const builtin = @import("builtin");
 const std = @import("std");
 const assert = std.debug.assert;
+const Io = std.Io;
 const log = std.log;
 const mem = std.mem;
-const posix = std.posix;
+const process = std.process;
+const fatal = process.fatal;
+const system = std.posix.system;
 
 const c = @cImport({
     @cInclude("unistd.h"); // getuid()
@@ -15,38 +18,53 @@
 const PasswordBuffer = @import("PasswordBuffer.zig");
 
 pub const Connection = struct {
-    read_fd: posix.fd_t,
-    write_fd: posix.fd_t,
+    read_fd: system.fd_t,
+    write_fd: system.fd_t,
 
-    pub fn reader(conn: Connection) std.fs.File.Reader {
-        const file = std.fs.File{ .handle = conn.read_fd };
-        return file.readerStreaming(&.{});
+    pub fn reader(conn: Connection, io: Io) Io.File.Reader {
+        const file = Io.File{ .handle = conn.read_fd, .flags = .{ .nonblocking 
= false } };
+        return file.readerStreaming(io, &.{});
     }
 
-    pub fn writer(conn: Connection) std.fs.File.Writer {
-        const file = std.fs.File{ .handle = conn.write_fd };
-        return file.writerStreaming(&.{});
+    pub fn writer(conn: Connection, io: Io) Io.File.Writer {
+        const file = Io.File{ .handle = conn.write_fd, .flags = .{ 
.nonblocking = false } };
+        return file.writerStreaming(io, &.{});
     }
 };
 
-pub fn fork_child() !Connection {
-    const parent_to_child = try posix.pipe();
-    const child_to_parent = try posix.pipe();
+pub fn fork_child(io: Io) Connection {
+    var parent_to_child: [2]system.fd_t = undefined;
+    var child_to_parent: [2]system.fd_t = undefined;
+    switch (system.errno(system.pipe(&parent_to_child))) {
+        .SUCCESS => {},
+        else => |err| fatal("failed to fork child authentication process: {}", 
.{err}),
+    }
+    switch (system.errno(system.pipe(&child_to_parent))) {
+        .SUCCESS => {},
+        else => |err| fatal("failed to fork child authentication process: {}", 
.{err}),
+    }
+
+    const pid: system.pid_t = fork: {
+        const rc = system.fork();
+        switch (system.errno(rc)) {
+            .SUCCESS => break :fork @intCast(rc),
+            else => |err| fatal("failed to fork child authentication process: 
{}", .{err}),
+        }
+    };
 
-    const pid = try posix.fork();
     if (pid == 0) {
         // We are the child
-        posix.close(parent_to_child[1]);
-        posix.close(child_to_parent[0]);
+        _ = system.close(parent_to_child[1]);
+        _ = system.close(child_to_parent[0]);
 
-        run(.{
+        run(io, .{
             .read_fd = parent_to_child[0],
             .write_fd = child_to_parent[1],
         });
     } else {
         // We are the parent
-        posix.close(parent_to_child[0]);
-        posix.close(child_to_parent[1]);
+        _ = system.close(parent_to_child[0]);
+        _ = system.close(child_to_parent[1]);
 
         return Connection{
             .read_fd = child_to_parent[0],
@@ -57,7 +75,7 @@
 
 var password: PasswordBuffer = undefined;
 
-pub fn run(conn: Connection) noreturn {
+fn run(io: Io, conn: Connection) noreturn {
     password = PasswordBuffer.init();
 
     const conv: pam.Conv = .{
@@ -69,20 +87,20 @@
     {
         const pw = @as(?*c.struct_passwd, c.getpwuid(c.getuid())) orelse {
             log.err("failed to get name of current user", .{});
-            posix.exit(1);
+            process.exit(1);
         };
 
         const result = pam.start("waylock", pw.pw_name, &conv, &pamh);
         if (result != .success) {
             log.err("failed to initialize PAM: {s}", .{result.description()});
-            posix.exit(1);
+            process.exit(1);
         }
     }
 
     while (true) {
-        read_password(conn) catch |err| {
+        read_password(io, conn) catch |err| {
             log.err("failed to read password from pipe: {s}", 
.{@errorName(err)});
-            posix.exit(1);
+            process.exit(1);
         };
 
         const auth_result = pamh.authenticate(0);
@@ -92,10 +110,10 @@
         if (auth_result == .success) {
             log.debug("PAM authentication succeeded", .{});
 
-            var writer = conn.writer();
+            var writer = conn.writer(io);
             writer.interface.writeByte(@intFromBool(true)) catch |err| {
                 log.err("failed to notify parent of success: {s}", 
.{@errorName(err)});
-                posix.exit(1);
+                process.exit(1);
             };
 
             // We don't need to prevent unlocking if this fails. Failure just
@@ -113,14 +131,14 @@
                 log.err("PAM deinitialization failed: {s}", 
.{end_result.description()});
             }
 
-            posix.exit(0);
+            process.exit(0);
         } else {
             log.err("PAM authentication failed: {s}", 
.{auth_result.description()});
 
-            var writer = conn.writer();
+            var writer = conn.writer(io);
             writer.interface.writeByte(@intFromBool(false)) catch |err| {
                 log.err("failed to notify parent of failure: {s}", 
.{@errorName(err)});
-                posix.exit(1);
+                process.exit(1);
             };
 
             if (auth_result == .abort) {
@@ -128,16 +146,16 @@
                 if (end_result != .success) {
                     log.err("PAM deinitialization failed: {s}", 
.{end_result.description()});
                 }
-                posix.exit(1);
+                process.exit(1);
             }
         }
     }
 }
 
-fn read_password(conn: Connection) !void {
+fn read_password(io: Io, conn: Connection) !void {
     assert(password.buffer.len == 0);
 
-    var reader = conn.reader();
+    var reader = conn.reader(io);
     var len_bytes: [4]u8 = undefined;
     try reader.interface.readSliceAll(&len_bytes);
     try password.grow(@as(u32, @bitCast(len_bytes)));
@@ -150,7 +168,7 @@
     resp: *[*]pam.Response,
     _: ?*anyopaque,
 ) callconv(.c) pam.Result {
-    const ally = std.heap.raw_c_allocator;
+    const ally = std.heap.c_allocator;
 
     const responses = ally.alloc(pam.Response, @intCast(num_msg)) catch {
         return .buf_err;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/flags.zig 
new/waylock-1.6.0/src/flags.zig
--- old/waylock-1.5.0/src/flags.zig     2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/src/flags.zig     2026-04-27 11:40:52.000000000 +0200
@@ -1,82 +1,51 @@
-// Zero allocation argument parsing for unix-like systems.
-// Released under the Zero Clause BSD (0BSD) license:
-//
-// Copyright 2023 Isaac Freund
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// SPDX-FileCopyrightText: © 2023 Isaac Freund
+// SPDX-License-Identifier: 0BSD
 
 const std = @import("std");
 const mem = std.mem;
 
 pub const Flag = struct {
-    name: [:0]const u8,
+    name: []const u8,
     kind: enum { boolean, arg },
 };
 
-pub fn parser(comptime Arg: type, comptime flags: []const Flag) type {
-    switch (Arg) {
-        // TODO consider allowing []const u8
-        [:0]const u8, [*:0]const u8 => {}, // ok
-        else => @compileError("invalid argument type: " ++ @typeName(Arg)),
-    }
+pub fn parser(comptime flags: []const Flag) type {
     return struct {
         pub const Result = struct {
             /// Remaining args after the recognized flags
-            args: []const Arg,
+            args: []const [:0]const u8,
             /// Data obtained from parsed flags
             flags: Flags,
 
             pub const Flags = flags_type: {
-                var fields: []const std.builtin.Type.StructField = &.{};
-                for (flags) |flag| {
-                    const field: std.builtin.Type.StructField = switch 
(flag.kind) {
-                        .boolean => .{
-                            .name = flag.name,
-                            .type = bool,
-                            .default_value_ptr = &false,
-                            .is_comptime = false,
-                            .alignment = @alignOf(bool),
+                const Attributes = std.builtin.Type.StructField.Attributes;
+                var names: [flags.len][]const u8 = undefined;
+                var types: [flags.len]type = undefined;
+                var attrs: [flags.len]Attributes = undefined;
+                for (flags, &names, &types, &attrs) |flag, *name, *ty, *attr| {
+                    name.* = flag.name;
+                    switch (flag.kind) {
+                        .boolean => {
+                            ty.* = bool;
+                            attr.* = .{ .default_value_ptr = &false };
                         },
-                        .arg => .{
-                            .name = flag.name,
-                            .type = ?[:0]const u8,
-                            .default_value_ptr = &@as(?[:0]const u8, null),
-                            .is_comptime = false,
-                            .alignment = @alignOf(?[:0]const u8),
+                        .arg => {
+                            ty.* = ?[:0]const u8;
+                            attr.* = .{ .default_value_ptr = &@as(ty.*, null) 
};
                         },
-                    };
-                    fields = fields ++ [_]std.builtin.Type.StructField{field};
+                    }
                 }
-                break :flags_type @Type(.{ .@"struct" = .{
-                    .layout = .auto,
-                    .fields = fields,
-                    .decls = &.{},
-                    .is_tuple = false,
-                } });
+                break :flags_type @Struct(.auto, null, &names, &types, &attrs);
             };
         };
 
-        pub fn parse(args: []const Arg) !Result {
+        pub fn parse(args: []const [:0]const u8) 
error{MissingFlagArgument}!Result {
             var result_flags: Result.Flags = .{};
 
             var i: usize = 0;
             outer: while (i < args.len) : (i += 1) {
-                const arg = switch (Arg) {
-                    [*:0]const u8 => mem.sliceTo(args[i], 0),
-                    [:0]const u8 => args[i],
-                    else => unreachable,
-                };
                 inline for (flags) |flag| {
-                    if (mem.eql(u8, "-" ++ flag.name, arg)) {
+                    if (mem.eql(u8, "-" ++ flag.name, args[i])) {
                         switch (flag.kind) {
                             .boolean => @field(result_flags, flag.name) = true,
                             .arg => {
@@ -86,11 +55,7 @@
                                         "' requires an argument but none was 
provided!", .{});
                                     return error.MissingFlagArgument;
                                 }
-                                @field(result_flags, flag.name) = switch (Arg) 
{
-                                    [*:0]const u8 => mem.sliceTo(args[i], 0),
-                                    [:0]const u8 => args[i],
-                                    else => unreachable,
-                                };
+                                @field(result_flags, flag.name) = args[i];
                             },
                         }
                         continue :outer;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/waylock-1.5.0/src/main.zig 
new/waylock-1.6.0/src/main.zig
--- old/waylock-1.5.0/src/main.zig      2025-09-10 10:24:33.000000000 +0200
+++ new/waylock-1.6.0/src/main.zig      2026-04-27 11:40:52.000000000 +0200
@@ -1,9 +1,9 @@
 const std = @import("std");
 const assert = std.debug.assert;
-const fs = std.fs;
-const io = std.io;
+const Io = std.Io;
 const mem = std.mem;
 const posix = std.posix;
+const process = std.process;
 const log = std.log;
 
 const build_options = @import("build_options");
@@ -30,8 +30,20 @@
     \\
 ;
 
-pub fn main() void {
-    const result = flags.parser([*:0]const u8, &.{
+pub fn main(init: process.Init) error{ OutOfMemory, Unexpected }!void {
+    const io = init.io;
+    const arena = init.arena.allocator();
+
+    var stdout_buffer: [512]u8 = undefined;
+    var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer);
+    const stdout = &stdout_writer.interface;
+
+    var stderr_buffer: [512]u8 = undefined;
+    var stderr_writer = Io.File.stderr().writer(io, &stderr_buffer);
+    const stderr = &stderr_writer.interface;
+
+    const args = try init.minimal.args.toSlice(arena);
+    const result = flags.parser(&.{
         .{ .name = "h", .kind = .boolean },
         .{ .name = "version", .kind = .boolean },
         .{ .name = "log-level", .kind = .arg },
@@ -42,23 +54,23 @@
         .{ .name = "input-color", .kind = .arg },
         .{ .name = "input-alt-color", .kind = .arg },
         .{ .name = "fail-color", .kind = .arg },
-    }).parse(std.os.argv[1..]) catch {
-        fs.File.stderr().writeAll(usage) catch {};
-        posix.exit(1);
+    }).parse(args[1..]) catch {
+        stderr.writeAll(usage) catch {};
+        process.exit(1);
     };
     if (result.flags.h) {
-        fs.File.stdout().writeAll(usage) catch posix.exit(1);
-        posix.exit(0);
+        stdout.writeAll(usage) catch process.exit(1);
+        process.exit(0);
     }
     if (result.args.len != 0) {
         log.err("unknown option '{s}'", .{result.args[0]});
-        fs.File.stderr().writeAll(usage) catch {};
-        posix.exit(1);
+        stderr.writeAll(usage) catch {};
+        process.exit(1);
     }
 
     if (result.flags.version) {
-        fs.File.stdout().writeAll(build_options.version ++ "\n") catch 
posix.exit(1);
-        posix.exit(0);
+        stdout.writeAll(build_options.version ++ "\n") catch process.exit(1);
+        process.exit(0);
     }
     if (result.flags.@"log-level") |level| {
         if (mem.eql(u8, level, "error")) {
@@ -71,7 +83,7 @@
             runtime_log_level = .debug;
         } else {
             log.err("invalid log level '{s}'", .{level});
-            posix.exit(1);
+            process.exit(1);
         }
     }
 
@@ -82,7 +94,7 @@
     if (result.flags.@"ready-fd") |raw| {
         options.ready_fd = std.fmt.parseInt(posix.fd_t, raw, 10) catch {
             log.err("invalid file descriptor '{s}'", .{raw});
-            posix.exit(1);
+            process.exit(1);
         };
     }
     if (result.flags.@"init-color") |raw| options.init_color = 
parse_color(raw);
@@ -93,7 +105,7 @@
     if (result.flags.@"input-alt-color") |raw| options.input_alt_color = 
parse_color(raw);
     if (result.flags.@"fail-color") |raw| options.fail_color = 
parse_color(raw);
 
-    Lock.run(options);
+    Lock.run(io, init.gpa, options);
 }
 
 fn parse_color(raw: []const u8) u24 {
@@ -105,7 +117,7 @@
 
 fn fatal_bad_color(raw: []const u8) noreturn {
     log.err("invalid color '{s}', expected format '0xRRGGBB'", .{raw});
-    posix.exit(1);
+    process.exit(1);
 }
 
 /// Set the default log level based on the build mode.
@@ -126,14 +138,7 @@
     comptime format: []const u8,
     args: anytype,
 ) void {
-    // waylock is small enough that we don't need scopes
-    comptime assert(scope == .default);
-
     if (@intFromEnum(level) > @intFromEnum(runtime_log_level)) return;
 
-    var buffer: [256]u8 = undefined;
-    const stderr = std.debug.lockStderrWriter(&buffer);
-    defer std.debug.unlockStderrWriter();
-
-    stderr.print(level.asText() ++ ": " ++ format ++ "\n", args) catch {};
+    log.defaultLog(level, scope, format, args);
 }

Reply via email to