aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/command/spawn.zig5
-rw-r--r--river/main.zig24
-rw-r--r--river/util.zig17
3 files changed, 28 insertions, 18 deletions
diff --git a/river/command/spawn.zig b/river/command/spawn.zig
index 1bc5c42..ced3922 100644
--- a/river/command/spawn.zig
+++ b/river/command/spawn.zig
@@ -40,10 +40,7 @@ pub fn spawn(
};
if (pid == 0) {
- // Clean things up for the child in an intermediate fork
- if (c.setsid() < 0) unreachable;
- if (os.system.sigprocmask(os.SIG.SETMASK, &os.empty_sigset, null) < 0) unreachable;
-
+ util.post_fork_pre_execve();
const pid2 = os.fork() catch c._exit(1);
if (pid2 == 0) os.execveZ("/bin/sh", &child_args, std.c.environ) catch c._exit(1);
diff --git a/river/main.zig b/river/main.zig
index 53a17e5..d9fc443 100644
--- a/river/main.zig
+++ b/river/main.zig
@@ -41,18 +41,7 @@ const usage: []const u8 =
pub var server: Server = undefined;
-fn sa_handler(_: c_int) callconv(.C) void {}
-
pub fn main() anyerror!void {
- // ignore SIGPIPE so we don't get killed when socket unexpectedly closes (thanks xwayland)
- // use our own handler instead of SIG_IGN so we don't leak this when execve()
- const act = os.Sigaction{
- .handler = .{ .handler = sa_handler },
- .mask = os.empty_sigset,
- .flags = 0,
- };
- os.sigaction(os.SIG.PIPE, &act, null);
-
// This line is here because of https://github.com/ziglang/zig/issues/7807
const argv: [][*:0]const u8 = os.argv;
const result = flags.parse(argv[1..], &[_]flags.Flag{
@@ -107,6 +96,16 @@ pub fn main() anyerror!void {
.warn, .err => .err,
});
+ // Ignore SIGPIPE so we don't get killed when writing to a socket that
+ // has had its read end closed by another process.
+ const sig_ign = os.Sigaction{
+ // TODO(zig): Remove this casting after https://github.com/ziglang/zig/pull/12410
+ .handler = .{ .handler = @intToPtr(os.Sigaction.handler_fn, @ptrToInt(os.SIG.IGN)) },
+ .mask = os.empty_sigset,
+ .flags = 0,
+ };
+ os.sigaction(os.SIG.PIPE, &sig_ign, null);
+
std.log.info("initializing server", .{});
try server.init();
defer server.deinit();
@@ -120,8 +119,7 @@ pub fn main() anyerror!void {
const child_args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmd, null };
const pid = try os.fork();
if (pid == 0) {
- if (c.setsid() < 0) unreachable;
- if (os.system.sigprocmask(os.SIG.SETMASK, &os.empty_sigset, null) < 0) unreachable;
+ util.post_fork_pre_execve();
os.execveZ("/bin/sh", &child_args, std.c.environ) catch c._exit(1);
}
util.gpa.free(cmd);
diff --git a/river/util.zig b/river/util.zig
index 2cd8874..13976df 100644
--- a/river/util.zig
+++ b/river/util.zig
@@ -1,6 +1,6 @@
// This file is part of river, a dynamic tiling wayland compositor.
//
-// Copyright 2020 The River Developers
+// Copyright 2022 The River Developers
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -15,6 +15,21 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
const std = @import("std");
+const os = std.os;
+
+const c = @import("c.zig");
/// The global general-purpose allocator used throughout river's code
pub const gpa = std.heap.c_allocator;
+
+pub fn post_fork_pre_execve() void {
+ if (c.setsid() < 0) unreachable;
+ if (os.system.sigprocmask(os.SIG.SETMASK, &os.empty_sigset, null) < 0) unreachable;
+ const sig_dfl = os.Sigaction{
+ // TODO(zig): Remove this casting after https://github.com/ziglang/zig/pull/12410
+ .handler = .{ .handler = @intToPtr(?os.Sigaction.handler_fn, @ptrToInt(os.SIG.DFL)) },
+ .mask = os.empty_sigset,
+ .flags = 0,
+ };
+ os.sigaction(os.SIG.PIPE, &sig_dfl, null);
+}