書式
#include <stdio.h>
char *tempnam(const char *dir, const char *pfx);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
tempnam(): _BSD_SOURCE || _SVID_SOURCE
説明
決してこの関数を使用しないこと。 代わりに mkstemp(3) か tmpfile(3) を使うこと。tempnam() 関数はファイル名として正しい文字列へのポインタを返す。 このファイル名を持つファイルは、 tempnam() がチェックした時点においては存在しない (しなかった)。 pfx が NULL でない 5 バイト以内の文字列であれば、 生成されるパス名のうちのファイル名の部分は pfx から始まるものになる。 生成されるディレクトリの部分は、「適切」でなければならない (大抵の場合、「適切」であるためにはまず少なくとも 書き込み可能でなければならない)。
適切なディレクトリの探索は、以下の手順にしたがって行われる。
- a)
- 環境変数 TMPDIR が設定されていて、 その内容が適切なディレクトリの名前なら、それを用いる。
- b)
- それ以外の場合、 dir 引き数が NULL でない文字列でかつ適切なら、それを用いる。
- c)
- それ以外の場合、 (<stdio.h> で定義されている) P_tmpdir が適切なら、それを用いる。
- d)
- 最後に実装で定義されたディレクトリが用いられることになる。
tempnam() が返す文字列は malloc(3) を使って確保される。そのため、 free(3) で解放すべきである。
返り値
成功すると tempnam() 関数は、一意なテンポラリファイル名へのポインタを返す。 一意な名前が生成できなければ NULL を返し、 errno にエラーの原因を示す値を設定する。エラー
- ENOMEM
- 保存領域の割り当てに失敗した。
準拠
SVr4, 4.3BSD, POSIX.1-2001. POSIX.1-2008 は tempnam() を廃止予定としている。注意
tempnam() は推測が難しい名前を生成するが、それにもかかわらず、 tempnam() がパス名を返してから、プログラムがそのファイルをオープンする までの間に、別のプログラムが同じパス名で、ファイルを open(2) で作成したり、シンボリックリンクを作成したりする可能性がある。 これはセキュリティホールにつながる可能性がある。 そのような可能性を回避するためには、 open(2) の O_EXCL フラグを使ってパス名をオープンすればよい。 もっといいのは、 mkstemp(3) や tmpfile(3) を使うことである。SUSv2 では TMPDIR に付いて言及されていない。 glibc は、プログラムが set-user-ID されていない場合に限ってこれを用いる。 SVr4 では d) で使用されるディレクトリを /tmp と定めている (glibc もこの通りである)。
パス名を返すのに使用するメモリを動的に確保するので、 tmpnam(3) と違い、 tempnam() はリエントラントであり、スレッドセーフである。
tempnam() 関数は最大 TMP_MAX 回まで、呼び出される度に異なる文字列を作成する (TMP_MAX は <stdio.h> で定義されている)。 もし TMP_MAX 回以上呼び出された場合、動作は実装依存である。
tempnam() は最大で pfx の先頭 5 バイトを使用する。
他と重ならない名前が見つけられなかった場合、glibc の tempnam() の実装はエラー EEXIST で失敗する。
バグ
「適切」という言葉の正確な意味は定義されていない。 ディレクトリに対してどの程度のアクセス権限が必要なのかは指定されていない。この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。