mirror of
https://mzte.de/git/LordMZTE/dotfiles.git
synced 2024-09-27 20:48:53 +02:00
68 lines
2 KiB
Zig
68 lines
2 KiB
Zig
|
const std = @import("std");
|
||
|
|
||
|
running: bool,
|
||
|
exepath: ?[]const u8,
|
||
|
|
||
|
const Self = @This();
|
||
|
|
||
|
/// Frees the data of this ProcessInfo.
|
||
|
/// `alloc` must be the same allocator that was supplied to `get`!
|
||
|
pub fn deinit(self: *Self, alloc: std.mem.Allocator) void {
|
||
|
if (self.exepath) |exepath|
|
||
|
alloc.free(exepath);
|
||
|
self.* = undefined;
|
||
|
}
|
||
|
|
||
|
/// Gets information about a process given it's name
|
||
|
pub fn get(
|
||
|
name: []const u8,
|
||
|
alloc: std.mem.Allocator,
|
||
|
) !Self {
|
||
|
var proc_dir = try std.fs.openIterableDirAbsolute("/proc", .{});
|
||
|
defer proc_dir.close();
|
||
|
|
||
|
var proc_iter = proc_dir.iterate();
|
||
|
procs: while (try proc_iter.next()) |proc| {
|
||
|
// Filter directories that aren't PIDs
|
||
|
for (std.fs.path.basename(proc.name)) |letter|
|
||
|
if (!std.ascii.isDigit(letter))
|
||
|
continue :procs;
|
||
|
|
||
|
var buf: [512]u8 = undefined;
|
||
|
const cmdline_f = std.fs.openFileAbsolute(
|
||
|
try std.fmt.bufPrint(&buf, "/proc/{s}/cmdline", .{proc.name}),
|
||
|
.{},
|
||
|
) catch |e| {
|
||
|
// This just happens when we're dealing with another user's process.
|
||
|
if (e == error.AccessDenied)
|
||
|
continue;
|
||
|
|
||
|
return e;
|
||
|
};
|
||
|
|
||
|
defer cmdline_f.close();
|
||
|
|
||
|
const cmdline_data = try cmdline_f.readToEndAlloc(alloc, std.math.maxInt(usize));
|
||
|
defer alloc.free(cmdline_data);
|
||
|
|
||
|
var cmdline_splits = std.mem.split(u8, cmdline_data, &.{0});
|
||
|
const exepath = cmdline_splits.next() orelse return error.InvalidCmdline;
|
||
|
|
||
|
// this is a startsWith instead of an eql because the arguments in the
|
||
|
// cmdline file are sometimes (and only sometimes!) separated by spaces
|
||
|
// and not null bytes.
|
||
|
if (!std.mem.startsWith(u8, std.fs.path.basename(exepath), name))
|
||
|
continue;
|
||
|
|
||
|
return .{
|
||
|
.running = true,
|
||
|
.exepath = try alloc.dupe(u8, exepath),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return .{
|
||
|
.running = false,
|
||
|
.exepath = null,
|
||
|
};
|
||
|
}
|