- 個人的な備忘録ですので、詳しいところと詳しくないところがアンバランスかも
- ただし誤りの指摘は歓迎します
ライセンス
- X11 License(割と重要)
バージョン
- 最新版は、http://rpm5.org/files/popt/ によると1.16
- https://launchpad.net/popt/2.0 に2.0開発中とあるが、微妙なところ
使い方
オプション指定
struct poptOption optionTable[]={}
- 要素は、
{"long-name", 'short_name', arg_type(数値), arg(参照値), 識別子(数値), "説明1(--option[=__ここに入る__])", "説明2"}
- たとえば、arg_typeを
POPT_ARG_INT
にするなら、argはint*
。 - POPT_ARG_NONEの場合、*argに1が代入される。
- POPT_ARG_VALの場合、*argに識別子が代入される。
- この2つにはオプション値は付けてはならない。
- POPT_ARG_STRINGの場合、*argにオプション値が代入されるが、popt 1.16では複製、開発版では移動が発生する。
- 前者の複製されたメモリの元側は、後のオプションの有無で解放されたりされなかったりする
流れ
-
poptGetContext()
でコンテキスト取得 -
poptGetNextArg()
を回す- POPT_ARG_VAL以外のタイプで識別子を設定した場合は、途中でその識別子が帰ってくることがある
-
poptGetOptArg()
でオプション値を取得した上で、細かい設定ができる - POPT_ARGFLAG_OPTIONALの場合、オプション値がNULLの場合があるが、その値の設定もここで行う
- オプション値がない場合1にするとかはデフォルトではやってくれない
-
poptGetOptArg()
の返し値は文字列
-
poptFreeContext()
で解放
メモリリーク
その1
- オプション値に相当する部分のメモリが開放されないため、たとえば、
{"option",'o',POPT_ARG_INT|POPT_ARG_OPTIONAL,&flg,OPT_O,NULL,NULL}
のとき、-o2
と付けるだけで2\0
に相当する2バイトがリークする。 - この問題は最新版であるbzr r789では改善されている。
- [170102] なぜかr790でrevertされてしまったので、(changes未反映のこともあり)r789を明示的にダウンロードすることをお薦めします。
- http://bazaar.launchpad.net/~rpm5/popt/trunk/tarball/789
- ただし、arg(参照値)を指定している場合、GetOptArg()ではNULLが帰ってくる。
for(;(optc=poptGetNextOpt(optCon))>=0;){
if(optc==OPT_O){
char *arg=poptGetOptArg(optCon);
if(arg)flg=strtol(arg,NULL,10);
else flg=1;
}
}
- というコードは、
- flgに2を代入した後当該文字列は開放される
-
poptGetOptArg()
でNULLが帰ってくる - 結果、flgに意図せず1が代入されてしまう
- ため、禁則である。
- 結果、POPT_ARG_OPTIONALを指定する場合、argはNULLにする必要があるといえる。
- OPTIONALでない場合は、argの中身を見て処理をするだけということも可能なので、NULLにしない場合もある。
- 1.16以下ではflgには正常に2が代入されていた(勿論メモリリークのせい)。
その2
- その1でメモリが開放されるのは、
- (
poptGetOptArg()
によらない)flgへの代入が発生した時 -
poptGetOptArg()
を呼ばずにpoptGetNextOpt() または poptFreeContext()
を呼んだ時
- (
- である。したがって、poptGetOptArg()により得られたメモリは自分で解放しなければならない。
- poptGetOptArg()により、メモリがpoptの管理外になるためである。同様に、POPT_ARG_STRINGについても、参照値に割り振られたメモリはpoptの管理外になるため、自分で解放しなければならない。
rsync
- rsyncにもpoptGetOptArg()についてメモリリークが発見された。POPT_ARG_STRINGについてはグローバル変数のため確認できず。
- https://bugzilla.samba.org/show_bug.cgi?id=12173 にて報告。