git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit5a2956b8f58e4962582ef0b3ce89f9fceeeac419
parent841fd4e81b
authorLeon Henrik Plickat <[email protected]>
date2020-11-17 03:40
Add default config location

 river/main.zig | 44 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/river/main.zig b/river/main.zig
index 4a86814..2018690 100644
--- a/river/main.zig
+++ b/river/main.zig
@@ -32,8 +32,33 @@ const usage: []const u8 =
     \\
 ;
 
+fn testConfigPath(comptime fmt: []const u8, args: anytype) std.fmt.AllocPrintError!?[:0]const u8 {
+    const path = try std.fmt.allocPrintZ(util.gpa, fmt, args);
+    std.os.access(path, std.os.X_OK) catch {
+        util.gpa.free(path);
+        return null;
+    };
+    return path;
+}
+
+fn getStartupCommand() std.fmt.AllocPrintError!?[:0]const u8 {
+    if (std.os.getenv("XDG_CONFIG_HOME")) |xdg_config_home| {
+        if (try testConfigPath("{}/river/init", .{xdg_config_home})) |path| {
+            return path;
+        }
+    } else if (std.os.getenv("HOME")) |home| {
+        if (try testConfigPath("{}/.config/river/init", .{home})) |path| {
+            return path;
+        }
+    }
+    if (try testConfigPath("/etc/river/init", .{})) |path| {
+        return path;
+    }
+    return null;
+}
+
 pub fn main() anyerror!void {
-    var startup_command: ?[*:0]const u8 = null;
+    var startup_command: ?[:0]const u8 = null;
     {
         var it = std.process.args();
         // Skip our name
@@ -45,7 +70,10 @@ pub fn main() anyerror!void {
                 std.os.exit(0);
             } else if (std.mem.eql(u8, arg, "-c")) {
                 if (it.nextPosix()) |command| {
-                    startup_command = @ptrCast([*:0]const u8, command.ptr);
+                    // If the user used '-c' multiple times the variable
+                    // already holds a path and needs to be freed.
+                    if (startup_command) |ptr| util.gpa.free(ptr);
+                    startup_command = try util.gpa.dupeZ(u8, std.mem.spanZ(command.ptr));
                 } else {
                     printErrorExit("Error: flag '-c' requires exactly one argument", .{});
                 }
@@ -69,6 +97,17 @@ pub fn main() anyerror!void {
 
     log.info(.server, "initializing", .{});
 
+    if (startup_command == null) {
+        if (try getStartupCommand()) |path| {
+            startup_command = path;
+            log.info(.server, "Using default startup command path: {}", .{path});
+        } else {
+            log.info(.server, "Starting without startup command", .{});
+        }
+    } else {
+        log.info(.server, "Using custom startup command path: {}", .{startup_command});
+    }
+
     var server: Server = undefined;
     try server.init();
     defer server.deinit();
@@ -82,6 +121,7 @@ pub fn main() anyerror!void {
             if (std.os.system.sigprocmask(std.os.SIG_SETMASK, &std.os.empty_sigset, null) < 0) unreachable;
             std.os.execveZ("/bin/sh", &child_args, std.c.environ) catch c._exit(1);
         }
+        util.gpa.free(cmd);
         break :blk pid;
     } else null;
     defer if (child_pid) |pid|