readlink

READLINK(2)                 Linux Programmer's Manual                READLINK(2)



名前
       readlink, readlinkat - シンボリックリンクの値を読む

書式
       #include <unistd.h>

       ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

       #include <fcntl.h>           /* AT_* 定数の定義 */
       #include <unistd.h>

       ssize_t readlinkat(int dirfd, const char *pathname,
                          char *buf, size_t bufsiz);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       readlink():
           _BSD_SOURCE || _XOPEN_SOURCE >= 500 ||
           _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_C_SOURCE >= 200112L

       readlinkat():
           glibc 2.10 以降:
               _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
           glibc 2.10 より前:
               _ATFILE_SOURCE

説明
       readlink()  は pathname で与えられたシンボリックリンクの内容を buf バッファーへ格納する、 buf のサイズは
       bufsiz である。 readlink()  はヌルバイトを buf に追加しない。 その内容全てを格納するのにバッファーが小さ過ぎる場合は、
       (bufsiz バイトの長さに) 内容を切り詰める。

   readlinkat()
       readlinkat() システムコールは readlink() と全く同様に動作するが、以下で説明する点が異なる。

       pathname で指定されたパス名が相対パスの場合、このパス名はファイルディスクリプター dirfd
       が参照するディレクトリに対する相対パスと解釈される (readlink()
       に相対パス名を渡した場合のように、呼び出したプロセスのカレントワーキングディレクトリに対する相対パスではない)。

       pathname で指定されたパス名が相対パスで、 dirfd が特別な値 AT_FDCWD の場合、 (readlink() と同様に)
       pathname は呼び出したプロセスのカレントワーキングディレクトリに対する相対パスと解釈される。

       pathname で指定されたパス名が絶対パスの場合、 dirfd は無視される。

       Linux 2.6.39 以降では、 pathname に空文字列を指定できる。 その場合、呼び出しは dirfd
       が参照するシンボリックリンクに対して行われる (dirfd はフラグ O_PATH O_NOFOLLOW を指定した open(2)
       を使って取得すべきである)。

       readlinkat() の必要性についての説明については openat(2) を参照。

返り値
       成功すると、これらのシステムコールは buf に格納されたバイト数を返す。 エラーの場合、-1 を返し、 errno にエラーを示す値を設定する。

エラー
       EACCES パスのディレクトリ部分に検索許可が与えられていない (path_resolution(7)  も参照すること)。

       EFAULT buf がプロセスに割り当てられたアドレス空間の外を指している。

       EINVAL bufsiz が正でない。

       EINVAL 指定したファイルがシンボリックリンクでない。

       EIO    ファイルシステムの読み込み中に I/O エラーが起こった。

       ELOOP  パス名にシンボリックリンクが多すぎる。

       ENAMETOOLONG
              パス名かパス名の一部分が長過ぎる。

       ENOENT その名前のファイルが存在しない。

       ENOMEM 十分なカーネルメモリーがない。

       ENOTDIR
              パスのディレクトリ部分がディレクトリでない。

       readlinkat() では以下のエラーも発生する。

       EBADF  dirfd が有効なファイルディスクリプターではない。

       ENOTDIR
              pathname が相対パスで、 dirfd がディレクトリ以外のファイルを参照しているファイルディスクリプターである。

バージョン
       readlinkat()  はカーネル 2.6.16 で Linux に追加された。 ライブラリによるサポートはバージョン 2.4 で glibc
       に追加された。

準拠
       4.4BSD (readlink()  は 4.2BSD で初めて登場した), POSIX.1-2001, POSIX.1-2008.

       readlinkat(): POSIX.1-2008.

注意
       バージョン 2.4 以前の glibc (バージョン 2.4 を含む) では、 readlink()  の返り値の型は int
       で宣言されていた。現在では、返り値の型は ssize_t である (返り値 ssize_t は POSIX.1-2001 で (新たに)
       必須となった)。

       静的な大きさのバッファーを使うと、 シンボリックリンクの内容を格納するのに十分な領域がない場合がある。 バッファーに必要なサイズは、
       そのシンボリックリンクに対して lstat(2) の呼び出しで返される stat.st_size の値から取得できる。 ただし、
       readlink() や readlinkat() が書き込んだバイト数をチェックして、
       シンボリックリンクのサイズが二つの呼び出しの間で増えていないことを確認すべきである。 readlink() や readlinkat()
       用のバッファーを動的に割り当てる方法でも、 バッファーサイズとして PATH_MAX を使用する場合に共通する移植性の問題を解決することができる。
       なぜなら、POSIX では、 システムがそのような上限値を定義していない場合には、 PATH_MAX
       が定義されることが保証されていないからである。

   glibc での注意
       readlinkat() が利用できない古いカーネルでは、 glibc ラッパー関数は readlink()
       を使用するモードにフォールバックする。 pathname が相対パスの場合、 glibc は dirfd 引き数に対応する
       /proc/self/fd のシンボリックリンクに基づいてパス名を構成する。


       以下のプログラムは、 readlink() が必要とするバッファーを、 lstat() が提供する情報に基づいて動的に割り当てる。
       また、両方の呼び出し間で競合条件がないことを保証している。

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>

       int
       main(int argc, char *argv[])
       {
           struct stat sb;
           char *linkname;
           ssize_t r;

           if (argc != 2) {
               fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           if (lstat(argv[1], &sb) == -1) {
               perror("lstat");
               exit(EXIT_FAILURE);
           }

           linkname = malloc(sb.st_size + 1);
           if (linkname == NULL) {
               fprintf(stderr, "insufficient memory\n");
               exit(EXIT_FAILURE);
           }

           r = readlink(argv[1], linkname, sb.st_size + 1);

           if (r == -1) {
               perror("readlink");
               exit(EXIT_FAILURE);
           }

           if (r > sb.st_size) {
               fprintf(stderr, "symlink increased in size "
                               "between lstat() and readlink()\n");
               exit(EXIT_FAILURE);
           }

           linkname[r] = '\0';

           printf("'%s' points to '%s'\n", argv[1], linkname);

           free(linkname);

           exit(EXIT_SUCCESS);
       }

関連項目
       readlink(1), lstat(2), stat(2), symlink(2), realpath(3),
       path_resolution(7), symlink(7)

この文書について
       この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部
       である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。



Linux                              2014-10-15                        READLINK(2)