make mzteinit more robust

This commit is contained in:
LordMZTE 2023-05-21 00:58:42 +02:00
parent d1f3b46fbc
commit cae0abe877
Signed by: LordMZTE
GPG key ID: B64802DC33A64FF6
3 changed files with 131 additions and 6 deletions

View file

@ -1,14 +1,20 @@
const std = @import("std");
const sysdaemon = @import("sysdaemon.zig");
const log = std.log.scoped(.env);
const DelimitedBuilder = @import("DelimitedBuilder.zig");
pub fn populateEnvironment(env: *std.process.EnvMap) !void {
/// Initialize the environment.
/// Returns true if the environment should be transferred to the system daemon.
pub fn populateEnvironment(env: *std.process.EnvMap) !bool {
if (env.get("MZTE_ENV_SET")) |_| {
return;
return false;
}
const alloc = env.hash_map.allocator;
const home = if (env.get("HOME")) |home| try alloc.dupe(u8, home) else blk: {
std.log.warn("Home not set, defaulting to current directory", .{});
log.warn("Home not set, defaulting to current directory", .{});
break :blk try std.fs.realpathAlloc(alloc, ".");
};
defer alloc.free(home);
@ -62,6 +68,8 @@ pub fn populateEnvironment(env: *std.process.EnvMap) !void {
defer alloc.free(res.stderr);
try b.push(res.stdout);
log.info("racket binary path registered", .{});
}
if (env.get("PATH")) |system_path| {
@ -89,4 +97,37 @@ pub fn populateEnvironment(env: *std.process.EnvMap) !void {
try env.putMove(try alloc.dupe(u8, "LUA_CPATH"), try b.toOwned());
}
return true;
}
pub fn populateSysdaemonEnvironment(env: *const std.process.EnvMap) !void {
if (try sysdaemon.getCurrentSystemDaemon() != .systemd)
return;
var argv = try std.ArrayList([]const u8).initCapacity(env.hash_map.allocator, env.count() + 3);
defer argv.deinit();
var arg_arena = std.heap.ArenaAllocator.init(env.hash_map.allocator);
defer arg_arena.deinit();
try argv.appendSlice(&.{ "systemctl", "--user", "set-environment" });
var env_iter = env.iterator();
while (env_iter.next()) |entry| {
try argv.append(try std.fmt.allocPrint(
arg_arena.allocator(),
"{s}={s}",
.{ entry.key_ptr.*, entry.value_ptr.* },
));
}
log.debug("sysdaemon env cmd: {s}", .{argv.items});
var child = std.ChildProcess.init(argv.items, env.hash_map.allocator);
const term = try child.spawnAndWait();
if (!std.meta.eql(term, .{ .Exited = 0 })) {
log.warn("Failed setting system environment, process exited with {}", .{term});
}
}

View file

@ -4,7 +4,50 @@ const env = @import("env.zig");
const run = @import("run.zig");
const util = @import("util.zig");
pub fn main() !void {
pub const std_options = struct {
pub const log_level = .debug;
pub fn logFn(
comptime msg_level: std.log.Level,
comptime scope: @TypeOf(.enum_literal),
comptime fmt: []const u8,
args: anytype,
) void {
const logfile = log_file orelse return;
if (scope != .default) {
logfile.writer().print("[{s}] ", .{@tagName(scope)}) catch return;
}
logfile.writer().writeAll(switch (msg_level) {
.err => "E: ",
.warn => "W: ",
.info => "I: ",
.debug => "D: ",
}) catch return;
logfile.writer().print(fmt ++ "\n", args) catch return;
}
};
var log_file: ?std.fs.File = null;
pub fn main() void {
log_file = createLogFile() catch null;
defer if (log_file) |lf| lf.close();
tryMain() catch |e| {
std.log.err("FATAL ERROR: {}", .{e});
std.debug.print("Encountered fatal error (check log), starting emergency shell!\n", .{});
@panic(@errorName(std.os.execveZ(
"/bin/sh",
&[_:null]?[*:0]const u8{"/bin/sh"},
&[_:null]?[*:0]const u8{},
)));
};
}
fn tryMain() !void {
var stdout = std.io.bufferedWriter(std.io.getStdOut().writer());
var exit = false;
@ -28,7 +71,7 @@ pub fn main() !void {
}
const key = env_var[0..eq_idx];
const value = env_var[eq_idx + 1..idx];
const value = env_var[eq_idx + 1 .. idx];
try env_map.put(key, value);
}
@ -43,7 +86,9 @@ pub fn main() !void {
try env_map.put("MZTEINIT", "1");
}
try env.populateEnvironment(&env_map);
if (try env.populateEnvironment(&env_map)) {
try env.populateSysdaemonEnvironment(&env_map);
}
while (true) {
try util.writeAnsiClear(stdout.writer());
@ -121,6 +166,16 @@ fn ui(buf_writer: anytype) !run.Command {
return cmd.?;
}
fn createLogFile() !std.fs.File {
var fname_buf: [128]u8 = undefined;
const fname = try std.fmt.bufPrintZ(
&fname_buf,
"/tmp/mzteinit-{}-{}.log",
.{ std.os.linux.getuid(), std.os.linux.getpid() },
);
return try std.fs.createFileAbsoluteZ(fname, .{});
}
fn updateStyle(
writer: anytype,
new_style: at.style.Style,

View file

@ -0,0 +1,29 @@
//! Utilities regarding the system daemon (systemd)
const std = @import("std");
pub const SystemDaemon = enum {
none,
systemd,
};
pub fn getCurrentSystemDaemon() !SystemDaemon {
const cache = struct {
var daemon: ?SystemDaemon = null;
};
if (cache.daemon) |d|
return d;
const systemd_stat: ?std.fs.File.Stat = std.fs.cwd().statFile("/etc/systemd") catch |e| blk: {
if (e == error.FileNotFound) {
break :blk null;
}
return e;
};
const daemon: SystemDaemon = if (systemd_stat) |_| .systemd else .none;
cache.daemon = daemon;
return daemon;
}