GNU/Linux >> Linux の 問題 >  >> Linux

パスを見つけるために readlink を実装する方法

受け入れられた答えはほぼ正しいですが、PATH_MAX は

<ブロック引用>

システムにそのような制限がない場合、POSIX ごとに定義される保証はありません。

(readlink(2) マンページより)

また、定義されている場合、常に「真の」制限を表すとは限りません。 (http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html を参照)

readlink のマンページには、symlink でそれを行う方法も記載されています:

<ブロック引用>

静的なサイズのバッファーを使用すると、シンボリック リンクのコンテンツに十分なスペースが提供されない場合があります。バッファーに必要なサイズは、リンク上の lstat(2) の呼び出しによって返される stat.st_size 値から取得できます。ただし、readlink() と read‐linkat() によって書き込まれたバイト数をチェックして、呼び出し間でシンボリックリンクのサイズが増加していないことを確認する必要があります。

ただし、ほとんどの /proc ファイルと同様に、/proc/self/exe/ の場合、stat.st_size は 0 になります。残っている唯一の解決策は、バッファーが収まらないときにバッファーのサイズを変更することです。

vector<char> の使用をお勧めします この目的のために次のように:

std::string get_selfpath()
{
    std::vector<char> buf(400);
    ssize_t len;

    do
    {
        buf.resize(buf.size() + 100);
        len = ::readlink("/proc/self/exe", &(buf[0]), buf.size());
    } while (buf.size() == len);

    if (len > 0)
    {
        buf[len] = '\0';
        return (std::string(&(buf[0])));
    }
    /* handle error */
    return "";
}

readlink を正しく使用するには、readlink() 関数を適切に使用してください 関数。

std::string にパスがある場合 、次のようなことができます:

#include <unistd.h>
#include <limits.h>

std::string do_readlink(std::string const& path) {
    char buff[PATH_MAX];
    ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
    if (len != -1) {
      buff[len] = '\0';
      return std::string(buff);
    }
    /* handle error condition */
}

固定パスのみを使用している場合:

std::string get_selfpath() {
    char buff[PATH_MAX];
    ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
    if (len != -1) {
      buff[len] = '\0';
      return std::string(buff);
    }
    /* handle error condition */
}

使用するには:

int main()
{
  std::string selfpath = get_selfpath();
  std::cout << selfpath << std::endl;
  return 0;
}

マンページの内容を見てみましょう:

 readlink() places the contents of the symbolic link path in the buffer
 buf, which has size bufsiz.  readlink does not append a NUL character to
 buf.

わかった。十分に単純でなければなりません。バッファが 1024 文字の場合:

 char buf[1024];

 /* The manpage says it won't null terminate.  Let's zero the buffer. */
 memset(buf, 0, sizeof(buf));

 /* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
 if (readlink("/proc/self/exe", buf, sizeof(buf)-1) < 0)
 {
    /* There was an error...  Perhaps the path does not exist
     * or the buffer is not big enough.  errno has the details. */
    perror("readlink");
    return -1;
 }

Linux
  1. Python でファイルまたはディレクトリの所有者を見つける方法

  2. 最大スタック サイズを確認するにはどうすればよいですか?

  3. Linux で「find」の結果を mv にパイプする方法

  1. LinuxでHADOOP_HOMEパスを見つける方法は?

  2. デフォルトのファイルマネージャを見つける方法は?

  3. ファイルシステムの UUID を見つける方法

  1. LinuxでディスクがSSDかHDDかを確認する方法

  2. findコマンドを使用して権限を監査する方法

  3. ファイルのURLを探す