2016-04-24 1 views
0

Linuxのシステムコールreadlinkは試作品を持っていますパスはファイルに到達するために最初に従わなければならないシンボリックリンクであってもよい。機能openのために例えばプロトタイプを参照してください:パスは、NULLで終了です引数文字列をコピーせずにsymlinkの値を読み取ることは可能ですか?一般的な使用で</p> <pre><code>ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); </code></pre> <p>、1は一定のNULL終端された文字列で指定したファイル・パス内のディレクトリにアクセスするための関数を書き込み:シンボリックリンクを読むこと

int open(const char *pathname, int flags); 

ますが、その中のディレクトリは/によって終了され、1つはreadlinkに引数としてそれらを供給しています。パス文字は「読み取り専用」なので、/文字を0に置き換えることはできません。

つまり、最初にディレクトリをコピーし、0を追加してからreadlinkを適用する必要があります。これは一時的に1文字を置き換えるよりも遅くなります。

既存のすべてのLinuxライブラリでこれを行う必要があり、これを高速に実行する方法がないことは私には奇妙に思えます。

ファイルパスにできるだけ早くアクセスする機能を記述する必要があります。 readlinkに適用するディレクトリ文字列をコピーするよりも、ディレクトリシンボリックリンクに従う方法はありますか?

追加:例 - 関数openを書きたいとしましょう。この関数は、与えられたパスを横切る必要があります。ディレクトリを見るたびに、それがシンボリックリンクかどうかを確認しなければなりません。あなたは、この使用してパスのあらゆるレベルでのシンボリックリンクをたどることにしました

int open(const char *pathname, int flags); 

+0

あなたが表示された場合にそれが役立つだろう私たちは実際にあなたが実行している操作を正確に示す擬似コードオーミング。私はシンボリックリンクとファイルを開いて、あなたが何を達成しようとしているのかは完全にはわかりません。 –

+0

明示的に 'O_NOFOLLOW'または' O_EXCL'を 'open'に渡さない限り、' open' *はシンボリックリンクに従います。シンボリックリンクを最初に従うようなことはありません。 –

+0

@FrederikDeweerdtはい、しかし、私の質問は、 'open'のような使用法に関するものではありません。私の質問はそのような_writing_に関する呼び出しです。 –

答えて

1

あなたが同様の機能を実装したい

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

そして、あなたはまだpathnameのコピーを避けたいですそれでも接頭辞をreadlink()に渡すことができます。

readlink()のソースコードを掘り下げて、私たちが目的のために簡単にクローンを変更できることを願っています。私の考えは、ヌルターミネータに頼るのではなく、pathnameの明示的な長さを与えられる可能性のある基本的な機能があるかもしれないということでした。

しかし、私はそのような運がなかった。例:https://fossies.org/dox/glibc-2.23/sysdeps_2unix_2sysv_2linux_2generic_2readlink_8c_source.html

null終端された文字列は、というLinguaフランカのC言語で書かれているので、やや不運かもしれません。私はあなたを与えることができる最高の提案は以下のとおりです。

  1. は非constとしてpathnameを取るためにあなたのopen() -alikeを変更

    。これにより、一部の呼び出し側に引数を強制的にコピーさせることができますが、少なくともconst以外の文字列を保持している人は、それを直接使用できます。

  2. open()-allkeで長さがPATH_MAXの事前割り当てされた文字列のプール(スレッドごとに1つで、スレッドローカルストレージを使用することを検討してください)を使用してください。すでに割り当てられているターゲットがとても遅いではなく、あなただけの質問で述べたようにされた後、あなたが'\0'ため/を入れ替えることができます(open()一回それを行うために必要なコピー文字列。

  3. 利用realpath()の代わりreadlink()。これは、一度に全体のパスを正規化し、ので、おそらくあなたは(あなたもreadlink()に苦しむだろう)realpath()自体の内部作られた単一のコピーから離れてコピーを心配する必要はありません。

+0

@JonnZwinckはい、ありがとう、ありがとう、これをしていただきありがとうございます、私はあなたが "ソースに掘り下げ"する必要があるとは思わなかった、私は誰かがすでに_know_ "引数 –

+0

非constを使うように私のopen-alikeのプロトタイプを変更することはできません。私はあなたの答えは非常に関連性がある、私は確かに運の外だと思うことができることを望む –

+0

@マークガレック:ようこそ。私は3つ目の選択肢、realpath()を追加しました。これは役に立つかもしれません。 –

関連する問題