前回の記事でも触れましたが最近はplan9portのrcをつかって生活をしています。
rcではヒストリ機能はサポートしておらず、readline系のなんかを使うと良いんじゃないかみたいなアドバイスがされています。
そんなときに便利なのはやっぱりrlwrapです。任意のコマンドを readlineで囲むことができます。
rlwrapの仕組みとしては、引数としてもらったコマンドを子プロセスとして把握していて、入出力の処理をするという仕組みになっています。
また、その一貫としてファイル名の補完というのがあり、子プロセスのカレントディレクトリ(a.k.a CWD)を見て、ファイル名を保管してくれるというのが有ります。
この機能、元々は/procファイルシステムを持つUNIX系システムでしかサポートされておらず、Macではrlwrapを最初に立ち上げたフォルダの中身がいつまでも保管されるようになっており不便でした。
macでもlibprocというものがあり、
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <libproc.h> int main (int argc, char* argv[]) { int ret; pid_t pid; char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; struct proc_vnodepathinfo vpi; if (argc > 1) { pid = (pid_t) atoi(argv[1]); ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf)); if (ret <= 0) { fprintf(stderr, "PID %d: proc_pidpath ();\n", pid); fprintf(stderr, " %s\n", strerror(errno)); return 1; } ret = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)); if (ret <= 0) { fprintf(stderr, "PID %d: proc_pidinfo ();\n", pid); fprintf(stderr, " %s\n", strerror(errno)); return 1; } printf("%s\n", vpi.pvi_cdir.vip_path); } return 0; }
こんな感じのコードでPIDを指定してそのプロセスのcwdを取得することができました。
これをMacで有効にしてくればいいのになと思っていたら、
そんなPRが二年前にすでに提出されていました。提出されていたのですが
libprocというファイルが存在するだけでは、実際に上記のMacのようなコードがサポートされているか不明瞭なので、autoreconfでの判定をもう少しちゃんとしないとねというところで止まっていました。
僕としてはぜひ取り込まれてほしいので、止まってるけどどんな感じとつついてみたところ、作者がさくっと取り込んでくれたようです。
これで、mac環境下でもrlwrapをつかっていて子プロセスのCWDが変わったときに適切にファイル名の補完が追従されるようになったようです。