Skip to content

Commit cf2c704

Browse files
committed
add strict option for pidof
1 parent 38be678 commit cf2c704

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

docs/content/programs/pidof.org

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#+TITLE: pidof
22
#+DATE: 2024-08-17T17:52:44+0800
3-
#+LASTMOD: 2024-09-01T11:56:51+0800
3+
#+LASTMOD: 2024-10-30T21:37:30+0800
44
#+TYPE: docs
55
#+DESCRIPTION: Linux has this command, but not macOS, so I write it for you.
66

7+
Program name is case insensitive by default, pass =-S= option if you want sensitive match.
8+
79
#+begin_src bash :results verbatim :exports results :wrap example :dir ../../..
810
./zig-out/bin/pidof -h
911
#+end_src
@@ -14,9 +16,10 @@
1416
./zig-out/bin/pidof [OPTIONS] [--] [program]
1517

1618
OPTIONS:
17-
-s, --single Single shot - this instructs the program to only return one pid.
18-
-S, --separator STRING Use separator as a separator put between pids.(default: )
19-
-u, --user_only Only show process belonging to current user.
20-
-v, --version Print version.
21-
-h, --help Print help message.
19+
-s, --single Only return the first matching pid.
20+
-d, --delimiter STRING Output delimiter if more than one PID is shown.(default: )
21+
-S, --strict Case sensitive when matching program name.
22+
-u, --user_only Only show process belonging to current user.
23+
-v, --version Print version.
24+
-h, --help Print help message.
2225
#+end_example

src/bin/pidof.zig

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,49 @@ const c = @cImport({
1212

1313
pub const Options = struct {
1414
single: bool = false,
15-
separator: []const u8 = " ",
15+
delimiter: []const u8 = " ",
16+
strict: bool = false,
1617
user_only: bool = false,
1718
version: bool = false,
1819
help: bool = false,
1920

2021
pub const __shorts__ = .{
2122
.single = .s,
22-
.separator = .S,
23+
.delimiter = .d,
24+
.strict = .S,
2325
.user_only = .u,
2426
.version = .v,
2527
.help = .h,
2628
};
2729
pub const __messages__ = .{
28-
.single = "Single shot - this instructs the program to only return one pid.",
29-
.separator = "Use separator as a separator put between pids.",
30+
.single = "Only return the first matching pid.",
31+
.delimiter = "Output delimiter if more than one PID is shown.",
32+
.strict = "Case sensitive when matching program name.",
3033
.user_only = "Only show process belonging to current user.",
3134
.version = "Print version.",
3235
.help = "Print help message.",
3336
};
3437
};
3538

36-
pub fn findPids(allocator: std.mem.Allocator, opt: Options, program: []const u8) !std.ArrayList(c.pid_t) {
39+
pub fn searchPids(allocator: std.mem.Allocator, opt: Options, program: []const u8) !std.ArrayList(c.pid_t) {
3740
var mib = [_]c_int{
3841
c.CTL_KERN,
3942
c.KERN_PROC,
4043
c.KERN_PROC_ALL,
4144
};
4245
var procSize: usize = 0;
46+
// sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
4347
var rc = c.sysctl(&mib, mib.len, null, &procSize, null, 0);
4448
if (rc != 0) {
45-
std.debug.print("get proc size, err:{any}", .{std.posix.errno(rc)});
49+
std.log.err("get proc size, err:{any}", .{std.posix.errno(rc)});
4650
return error.sysctl;
4751
}
4852

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

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

72-
// p_comm is [17]u8
7376
const name = std.mem.sliceTo(&proc.kp_proc.p_comm, 0);
74-
if (program.len >= name.len) {
75-
if (std.mem.eql(u8, name, program[0..name.len])) {
77+
if (opt.strict) {
78+
if (std.mem.eql(u8, name, program)) {
79+
try pids.append(proc.kp_proc.p_pid);
80+
}
81+
} else {
82+
if (std.ascii.eqlIgnoreCase(name, program)) {
7683
try pids.append(proc.kp_proc.p_pid);
7784
}
7885
}
@@ -90,21 +97,20 @@ pub fn main() !void {
9097
defer opt.deinit();
9198

9299
if (opt.positional_args.len == 0) {
93-
std.debug.print("program is not given", .{});
100+
std.log.err("program is not given", .{});
94101
std.posix.exit(1);
95102
}
96103

97104
const program = opt.positional_args[0];
98-
99-
const pids = try findPids(allocator, opt.args, program);
105+
const pids = try searchPids(allocator, opt.args, program);
100106
if (pids.items.len == 0) {
101107
std.posix.exit(1);
102108
}
103109

104110
var stdout = std.io.getStdOut().writer();
105111
for (pids.items, 0..) |pid, i| {
106112
if (i > 0) {
107-
try stdout.writeAll(opt.args.separator);
113+
try stdout.writeAll(opt.args.delimiter);
108114
}
109115
try stdout.print("{d}", .{pid});
110116
}

0 commit comments

Comments
 (0)