summaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/main.zig b/src/main.zig
index 08beae86..b8cb6b2d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -93,15 +93,30 @@ const help_text =
\\ a frontend can say which session it wants. One
\\ path component: no '/' and nothing empty
\\ --attach become a frontend of the one detached session
- \\ that is running: draw its screen, send it input,
- \\ fork its pane shells. Several frontends may be
- \\ attached at once and all see the same screen
+ \\ that is running: draw its screen and send it
+ \\ input, and nothing else — the session owns its
+ \\ pane shells, its files and its watches. Works in
+ \\ both the terminal and the SDL window build.
+ \\ Several frontends may be attached at once and all
+ \\ see the same screen
\\ --attach=<name> ...of the session called <name>, which is what to
\\ use when more than one is running
\\ -h, --help show this help and exit
+ \\ --version print the version and exit
\\
;
+/// Built at COMPTIME, because both halves are: `version` comes out of
+/// `build.zig.zon` through the options module and `commit` out of `git` at
+/// configure time, so there is nothing here to format at runtime and no buffer
+/// to size. The commit is in parentheses when there is one and absent
+/// otherwise — a build from a tarball says `pardes 0.0.1` and is not lying
+/// about a revision it never had. See `pardes.version`/`pardes.commit`.
+const version_text = if (pardes.commit) |c|
+ "pardes " ++ pardes.version ++ " (" ++ c ++ ")\n"
+else
+ "pardes " ++ pardes.version ++ "\n";
+
const nested_text =
\\pardes: this shell is already inside pardes, and a pardes inside a pardes
\\is spicy. Name a file or a directory and the outer session opens it, or
@@ -129,9 +144,10 @@ fn emscriptenMain(argc: c_int, argv: [*]?[*:0]u8) callconv(.c) c_int {
return 0;
}
-// no argv in the browser: options stay default, state comes from the dump
+// no argv in the browser: options stay default, state comes from the dump, and
+// there is no session to attach to — a browser tab has no unix socket.
fn webMain() !void {
- try @import("gui/gui.zig").run(.{});
+ try @import("gui/gui.zig").run(.{}, .{}, null);
}
fn nativeMain(init: std.process.Init) !void {
@@ -159,8 +175,8 @@ fn nativeMain(init: std.process.Init) !void {
// free to mean "the default name" the way opts.fs uses it for a directory.
var detach: ?[]const u8 = null;
// ...and `--attach[=<name>]`, the same shape: null when it was not given,
- // and the empty string means "the one session there is" (tty.zig
- // `sessionName`) rather than a session with no name.
+ // and the empty string means "the one session there is"
+ // (detached_client.resolve) rather than a session with no name.
var attach: ?[]const u8 = null;
// Kept RAW until every flag is parsed: classifying it means chdir'ing into
// a directory and recording nothing, and the nested client below still
@@ -216,6 +232,9 @@ fn nativeMain(init: std.process.Init) !void {
} else if (std.mem.eql(u8, a, "-h") or std.mem.eql(u8, a, "--help")) {
try std.Io.File.stdout().writeStreamingAll(init.io, help_text);
return;
+ } else if (std.mem.eql(u8, a, "--version")) {
+ try std.Io.File.stdout().writeStreamingAll(init.io, version_text);
+ return;
} else if (a.len > 0 and a[0] != '-' and positional == null) {
positional = a;
} else {
@@ -285,6 +304,19 @@ fn nativeMain(init: std.process.Init) !void {
// reading. Refused rather than resolved by declaration order, which would
// silently drop whichever flag lost.
if (detach != null and attach != null) return error.BadArgs;
+ // `--fs` mounts the acme control filesystem, and only a LOCAL session has
+ // one: `fs_service.start` is called inside tty.zig's `localSession` and
+ // gui.zig's equivalent, both of which an `--attach` skips entirely, and
+ // `detached/server.zig` never reads `opts.fs` at all. So `--fs` with either
+ // of these was parsed, stored, and then served by nobody.
+ //
+ // Refused for the same reason as the line above, and it is the stronger
+ // case: a contradiction is at least visible, whereas a silently dropped
+ // mount is invisible until someone waits for a directory that will never
+ // appear. Serving it instead would mean mounting FUSE in the detached core,
+ // which is a feature rather than a fix — `push_fs_reply` is one of the five
+ // host methods that core deliberately leaves null (docs/detached.md).
+ if (opts.fs != null and (detach != null or attach != null)) return error.BadArgs;
// `--detach` replaces the frontend rather than choosing among them: the
// core runs here, with no terminal, and the frontends are elsewhere on a
// socket (src/detached/). It is checked before `platform` because it is not
@@ -300,15 +332,18 @@ fn nativeMain(init: std.process.Init) !void {
try std.fmt.allocPrint(arena, "{d}", .{@as(u32, @intCast(std.c.getpid()))});
return @import("detached/server.zig").run(init, opts, named);
}
- // A frontend is a SHELL, and only the tty one knows how to be one today.
- // Comptime-folded, so a tty build carries none of this.
- if (attach != null and pardes.platform != .tty) {
- try std.Io.File.stderr().writeStreamingAll(init.io, "pardes: --attach needs the tty shell\n");
+ // A frontend is a SHELL, and the two native ones — a terminal and an SDL
+ // window — both know how to be one. The browser has no unix socket to
+ // reach a session over and the AppKit shell is entered by its own host
+ // rather than through this file, so neither is wired for it; the check is
+ // comptime-folded, so a tty or gui build carries none of it.
+ if (attach != null and pardes.platform != .tty and pardes.platform != .gui) {
+ try std.Io.File.stderr().writeStreamingAll(init.io, "pardes: --attach needs the tty or gui shell\n");
std.process.exit(1);
}
switch (pardes.platform) {
.tty => try @import("tty/tty.zig").run(init, opts, attach),
- .gui => try @import("gui/gui.zig").run(init, opts),
+ .gui => try @import("gui/gui.zig").run(init, opts, attach),
// Every other shell is entered by its host and never links this file
// at all: the browser through src/web.zig, the macOS app through
// src/macos.zig, and the ESP32-P4 firmware through src/esp32p4/app.zig,