I am using both directory-1.3.8.3 and unix-compat-0.7.4.1 in a hobby project. Both libraries allow to check if a path is a symbolic link, but they throw different results. Here there is a minimal examples
#!/usr/bin/env cabal
{- cabal:
build-depends:
base
, directory==1.3.8.3
, unix-compat==0.7.4.1
, filepath==1.5.2.0
default-language: GHC2024
-}
import System.Directory.OsPath qualified as Directory
import System.PosixCompat qualified as Posix
import System.OsPath qualified as OsPath
import System.Exit (exitSuccess)
main :: IO()
main = do
posix <- Posix.isSymbolicLink <$> Posix.getFileStatus "linked.txt"
direct <- Directory.pathIsSymbolicLink $ OsPath.unsafeEncodeUtf "linked.txt"
putStrLn "PosixCompat result is:"
print posix
putStrLn "Directory result is:"
print direct
exitSuccess
Now, create a symlink file and run the program.
> ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.10.1
> touch original.txt
> ln -s original.txt linked.txt
> cabal run main.hs
PosixCompat result is:
False
Directory result is:
True
Is this behaviour expected? to me it seems that either there is a bug or there is something I donāt understand (likely the second)
You are not the first one tripping on this, see unix/#79, so I would say documentation is lacking.
If you have time, please file an issue, if not I will do it myself.
Edit: I hadnāt seen there was another answer that was posted while I wrote mine.
Long Story with the same conclusion as above
Confusing behaviour to say the least: After a deep dive into the source of unix-compat and unpacking and running the tests myself I can now at least offer a hint.
Iāve looked into the man page for stat, which I found to be likely to be used by unix-compat internally.
An excerpt from man fstat64(2)
stat() and fstatat() retrieve information about the file pointed to by pathname; the differences for fsā
tatat() are described below.
lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about
the link itself, not the file that the link refers to.
fstat() is identical to stat(), except that the file about which information is to be retrieved is specified
by the file descriptor fd.