Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_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 stat(2) の呼び出しがシンボリックリンクでない fpath で失敗した。 これのよくある原因 は、呼び出し元が親ディレクトリに対する読み込み許可を持っており、 ファイル名 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 が属すディレクトリで何らかの動作を実行する必要がある場合に 便利である。 (このフラグを指定しても fn の 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 が指定されていた (FTW_DEPTH が flags に指定されていなかった場合、 ディレクトリに対しては常に typeflag が FTW_D で fn() が呼び出される)。 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() の返り値として返される。
バージョン
nftw() は バージョン 2.1 以降の glibc で利用できる。
準拠
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() を使うこと。 「stat できるがディレクトリではないオブジェクト」 (ファイル, シンボリックリンク, fifo 等) に対しては、すべて FTW_F が返される。 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.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。