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("_POSIX_C_SOURCE", "200809L");
|
||||||
@cDefine("WLR_USE_UNSTABLE", {});
|
@cDefine("WLR_USE_UNSTABLE", {});
|
||||||
|
|
||||||
@cInclude("time.h");
|
|
||||||
@cInclude("stdlib.h");
|
@cInclude("stdlib.h");
|
||||||
|
@cInclude("time.h");
|
||||||
|
@cInclude("unistd.h");
|
||||||
|
|
||||||
@cInclude("linux/input-event-codes.h");
|
@cInclude("linux/input-event-codes.h");
|
||||||
|
|
||||||
@cInclude("wayland-server-core.h");
|
@cInclude("wayland-server-core.h");
|
||||||
//@cInclude("wlr/backend.h");
|
//@cInclude("wlr/backend.h");
|
||||||
//@cInclude("wlr/render/wlr_renderer.h");
|
//@cInclude("wlr/render/wlr_renderer.h");
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const c = @import("../c.zig");
|
||||||
|
|
||||||
const Error = @import("../command.zig").Error;
|
const Error = @import("../command.zig").Error;
|
||||||
const Seat = @import("../Seat.zig");
|
const Seat = @import("../Seat.zig");
|
||||||
|
|
||||||
@ -31,17 +33,31 @@ pub fn spawn(
|
|||||||
|
|
||||||
const cmd = try std.mem.join(allocator, " ", args[1..]);
|
const cmd = try std.mem.join(allocator, " ", args[1..]);
|
||||||
defer allocator.free(cmd);
|
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_args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmdZ, null };
|
||||||
const child = try std.ChildProcess.init(&child_args, allocator);
|
|
||||||
defer child.deinit();
|
|
||||||
|
|
||||||
std.ChildProcess.spawn(child) catch |err| {
|
const pid = std.os.fork() catch {
|
||||||
out.* = try std.fmt.allocPrint(
|
out.* = try std.fmt.allocPrint(allocator, "fork/execve failed", .{});
|
||||||
allocator,
|
|
||||||
"failed to spawn {}: {}.",
|
|
||||||
.{ cmd, err },
|
|
||||||
);
|
|
||||||
return Error.Other;
|
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