コードをいじった後、lstat(2) の機能またはバグを見つけたようです。stat と fstat でもある lstat のマニュアル ページによると、stat と lstat の違いは次のとおりです。
stat() は、パスが指すファイルを統計し、buf を埋めます。
lstat() は stat() と同じですが、path がシンボリック リンクの場合、参照先のファイルではなく、リンク自体が stat される点が異なります。
私はあなたのプログラムを取り、それで少し遊んだ。リンクを確認するために、lstat、stat、および fopen を使用しました。コードは以下です。要するに、stat と fopen の両方がリンクを適切に検出しましたが、lstat は失敗しました。これについては説明がありません。
以下のプログラムは、「ln -s bar bar」として作成されたファイル bar で実行され、次の出力が得られました。
./foo ./bar
Errno as returned from lstat = 0
Errno as returned from stat = 92
loop found
Errno as returned from fopen = 92
loop found
コード:
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
struct stat buffer;
int status;
int savedErrno1;
int savedErrno2;
int savedErrno3;
FILE *theFile;
if (argc != 2) {
printf("error: file name required\n");
return 0;
}
errno = 0;
status = lstat(argv[1], &buffer);
savedErrno1 = errno;
printf("Errno as returned from lstat = %d\n", savedErrno1);
if (savedErrno1 == ELOOP) {
printf("loop found\n");
}
errno = 0;
status = stat(argv[1], &buffer);
savedErrno2 = errno;
printf("Errno as returned from stat = %d\n", savedErrno2);
if (savedErrno2 == ELOOP) {
printf("loop found\n");
}
errno = 0;
theFile = fopen(argv[1], "w");
savedErrno3 = errno;
printf("Errno as returned from fopen = %d\n", savedErrno3);
if (savedErrno3 == ELOOP) {
printf("loop found\n");
}
return 1;
}