-
Notifications
You must be signed in to change notification settings - Fork 631
/
Copy pathopen.zig
79 lines (67 loc) · 2.16 KB
/
open.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
const std = @import("std");
const builtin = @import("builtin");
const Allocator = std.mem.Allocator;
/// The type of the data at the URL to open. This is used as a hint
/// to potentially open the URL in a different way.
pub const Type = enum {
text,
unknown,
};
/// Open a URL in the default handling application.
///
/// Any output on stderr is logged as a warning in the application logs.
/// Output on stdout is ignored.
pub fn open(
alloc: Allocator,
typ: Type,
url: []const u8,
) !void {
const cmd: OpenCommand = switch (builtin.os.tag) {
.linux => .{ .child = std.process.Child.init(
&.{ "xdg-open", url },
alloc,
) },
.windows => .{ .child = std.process.Child.init(
&.{ "rundll32", "url.dll,FileProtocolHandler", url },
alloc,
) },
.macos => .{
.child = std.process.Child.init(
switch (typ) {
.text => &.{ "open", "-t", url },
.unknown => &.{ "open", url },
},
alloc,
),
.wait = true,
},
.ios => return error.Unimplemented,
else => @compileError("unsupported OS"),
};
var exe = cmd.child;
if (cmd.wait) {
// Pipe stdout/stderr so we can collect output from the command
exe.stdout_behavior = .Pipe;
exe.stderr_behavior = .Pipe;
}
try exe.spawn();
if (cmd.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 {
stdout.deinit();
stderr.deinit();
}
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});
}
}
const OpenCommand = struct {
child: std.process.Child,
wait: bool = false,
};