[GHC] #8741: `System.Directory.getPermissions` fails on read-only filesystem
GHC
ghc-devs at haskell.org
Thu Feb 6 10:35:45 UTC 2014
#8741: `System.Directory.getPermissions` fails on read-only filesystem
-------------------------------------+-------------------------------------
Reporter: hvr | Owner: AlainODea
Type: bug | Status: patch
Priority: high | Milestone:
Component: libraries/unix | Version: 7.6.3
Resolution: | Keywords:
Operating System: POSIX | Architecture: Unknown/Multiple
Type of failure: Incorrect result | Difficulty: Easy (less than 1
at runtime | hour)
Test Case: | Blocked By:
Blocking: | Related Tickets:
-------------------------------------+-------------------------------------
Comment (by duncan):
So the patch looks ok.
I think I would also add ETXTBSY as another alternative, i.e.
{{{
(err == eACCES || err == eROFS || err == eTXTBSY)
}}}
Since according to `access(2)`
{{{
ETXTBSY
Write access was requested to an executable which is being
exe‐
cuted.
}}}
and `open(2)`:
{{{
ETXTBSY
pathname refers to an executable image which is currently
being
executed and write access was requested.
}}}
So the patch on its own is fine, but looking at
`System.Directory.getPermissions` leaves me aghast:
{{{
read_ok <- Posix.fileAccess name True False False
write_ok <- Posix.fileAccess name False True False
exec_ok <- Posix.fileAccess name False False True
stat <- Posix.getFileStatus name
}}}
Four! Four? Four calls to stat? (`access()` is just a C lib function that
calls `stat()`.)
Surely we can do better than that? One call to stat should be enough.
Also, `access` doesn't do quite what we want. What we want to know is "if
I tried to read/write/exec/traverse this file/dir, would it work?". But
access answerss a subtly different question:
{{{
The check is done using the calling process's real UID and GID,
rather
than the effective IDs as is done when actually attempting an
operation
(e.g., open(2)) on the file. This allows set-user-ID programs to
eas‐
ily determine the invoking user's authority.
}}}
Well, that's all very good and useful, but it's not what we want here.
So yes, ideally we'd do one stat call and work it all out from there.
{{{
stat <- Posix.getFileStatus name
let mode = Posix.fileMode stat
read_ok = -- bit twiddling on mode using constants like
Posix.ownerReadMode
write_ok = -- etc
exec_ok = -- etc
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8741#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list