mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 08:16:13 +03:00
os/open: do not wait for commands which do not terminate
Some opener commands (like macOS's open) finish immediately after running, while others (xdg-open) do not, staying alive until the application that was opened itself terminates. For now, we explicitly state whether or not we should wait for a command. Eventually we may want to do something more generic (e.g. wait for some predetermined amount of time and if the process does not complete, give up without collecting stderr).
This commit is contained in:
@ -7,19 +7,31 @@ const Allocator = std.mem.Allocator;
|
||||
/// Any output on stderr is logged as a warning in the application logs.
|
||||
/// Output on stdout is ignored.
|
||||
pub fn open(alloc: Allocator, url: []const u8) !void {
|
||||
const argv = switch (builtin.os.tag) {
|
||||
.linux => &.{ "xdg-open", url },
|
||||
.macos => &.{ "open", url },
|
||||
.windows => &.{ "rundll32", "url.dll,FileProtocolHandler", url },
|
||||
// Some opener commands terminate after opening (macOS open) and some do not
|
||||
// (xdg-open). For those which do not terminate, we do not want to wait for
|
||||
// the process to exit to collect stderr.
|
||||
const argv, const wait = switch (builtin.os.tag) {
|
||||
.linux => .{ &.{ "xdg-open", url }, false },
|
||||
.macos => .{ &.{ "open", url }, true },
|
||||
.windows => .{ &.{ "rundll32", "url.dll,FileProtocolHandler", url }, false },
|
||||
.ios => return error.Unimplemented,
|
||||
else => @compileError("unsupported OS"),
|
||||
};
|
||||
|
||||
var exe = std.process.Child.init(argv, alloc);
|
||||
|
||||
if (comptime wait) {
|
||||
// Pipe stdout/stderr so we can collect output from the command
|
||||
exe.stdout_behavior = .Pipe;
|
||||
exe.stderr_behavior = .Pipe;
|
||||
}
|
||||
|
||||
try exe.spawn();
|
||||
|
||||
if (comptime wait) {
|
||||
// 50 KiB is the default value used by std.process.Child.run
|
||||
const output_max_size = 50 * 1024;
|
||||
|
||||
var stdout = std.ArrayList(u8).init(alloc);
|
||||
var stderr = std.ArrayList(u8).init(alloc);
|
||||
defer {
|
||||
@ -27,14 +39,11 @@ pub fn open(alloc: Allocator, url: []const u8) !void {
|
||||
stderr.deinit();
|
||||
}
|
||||
|
||||
// 50 KiB is the default value used by std.process.Child.run
|
||||
const output_max_size = 50 * 1024;
|
||||
|
||||
try exe.spawn();
|
||||
try exe.collectOutput(&stdout, &stderr, output_max_size);
|
||||
_ = try exe.wait();
|
||||
|
||||
// If we have any stderr output we log it. This makes it easier for
|
||||
// users to debug why some open commands may not work as expected.
|
||||
if (stderr.items.len > 0) std.log.err("open stderr={s}", .{stderr.items});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user