Skip to content

Commit

Permalink
add strict option for pidof
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Oct 30, 2024
1 parent 38be678 commit cf2c704
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
15 changes: 9 additions & 6 deletions docs/content/programs/pidof.org
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#+TITLE: pidof
#+DATE: 2024-08-17T17:52:44+0800
#+LASTMOD: 2024-09-01T11:56:51+0800
#+LASTMOD: 2024-10-30T21:37:30+0800
#+TYPE: docs
#+DESCRIPTION: Linux has this command, but not macOS, so I write it for you.

Program name is case insensitive by default, pass =-S= option if you want sensitive match.

#+begin_src bash :results verbatim :exports results :wrap example :dir ../../..
./zig-out/bin/pidof -h
#+end_src
Expand All @@ -14,9 +16,10 @@
./zig-out/bin/pidof [OPTIONS] [--] [program]

OPTIONS:
-s, --single Single shot - this instructs the program to only return one pid.
-S, --separator STRING Use separator as a separator put between pids.(default: )
-u, --user_only Only show process belonging to current user.
-v, --version Print version.
-h, --help Print help message.
-s, --single Only return the first matching pid.
-d, --delimiter STRING Output delimiter if more than one PID is shown.(default: )
-S, --strict Case sensitive when matching program name.
-u, --user_only Only show process belonging to current user.
-v, --version Print version.
-h, --help Print help message.
#+end_example
34 changes: 20 additions & 14 deletions src/bin/pidof.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,49 @@ const c = @cImport({

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

pub const __shorts__ = .{
.single = .s,
.separator = .S,
.delimiter = .d,
.strict = .S,
.user_only = .u,
.version = .v,
.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.",
.single = "Only return the first matching pid.",
.delimiter = "Output delimiter if more than one PID is shown.",
.strict = "Case sensitive when matching program name.",
.user_only = "Only show process belonging to current user.",
.version = "Print version.",
.help = "Print help message.",
};
};

pub fn findPids(allocator: std.mem.Allocator, opt: Options, program: []const u8) !std.ArrayList(c.pid_t) {
pub fn searchPids(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;
// sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
var rc = c.sysctl(&mib, mib.len, null, &procSize, null, 0);
if (rc != 0) {
std.debug.print("get proc size, err:{any}", .{std.posix.errno(rc)});
std.log.err("get proc size, err:{any}", .{std.posix.errno(rc)});
return error.sysctl;
}

const procList = try allocator.alloc(c.struct_kinfo_proc, procSize / @sizeOf(c.struct_kinfo_proc));
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/sysctl.3.html
rc = c.sysctl(&mib, mib.len, @ptrCast(procList), &procSize, null, 0);
if (rc != 0) {
std.debug.print("get proc list failed, err:{any}", .{std.posix.errno(rc)});
std.log.err("get proc list failed, err:{any}", .{std.posix.errno(rc)});
return error.sysctl;
}

Expand All @@ -69,10 +73,13 @@ pub fn findPids(allocator: std.mem.Allocator, opt: Options, program: []const u8)
}
}

// 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])) {
if (opt.strict) {
if (std.mem.eql(u8, name, program)) {
try pids.append(proc.kp_proc.p_pid);
}
} else {
if (std.ascii.eqlIgnoreCase(name, program)) {
try pids.append(proc.kp_proc.p_pid);
}
}
Expand All @@ -90,21 +97,20 @@ pub fn main() !void {
defer opt.deinit();

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

const program = opt.positional_args[0];

const pids = try findPids(allocator, opt.args, program);
const pids = try searchPids(allocator, opt.args, program);
if (pids.items.len == 0) {
std.posix.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.writeAll(opt.args.delimiter);
}
try stdout.print("{d}", .{pid});
}
Expand Down

0 comments on commit cf2c704

Please sign in to comment.