Skip to content

Commit

Permalink
add pidof (#10)
Browse files Browse the repository at this point in the history
* add pidof

* fix build

* ignore pidof for linux/window
  • Loading branch information
jiacai2050 committed Jun 28, 2023
1 parent 5de8771 commit 1150d21
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 19 deletions.
3 changes: 2 additions & 1 deletion README.org
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#+TITLE: Zigcli
#+DATE: 2022-09-20T22:55:17+0800
#+LASTMOD: 2022-09-20T22:55:17+0800
#+LASTMOD: 2023-06-28T20:22:53+0800
#+AUTHOR: Jiacai Liu
#+EMAIL: dev@liujiacai.net
#+OPTIONS: toc:nil num:nil
Expand All @@ -13,6 +13,7 @@ Command line programs written in Zig. Currently there are:
- =loc=, lines of code.
- =tree=, list contents of directories in a tree-like format.
- =yes=, output a string repeatedly until killed.
- =pidof=, like [[https://man7.org/linux/man-pages/man1/pidof.1.html][pidof]], but for macOS.

Prebuilt binaries can be found in [[https://github.com/jiacai2050/loc/actions/workflows/binary.yml][CI's artifacts]], or you can build from source:
#+begin_src bash
Expand Down
47 changes: 34 additions & 13 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,27 @@ pub fn build(b: *Build) void {
buildLoc(b, optimize, target, simargs_dep),
"loc",
},
.{
buildPidof(b, optimize, target, simargs_dep),
"pidof",
},
.{
buildYes(b, optimize, target),
"yes",
},
}) |prog| {
const exe = prog.@"0";
const name = prog.@"1";
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run-" ++ name, "Run " ++ name);
run_step.dependOn(&run_cmd.step);
if (prog.@"0") |exe| {
const name = prog.@"1";
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
if (b.args) |args| {
run_cmd.addArgs(args);
}
b.step("run-" ++ name, "Run " ++ name)
.dependOn(&run_cmd.step);

all_tests.append(buildTestStep(b, name, target)) catch @panic("OOM");
all_tests.append(buildTestStep(b, name, target)) catch @panic("OOM");
}
}

const test_all_step = b.step("test", "Run all tests");
Expand All @@ -52,7 +57,7 @@ fn buildTestStep(b: *std.Build, comptime name: []const u8, target: std.zig.Cross
return test_step;
}

fn buildTree(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTarget, simargs_dep: *std.build.Dependency) *Build.CompileStep {
fn buildTree(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTarget, simargs_dep: *std.build.Dependency) ?*Build.CompileStep {
const exe = b.addExecutable(.{
.name = "tree",
.root_source_file = FileSource.relative("src/tree.zig"),
Expand All @@ -64,7 +69,7 @@ fn buildTree(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTar
return exe;
}

fn buildLoc(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTarget, simargs_dep: *std.build.Dependency) *Build.CompileStep {
fn buildLoc(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTarget, simargs_dep: *std.build.Dependency) ?*Build.CompileStep {
const exe = b.addExecutable(.{
.name = "loc",
.root_source_file = FileSource.relative("src/loc.zig"),
Expand All @@ -78,7 +83,7 @@ fn buildLoc(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTarg
return exe;
}

fn buildYes(b: *std.build.Builder, optimize: std.builtin.Mode, target: std.zig.CrossTarget) *std.build.CompileStep {
fn buildYes(b: *std.build.Builder, optimize: std.builtin.Mode, target: std.zig.CrossTarget) ?*Build.CompileStep {
const exe = b.addExecutable(.{
.name = "yes",
.root_source_file = FileSource.relative("src/yes.zig"),
Expand All @@ -88,3 +93,19 @@ fn buildYes(b: *std.build.Builder, optimize: std.builtin.Mode, target: std.zig.C

return exe;
}

fn buildPidof(b: *std.Build, optimize: std.builtin.Mode, target: std.zig.CrossTarget, simargs_dep: *std.build.Dependency) ?*Build.CompileStep {
if (target.getOsTag() != .macos) {
return null;
}

const exe = b.addExecutable(.{
.name = "pidof",
.root_source_file = FileSource.relative("src/pidof.zig"),
.target = target,
.optimize = optimize,
});
exe.addModule("simargs", simargs_dep.module("simargs"));

return exe;
}
6 changes: 3 additions & 3 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.{
.name = "loc",
.name = "zigcli",
.version = "0.1.0",
.dependencies = .{
.simargs = .{
.url = "https://github.com/jiacai2050/simargs/archive/2ac9368.tar.gz",
.hash = "1220c7f602de51855b241b771058255d5023e156c2d8df93c3cf0f6ec3248e484f95",
.url = "https://github.com/jiacai2050/simargs/archive/77eb191.tar.gz",
.hash = "1220eef7753fccb692bbebae6b4ee2bab7900e954b5598ea25649ade4c062481cb49",
},
.@"table-helper" = .{
.url = "https://github.com/jiacai2050/table-helper/archive/f0c8eb9.tar.gz",
Expand Down
2 changes: 1 addition & 1 deletion src/loc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ fn populateLoc(allocator: std.mem.Allocator, loc_map: *LocMap, dir: fs.Dir, base
loc_entry.files += 1;

const metadata = try file.metadata();
const file_size = @truncate(usize, metadata.size());
const file_size: usize = @truncate(metadata.size());
if (file_size == 0) {
return;
}
Expand Down
95 changes: 95 additions & 0 deletions src/pidof.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//! Pidof for macOS
//!
//! https://man7.org/linux/man-pages/man1/pidof.1.html

const std = @import("std");
const simargs = @import("simargs");
const c = @cImport({
@cInclude("sys/sysctl.h");
});

pub const Options = struct {
single: bool = false,
separator: []const u8 = " ",
help: bool = false,

pub const __shorts__ = .{
.single = .s,
.separator = .S,
.help = .h,
};
pub const __messages__ = .{
.single = "Single shot - this instructs the program to only return one pid.",
.separator = "Use separator as a separator put between pids.",
.help = "Print help message.",
};
};

pub fn findPids(allocator: std.mem.Allocator, opt: Options, program: []const u8) !std.ArrayList(c.pid_t) {
var mib = [_]c_int{
c.CTL_KERN,
c.KERN_PROC,
c.KERN_PROC_ALL,
};
var procSize: usize = 0;
var rc = c.sysctl(&mib, mib.len, null, &procSize, null, 0);
if (rc != 0) {
std.debug.print("get proc size, err:{any}", .{std.c.getErrno(rc)});
return error.sysctl;
}

var procList = try allocator.alloc(c.struct_kinfo_proc, procSize / @sizeOf(c.struct_kinfo_proc));
rc = c.sysctl(&mib, mib.len, @ptrCast(procList), &procSize, null, 0);
if (rc != 0) {
std.debug.print("get proc list failed, err:{any}", .{std.c.getErrno(rc)});
return error.sysctl;
}

// procSize may change between two calls of sysctl, so we cannot iterate
// procList directly with for(procList) |proc|.
var pids = std.ArrayList(c.pid_t).init(allocator);
for (0..procSize / @sizeOf(c.struct_kinfo_proc)) |i| {
if (opt.single and pids.items.len == 1) {
break;
}
const proc = procList[i];
// p_comm is [17]u8
const name = std.mem.sliceTo(&proc.kp_proc.p_comm, 0);
if (program.len >= name.len) {
if (std.mem.eql(u8, name, program[0..name.len])) {
try pids.append(proc.kp_proc.p_pid);
}
}
}

return pids;
}

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

const opt = try simargs.parse(allocator, Options, "[program]");
defer opt.deinit();

if (opt.positional_args.items.len == 0) {
std.debug.print("program is not given", .{});
std.os.exit(1);
}

const program = opt.positional_args.items[0];

const pids = try findPids(allocator, opt.args, program);
if (pids.items.len == 0) {
std.os.exit(1);
}

var stdout = std.io.getStdOut().writer();
for (pids.items, 0..) |pid, i| {
if (i > 0) {
try stdout.writeAll(opt.args.separator);
}
try stdout.print("{d}", .{pid});
}
}
2 changes: 1 addition & 1 deletion src/util.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub const StringUtil = struct {
const SIZE_UNIT = [_][]const u8{ "B", "K", "M", "G", "T" };

pub fn humanSize(allocator: mem.Allocator, n: u64) ![]const u8 {
var remaining = @floatFromInt(f64, n);
var remaining: f64 = @floatFromInt(n);
var i: usize = 0;
while (remaining > 1024) {
remaining /= 1024;
Expand Down

0 comments on commit 1150d21

Please sign in to comment.