process.zig (1571B)
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 4 pub const ProcessInfo = struct { 5 name: []const u8, 6 ppid: std.c.pid_t, 7 }; 8 9 pub fn getProcessInfo(io: std.Io, allocator: std.mem.Allocator, pid: std.c.pid_t) !ProcessInfo { 10 if (builtin.os.tag != .linux and builtin.os.tag != .openbsd) return error.UnsupportedOs; 11 12 var path_buf: [std.Io.Dir.max_path_bytes]u8 = undefined; 13 const path = try std.fmt.bufPrint(&path_buf, "/proc/{d}/stat", .{pid}); 14 15 const file = try std.Io.Dir.openFileAbsolute(io, path, .{ .mode = .read_only }); 16 defer file.close(io); 17 18 var file_buffer: [4096]u8 = undefined; 19 var file_reader = file.reader(io, &.{}); 20 21 const bytes_read = try file_reader.interface.readSliceShort(&file_buffer); 22 const content = file_buffer[0..bytes_read]; 23 24 const name_start = std.mem.indexOf(u8, content, "(") orelse return error.InvalidStatFormat; 25 const name_end = std.mem.lastIndexOf(u8, content, ")") orelse return error.InvalidStatFormat; 26 27 if (name_end <= name_start + 1) return error.InvalidStatFormat; 28 29 const name = try allocator.dupe(u8, content[name_start + 1 .. name_end]); 30 31 const after_name = content[name_end + 1 ..]; 32 var field_it = std.mem.tokenizeAny(u8, after_name, " \t\n"); 33 34 // Skip state field 35 _ = field_it.next() orelse return error.InvalidStatFormat; 36 37 const ppid_str = field_it.next() orelse return error.InvalidStatFormat; 38 const ppid = try std.fmt.parseInt(std.c.pid_t, ppid_str, 10); 39 40 return ProcessInfo{ 41 .name = name, 42 .ppid = ppid, 43 }; 44 }