名前
realpath - 正規化された絶対パス名を返す
書式
#include <limits.h>
#include <stdlib.h>
char *realpath(const char *path, char *resolved_path);
説明
realpath() は path として与えられた NULL で終る文字列の中にある すべてのシンボリックリンクを展開し /./, /../ による参照や余分な / を解決して、正規化された絶対パス名を resolved_path というバッファーの中に格納する。 このバッファーのサイズは PATH_MAX である。 結果として返るパスの中には、シンボリックリンクや /./, /../ といった要素は含まれない。
返り値
エラーがなかった場合、 realpath() は resolved_path へのポインターを返す。
それ以外の場合は、ヌル (NULL) ポインターが返り、配列 resolved_path の内容は不定である。 グローバル変数 errno がエラーの内容にあわせてセットされる。
エラー
EACCES | パスのディレクトリ部分に、読み出し許可または検索許可が与えられていない。 |
EINVAL | path か resolved_path のいずれかが NULL である。 (libc5 では、このような場合 segfault を起こすだけであろう) 但し、下記の「注意」の節を参照のこと。 |
EIO | ファイルシステムを読むときに、I/Oエラーが起こった。 |
ELOOP | パス名の変換にあたり、解決すべきシンボリック・リンクの数が多過ぎた。 |
ENAMETOOLONG | |
パス名の一要素の文字数が NAME_MAX を越えている、またはパス名全体の文字数が PATH_MAX を越えている。 | |
ENOENT | 指定されたファイルが存在しない。 |
ENOTDIR | |
パスのディレクトリ要素が、ディレクトリでない。 | |
バージョン
この関数が Linux に登場したのは libc 4.5.21 である。
準拠
4.4BSD, POSIX.1-2001.
4.4BSD と Solaris では、パス名の長さの上限は (<sys/param.h> の中にある) MAXPATHLEN である。SUSv2 では PATH_MAX と NAME_MAX が規定されており、 これらは <limits.h> で定義されているか、 pathconf(3) 関数から得られる。以下のようなソースコードになっていることが多い (バグの章も参照のこと) :
#ifdef PATH_MAX path_max = PATH_MAX; #else path_max = pathconf(path, _PC_PATH_MAX); if (path_max <= 0) path_max = 4096; #endif
4.4BSD、Linux、SUSv2 では、返り値は常に絶対パス名である。 Solaris では、 引き数 path が相対パスの場合、返り値が相対パスになることがある。 realpath() のプロトタイプ宣言は、 libc4 と libc5 では <unistd.h> にあるが、 それ以外の環境ではいずれも <stdlib.h> にある。
注意
realpath() の glibc の実装では非標準の拡張がなされている。 resolved_path に NULL が指定されると、 realpath() は malloc(3) を使って解決したパス名を保持するためのバッファを 最大で PATH_MAX バイトまで割り当て、 このバッファへのポインタを返す。 呼び出し元は、 free(3) を使ってこのバッファを解放すべきである。
バグ
この関数の使用は避けること。設計段階から問題があるからだ。 (非標準の resolved_path == NULL の拡張機能を使わない限り) 出力バッファ resolved_path の適切なサイズを決定することができないからである。 POSIX ではバッファ・サイズとして PATH_MAX は十分だとされているが、 PATH_MAX は定義済の定数である必要はなく、 pathconf(3) を使って得られる値であってもよいことになっている。 pathconf(3) からバッファ・サイズを取得したとしても必ずしも十分ではない。 なぜなら、 pathconf(3) の返り値が大き過ぎて適切にメモリを確保することができないかもしれない と POSIX では警告されているし、 pathconf(3) は PATH_MAX に制限がないことを示す -1 を返すかもしれないからである。
libc4 と libc5 の実装はバッファ・オーバーフローの可能性を持っている (libc-5.4.13 で修正されたが)。したがって、mount のような set-user-ID されるプログラムでは、この関数相当の関数を自前で持つ必要がある。
関連項目
readlink(2), canonicalize_file_name(3), getcwd(3), pathconf(3), sysconf(3)