unix package built wrong on Solaris
On Solaris with recent gcc versions the unix package gets built with an inconsistent state of system header files which results in getSymbolicLinkStatus
not working. In turn this breaks darcs.
The problem is that the HsUnix.h
file contains a bunch of inline functions. These get inlined into the .hc
file for the Files.hs
module that FFI imports them. The problem is that this .hc
file #include
s an RTS header files which uses some #define
to get certain API spec compatibility and for some reason this causes the lstat()
call to be directed to the 32bit file ABI whereas the .hsc
file was compiled for the 64bit (large file support) ABI. The outcome is that the .o
file for the System.Posix.Files
module is actually calling the lstat()
function when it expects to be calling the lstat64()
function. As a result we get back the wrong struct stat
and so of course all the functions like isDirectory
etc are then looking at the wrong offsets in the struct stat
.
The functions that are being FFI imported are compiled into the cbits/HsUnix.c
file anyway (because it #import
s HsUnix.h
with a #define
to turn off the inlining) so there is no need for them to be inlined into the .hc
file. The cbits/HsUnix.c
gets built correctly (because it does not #include
the RTS headers that cause the problem) and so does call lstat64
rather than lstat()
. This can be verified with nm
.
So the solution is to remove all the inline calls from HsUnix.h
, changing them to simple prototypes, and to put the function bodies in HsUnix.c
. This solution works fine. Tested on Solaris 10, ghc-6.8.3. The files appear to be unchanged in ghc 6.10 and HEAD so the same solution should work there.
We should add a test case for this. It should test the getSymbolicLinkStatus
function with a few things that obviously should work, like isDirectory
etc. We might as well test getFileStatus
too. The difference is that the FFI wrapper for getFileStatus
is defined in the base
package rather than the unix
package. This is why it was unaffected by the above problem.
Generally all the FFI wrappers defined via inlines in .h
files that get #include
d into .hc
files are rather suspect, but especially so for wrappers of things defined in system header files. These should instead be wrapped in very simple .c files that #include
a minimum of headers so as to not bump into weird untested combinations of system headers and standards compatibility #define
s.
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |