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 #includes 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 #imports 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 #included 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 #defines.
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 |