Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_all
名前
ftw, nftw - ファイルツリーを歩きまわる
書式
#include <ftw.h> int ftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb, int typeflag), int nopenfd); #define _XOPEN_SOURCE 500 /* feature_test_macros(7) 参照 */ #define _XOPEN_SOURCE 500 #include <ftw.h> int nftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf), int nopenfd, int flags);
説明
ftw() は、 dirpath で指定されたディレクトリ以下のディレクトリツリー全体を歩きまわり、 ツ リー中でエントリが見付かるごとに、 fn() を呼び出す。 デフォルトでは、ディレクトリそのもの が、そのディレクトリにあるファイルや サブディレクトリよりも先に処理される (行きがけ順探索; preorder traversal)。 呼び出し元プロセスが利用可能なファイルディスクリプタを使い切って しまわないようにするた め、 ftw() が同時にオープンするディレクトリの最大数を nopenfd で指定することができる。 探 索の深さがこの値を越えると、 一つのディレクトリを閉じてから他のディレクトリをオープンし直 すこと になるので、 ftw() の動作は遅くなる。 ftw() は、ディレクトリツリーの階層 1 レベル につき、 最大でも一つのファイルディスクリプタしか使用しない。 ディレクトリツリーで見つかったエントリ毎に、 ftw() は fpath, sb, typeflag の 3つを引き数 として fn() を呼び出す。 fpath はエントリのパス名である。 dirpath が相対パス名で指定され た場合には、 fpath は ftw() が呼び出された時点の呼び出し元プロセスのカレントワーキング ディレクトリ からの相対パス名となる。 dirpath が絶対パス名で指定された場合には、 fpath は 絶対パス名となる。 sb は fpath に対する stat(2) の呼び出しで返される stat 構造体へのポイン タである。 typeflag は整数で、以下の値のいずれか一つである: FTW_F fpath が通常のファイルである FTW_D fpath がディレクトリである FTW_DNR fpath が読み込みできないディレクトリである FTW_NS シンボリックリンクではない fpath に対する stat(2) 呼び出しが失敗した。 fpath がシンボリックリンクで、かつ stat(2) が失敗した場合、 FTW_NS と FTW_SL (後 述) のどちらが typeflag に渡されるかは未定義であると、POSIX.1-2001 には書かれてい る。 ツリーの探索を止めたい場合は、 fn() が 0 以外の値を返せば良い (この値は ftw() 自身の戻り 値となる)。 それ以外の場合は ftw() はツリー全体の探索を続け、すべてのツリーを探索し終えた ところで 0 を返す。探索中に (malloc(3) の失敗などの) エラーが起こると -1 を返す。 ftw() は動的なデータ構造を用いるので、ツリー探索を安全に中断する唯一の方法は 0 以外の値を fn() の返り値とすることである。割り込みを扱うには、 例えば発生した割り込みをマークしておい て、 0 以外の値を返すようにする シグナルによりメモリリークを起こさずに探索を終了できるよう にするには、 シグナルハンドラで fn() がチェックするグローバルなフラグをセットするようにす ればよい。 プログラムを終了させる場合以外は、 longjmp(3) を使用しないこと。 nftw() 関数 nftw() は ftw() と同じだが、引き数 flags が追加される点と、 fn() の引き数に ftwbuf が追加される点が異なる。 この flags 引き数は下記のフラグの 0 個以上の論理和を取ったものである: FTW_ACTIONRETVAL (glibc 2.3.3 以降) このフラグは glibc 固有である。 このフラグをセットすると、 nftw() の fn() の返り 値の扱いが変わる。 fn() は以下の値のいずれか一つを返す必要がある。 FTW_CONTINUE nftw() は通常通り処理を続ける。 FTW_SKIP_SIBLINGS fn() がこの値を返した場合、処理中のエントリの兄弟 (同じ階層のエントリ) の 処理はスキップされ、親ディレクトリで続きの処理が行われる。 FTW_SKIP_SUBTREE fn() が呼び出されたエントリがディレクトリ (typeflag が FTW_D) の場合に、こ の値を返すと fn() の引き数として渡されたディレクトリ内のエントリの処理が行わ れなくなる。 nftw() は処理中のディレクトリの兄弟 (同じ階層のエントリ) から 処理を続ける。 FTW_STOP nftw () は、返り値 FTW_STOP ですぐに復帰する。 他の返り値は将来新しい動作に対応付けられる可能性がある。 fn() は上記のリストにある 値以外を返さないようにすべきである。 <ftw.h> で FTW_ACTIONRETVAL の定義が有効にするためには、 (「どの」ヘッダファイルを インクルードするよりも前に) 機能検査マクロ _GNU_SOURCE を定義しなければならない。 FTW_CHDIR セットされると、ディレクトリの内容を処理する前に そのディレクトリに chdir(2) す る。このフラグは、 fpath が属すディレクトリで何らかの動作を実行する必要がある場合に 便利である。 FTW_DEPTH セットされると、帰りがけ順探索 (post-order traversal) を行う。 つまり、ディレクトリ そのものを引き数とした fn() 呼出しは、そのディレクトリに含まれるファイルとサブディ レクトリに 対する処理の「後で」行われる (デフォルトでは、ディレクトリ自身の処理は ディレクトリ内のエントリ より「前に」行なわれる)。 FTW_MOUNT セットされると、同じファイルシステムの中だけを探索対象とする (つまり、マウントポイ ントをまたぐことはない)。 FTW_PHYS セットされると、シンボリックリンクを辿らない (おそらくこちらが 通常望ましい動作だろ う)。セットされていないとシンボリックリンクを 辿るが、同じファイルが二回報告される ことはない。 FTW_PHYS がセットされずに FTW_DEPTH がセットされると、自分自身に対するシンボリック リンクを配下に持つ ディレクトリに対して fn() が呼び出されることは決してない。 ディレクトリツリーのエントリ毎に、 nftw() は 4つの引き数で fn() を呼び出す。 fpath と sb は ftw() と同じである。 typeflag には、 ftw() で取り得る値のいずれか、または以下の値のい ずれかが渡される: FTW_DP fpath がディレクトリで、かつ flags で FTW_DEPTH が指定されていた。 fpath 配下のファ イルとサブディレクトリは全て処理が終わっている。 FTW_SL fpath がシンボリックリンクで、かつ FTW_PHYS が flags に セットされていた。 FTW_SLN fpath がシンボリックリンクで、存在しないファイルを指している (これがセットされるの は FTW_PHYS がセットされていない場合だけである)。 nftw() が fn() を呼び出す際に渡す 4つめの引き数は FTW 型の構造体である。 struct FTW { int base; int level; }; base は、ファイル名 (basename 要素) の、 fpath で渡されるパス名の中でのオフセットである。 level はディレクトリツリーでの fpath の深さを示す。深さはディレクトリツリーのトップ (root) からの 相対値である (dirpath は深さ 0 である)。
返り値
これらの関数は、成功すると 0 を、エラーが発生すると -1 を返す。 fn() が 0 以外を返した場合、ディレクトリツリーの探索を終了し、 fn() が返した値を ftw() や nftw() の結果として返す。 nftw() が FTW_ACTIONRETVAL フラグ付きで呼ばれた場合、ツリーの探索を終了させるために fn() が使用できる、非 0 の値は FTW_STOP だけであり、 この値は nftw() の返り値として返される。
準拠
POSIX.1-2001, SVr4, SUSv1. POSIX.1-2008 は ftw() を廃止予定としている。
注意
POSIX.1-2001 の注記によると、 fn がカレントワーキングディレクトリを保持しなかった場合の 結 果は規定されていないとされている。 nftw() 関数と、 ftw() における FTW_SL は、SUSv1 で導入された。 ftw() で FTW_SL を一切使わないシステムや、 存在しないファイルを指しているシンボリックリン クの場合にのみ FTW_SL を使うシステム、また ftw() が全てのシンボリックリンクに対して FTW_SL を使うシステムもある。 予測可能な動作をさせるためには、 nftw() を使うこと。 Linux では、 libc4, libc5, glibc 2.0.6 は 「stat できるがディレクトリではないオブジェク ト」 (ファイル, シンボリックリンク, fifo 等) に対してはすべて FTW_F を使う。 nftw() 関数は glibc 2.1 以降で利用できる。 FTW_ACTIONRETVAL は glibc 固有である。
例
以下のプログラムは、一つ目のコマンドライン引き数を名前に持つパス以下の ディレクトリツリー を探索する。引き数が指定されなかった場合は、 カレントディレクトリ以下を探索する。 各々の ファイルについて様々の情報が表示される。 二番目のコマンドライン引き数に文字を指定すること で、 nftw() を呼び出す際に flags 引き数に渡す値を制御することができる。 #define _XOPEN_SOURCE 500 #include <ftw.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> static int display_info(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) { printf("%-3s %2d %7jd %-40s %d %s\n", (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" : (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" : (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" : (tflag == FTW_SLN) ? "sln" : "???", ftwbuf->level, (intmax_t) sb->st_size, fpath, ftwbuf->base, fpath + ftwbuf->base); return 0; /* To tell nftw() to continue */ } int main(int argc, char *argv[]) { int flags = 0; if (argc > 2 && strchr(argv[2], 'd') != NULL) flags |= FTW_DEPTH; if (argc > 2 && strchr(argv[2], 'p') != NULL) flags |= FTW_PHYS; if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags) == -1) { perror("nftw"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
関連項目
stat(2), fts(3), readdir(3)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.54 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。