chikuchikugonzalezの雑記帳

趣味とか日記とかメモとか(∩゚д゚)

Rustでプロセスの実行ファイルパスを取得するナニカを作った

Process Entry、略して pentry と名付けました。
github.com

大元の動機は結構前にGoでツール作ってた時、「あー、親プロセスの実行ファイルとれねーかなー」とか思ったたら既にあったというもの*1
github.com

で、これと同じことをRustできないかなー、って思ったのが始まり。
つーてLinux側は特に心配してなかったんだけど、Windows側はFFIの関係でちょっと苦労した*2

使い方

基本はプロセスIDから探すので、こうなります。ところでホントにlibc使わないと今のプロセスID取れないんですか…?

extern crate libc;
extern crate pentry;

let pid: i32;
unsafe {
    pid = libc::getpid() as i32;
}

if let Ok(ps) = pentry::find(pid) {
    println!("#{} {}", ps.pid(), ps.path().unwrap());
}

で、いちいちlibc書くのめんどいだろうからヘルパー的に現在プロセスを取得する関数はあります。

extern crate pentry;

if let Ok(ps) = pentry::current() {
    println!("{:?}", ps);
}

取得できたプロセスオブジェクトには親プロセスを取得するためのメソッド parent() が生えているので、それをたどれば親プロセスを取得できます( ´∀`)b

extern crate pentry;

let ps  = pentry::current().unwrap();
let pps = ps.parent().unwrap();
println!("Parent: {:?}", pps);
おまけ:pentryコマンド

cargo install pentryとかすると一緒に pentry コマンドが $HOME/.cargo/bin に配置されます。これを使うと特定プロセスの実行ファイルとか見れます、たぶん*3
ある意味参考実装的なものですね。

chiku2gonzalez@xenial:~$ pentry  -h
Show some process information.

USAGE: pentry -h|--help
       pentry [-P|--parent] [PID [PID...]]

Options:
    -h, --help          Show this usage message.
    -P, --parent        Inspect parent process entry.

chiku2gonzalez@xenial:~$ .cargo/bin/pentry
  PID	 PPID	PATH
 5284	 2379	/home/chiku2gonzalez/.cargo/bin/pentry

chiku2gonzalez@xenial:~$ .cargo/bin/pentry -P
  PID	 PPID	PATH
 2379	 2377	/bin/bash
 5295	 2379	┗ /home/chiku2gonzalez/.cargo/bin/pentry

chiku2gonzalez@xenial:~$ 
余談

とりあえず trait を Go の interface みたいにできないのがツライ(´・ω・`) *4

*1:HashiCorpの人が作ってた

*2:コード量の大半はFFI絡みという

*3:フルパスに関しては取れないこともある前提で。型もOptionだし。

*4:Result型に入らない的な意味で