command/spawn: clean up and disown children
- Call setsid - Clean up the signal mask. - Use a double fork so that processes get inherited by init.
This commit is contained in:
parent
d77ac5ac7a
commit
cbf645d468
@ -19,9 +19,12 @@ pub usingnamespace @cImport({
|
||||
@cDefine("_POSIX_C_SOURCE", "200809L");
|
||||
@cDefine("WLR_USE_UNSTABLE", {});
|
||||
|
||||
@cInclude("time.h");
|
||||
@cInclude("stdlib.h");
|
||||
@cInclude("time.h");
|
||||
@cInclude("unistd.h");
|
||||
|
||||
@cInclude("linux/input-event-codes.h");
|
||||
|
||||
@cInclude("wayland-server-core.h");
|
||||
//@cInclude("wlr/backend.h");
|
||||
//@cInclude("wlr/render/wlr_renderer.h");
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
@ -31,17 +33,31 @@ pub fn spawn(
|
||||
|
||||
const cmd = try std.mem.join(allocator, " ", args[1..]);
|
||||
defer allocator.free(cmd);
|
||||
const cmdZ = try std.cstr.addNullByte(allocator, cmd);
|
||||
defer allocator.free(cmdZ);
|
||||
|
||||
const child_args = [_][]const u8{ "/bin/sh", "-c", cmd };
|
||||
const child = try std.ChildProcess.init(&child_args, allocator);
|
||||
defer child.deinit();
|
||||
const child_args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmdZ, null };
|
||||
|
||||
std.ChildProcess.spawn(child) catch |err| {
|
||||
out.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"failed to spawn {}: {}.",
|
||||
.{ cmd, err },
|
||||
);
|
||||
const pid = std.os.fork() catch {
|
||||
out.* = try std.fmt.allocPrint(allocator, "fork/execve failed", .{});
|
||||
return Error.Other;
|
||||
};
|
||||
|
||||
if (pid == 0) {
|
||||
// Clean things up for the child in an intermediate fork
|
||||
if (c.setsid() < 0) unreachable;
|
||||
if (std.os.system.sigprocmask(std.os.SIG_SETMASK, &std.os.empty_sigset, null) < 0) unreachable;
|
||||
|
||||
const pid2 = std.os.fork() catch std.os.exit(1);
|
||||
if (pid2 == 0) std.os.execveZ("/bin/sh", &child_args, std.c.environ) catch std.os.exit(1);
|
||||
|
||||
std.os.exit(0);
|
||||
}
|
||||
|
||||
// Wait the intermediate child.
|
||||
const status = std.os.waitpid(pid, 0);
|
||||
if (std.os.WIFEXITED(status) and std.os.WEXITSTATUS(status) != 0) {
|
||||
out.* = try std.fmt.allocPrint(allocator, "fork/execve failed", .{});
|
||||
return Error.Other;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user