したがって、基本的に、本当に必要なのは、ファイル記述子が与えられ、基本的に同じファイルをもう一度開いて、別の位置、共有、モードなどを取得することです。そして、これを Windows (「ファイル記述子」 " は基本的に外部オブジェクトであり、OSやランタイム ライブラリによって直接使用されるものではありません。
驚くべきことに、少なくとも MS VC++ ではそれを行う方法があります。2 つのステップを除いてすべて Win32 API のみを使用するため、他のコンパイラ/ライブラリへの移植はかなり合理的なはずです (ほとんどの場合、これら 2 つの関数のバージョンが提供されていると思います)。これらは、Unix スタイルのファイル記述子をネイティブの Win32 ファイル ハンドルに変換し、ネイティブの Win32 ファイル ハンドルを Unix スタイルのファイル記述子に変換するためのものです。
- _get_osfhandle() を使用して、ファイル記述子をネイティブ ファイル ハンドルに変換します。
- GetFileInformationByHandleEx(FILE_NAME_INFO) 1でファイルの名前を取得します。
- CreateFile を使用して、そのファイルへの新しいハンドルを開きます
- _open_osfhandle() でそのハンドルのファイル記述子を作成します
ほら、同じファイルを参照する新しいファイル記述子がありますが、独自の権限、位置などがあります。
質問の終わりに向かって、「アクセス許可」も必要なように聞こえますが、それは実際には意味がないようです-アクセス許可は、ファイルを開く方法ではなく、ファイル自体に添付されるため、ファイルを開いたり、再度開いたりしても、ファイルのアクセス許可には影響しません。本当に知りたい場合は、GetFileInformationByHandle で取得できますが、Windows のファイル アクセス許可は、Unix の (従来の) ファイル アクセス許可とはかなり異なることに注意してください。Unix には、すべてのファイルに対する所有者/グループ/世界のアクセス許可があり、ほとんどのシステムにも ACL があります (ただし、動作方法にはさらにバリエーションがあります)。Windows にはパーミッションがまったくない (例: FAT または FAT32 上のファイル) か、ACL を使用する (例: NTFS 上のファイル) かのいずれかですが、
おそらく、「アクセス許可」を使用して、ファイルが読み取り、書き込み、またはその両方で開かれていたかどうかを参照しています。それを取得することは、前述のいずれよりもかなり醜いです。問題は、そのほとんどが Win32 ではなくライブラリにあることです。そのため、コンパイラ間で移植可能に近い方法はおそらくないでしょう。MS VC++ 9.0 SP1 (他のコンパイラでは保証されていません) では、次のことができます。
#include <stdio.h>
int get_perms(int fd) {
int i;
FILE * base = __iob_func();
for (i=0; i<_IOB_ENTRIES; i++)
if (base[i]._file == fd)
return base[i]._flag; // we've found our file
return 0; // file wasn't found.
}
これにはいくつかの探検が含まれていたため、実際に機能するかどうかを確認するための簡単なテストを作成しました。
#ifdef TEST
#include <io.h>
void show_perms(int perms, char const *caption) {
printf("File opened for %s\n", caption);
printf("Read permission = %d\n", (perms & _IOREAD)!=0);
printf("Write permission = %d\n", (perms & _IOWRT)!=0);
}
int main(int argc, char **argv) {
FILE *file1, *file2;
int perms1, perms2;
file1=fopen(argv[1], "w");
perms1 = get_perms(_fileno(file1));
fclose(file1);
file2=fopen(argv[1], "r");
perms2 = get_perms(_fileno(file2));
fclose(file2);
show_perms(perms1, "writing");
show_perms(perms2, "reading");
return 0;
}
#endif
結果は成功を示しているようです。
File opened for writing
Read permission = 0
Write permission = 1
File opened for reading
Read permission = 1
Write permission = 0
次に、stdio.h で定義されている _IOREAD、_IOWRT、および _IORW に対して、返されたフラグをテストできます。以前の警告にもかかわらず、ライブラリのこの部分がかなり安定していると思われる (確かに保証はできませんが) ので、大きな変更が実際に行われる可能性はおそらくごくわずかです。
ただし、他の方向では、基本的に他のライブラリで動作する可能性はまったくありません。Intel 、MinGW、またはバックエンドとして MS VC++ を使用する Comeau など、MS ライブラリを使用する他のコンパイラで動作する可能性があります (ただし、保証されているわけではありません)。それらの中で、動作する可能性が最も高いのは Comeau であり、MinGW が最も可能性が低いと思います (ただし、これは推測にすぎません。それらのいずれでも動作しない可能性は十分にあります)。
- 再配布可能な Win32 FileID API ライブラリが必要です