This report consists of four parts:
1. - description of the bug
2. - contents of test.bat
3. - contents of inobug.txt
4. - contents of ino.c
1. description of the bug
Both the stat and the fstat function don't return a correct value in the member
st_ino of the stat structure in certain cases. This problem is present in DJGPP
2.02 and 2.03. I ran the tests under Windows 98, but I don't think the OS has
anything to do with it. The cases I tested are
- stat/fstat a file with the same path on different drives
- stat/fstat a file two times
- stat/fstat a file two times with a different path
I used the batch file test.bat. test.bat uses drive a:, but drive d: gives
the same results on my PC (filesystem doesn't matter?). test.bat calls the
program ino.exe and redirects the output to c:\inobug.txt. The output I got
is showed in section 3. The source of ino.exe is showed in section 4.
The bug seems to cause stat to return the same st_ino value for files on
different drives and fstat to return a different value in st_ino. Of course,
the correct behaviour is that two files have different values in st_ino and
one file the same value in st_ino for every call to stat/fstat.
2. test.bat:
rem change the f in echo f into an appropriate character if you don't use
rem the english version of win9x
echo f|xcopy c:\command.com c:\foo
xcopy c:\foo a:\
c:\djgpp\ino c:\foo a:\foo > c:\inobug.txt
c:\djgpp\ino c:\foo c:\foo >> c:\inobug.txt
c:
cd\
c:\djgpp\ino .\foo foo >> c:\inobug.txt
3. inobug.txt:
stat says: c:\foo and a:\foo are one file.
fstat says: c:\foo and a:\foo are two files.
stat says: c:\foo and c:\foo are one file.
fstat says: c:\foo and c:\foo are two files.
stat says: .\foo and foo are one file.
fstat says: .\foo and foo are two files.
4. ino.c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct stat stat1, stat2, fstat1, fstat2;
int file1, file2;
if (argc != 3)
{
printf("Usage: ino file1 file2\n");
exit(1);
}
if ((file1 = open(argv[1], O_RDONLY)) < 0 ||
(file2 = open(argv[2], O_RDONLY)) < 0)
{
printf("Error while opening the files.\n");
exit(2);
}
if (!stat(argv[1], &stat1) && !stat(argv[2], &stat2) &&
!fstat(file1, &fstat1) && !fstat(file2, &fstat2))
{
printf("stat says: ");
if (stat1.st_ino == stat2.st_ino)
printf("%s and %s are one file.\n", argv[1], argv[2]);
else
printf("%s and %s are two files.\n", argv[1], argv[2]);
printf("fstat says: ");
if (fstat1.st_ino == fstat2.st_ino)
printf("%s and %s are one file.\n", argv[1], argv[2]);
else
printf("%s and %s are two files.\n", argv[1], argv[2]);
}
else
{
printf("Error while getting the file status.\n");
exit(3);
}
close(file1);
close(file2);
return 0;
}
// end of report