FFI file operations broken on 32-bit systems (inc many functions in unix package)
hsc2hs has a C preprocessor prelude (utils/hsc2hs/template-hsc.h) which includes some GHC header files. As a result, hsc processes files in 64-bit offset mode:
% cpp -I../../includes -dM template-hsc.h | grep FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
However, when building HsUnix.c (or any c file with cabal), the environment is different and it's built in 32-bit offset mode.
This leads to the case where structures which are different between 32 and 64 bit offset mode (like struct stat) are broken. The offsets in the Haskell code from hsc2hs are for the 64-bit structure, but the libc calls are made to fill in the 32-bit one.
hsc2hs can be changed to compile in 32-bit offset mode by removing the includes from the beginning of the template header file. (All the GHC builds fine this way). However, this leads to a mismatch in the sizes of types between GHC and the code. So, although the offsets are now correct and the correct libc functions are called - extracting, say, an ino_t reads 64, not 32, bits.
Also, mismatching GHC and the code on something as fundamental as this seems to be a recipe for trouble in the future.
Thus, GHC should probably add -D_FILE_OFFSET_BITS=64 when building .c files. I believe that will fix everything.
Test case
import System.Posix.Files
main = do
System.Posix.Files.getFileStatus "/" >>= print . System.Posix.Files.fileID
Should print a garbage number. However, this depends on the contents of memory. Try both in ghci and with ghc --make
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |