Proposal unix. Change to `IO (Maybe String)`: getLoginName, getUserEntry* and getGroupEntry*

Thomas Miedema thomasmiedema at gmail.com
Fri Sep 26 16:23:11 UTC 2014


In the unix package, in System.Posix.User, we have the following functions
[1]:

* getLoginName (getlogin)
* getUserEntryForID (getpwuid_r)
* getGroupEntryForID (getgrgid_r)
* getUserEntryForName (getpwnam_r)
* getGroupEntryForName (getgrnam_r)

They have signature `IO String`, and use `throwErrnoIfNull` to call the c
functions listed in parenthesis.


## Proposal
Change the signature of the functions listed above to `IO (Maybe String)`.

The new semantics would be:
* If the c function returns a NULL pointer with errno set to ENOENT,
meaning the given user or group could not be found, the result is Nothing.
* If another error occured, an error is thrown (no change).
* Otherwise the result is Just "result".


## Motivation
At least `getlogin` and `getgrgid` are unreliable on Linux. It is possible
for them to return NULL pointers [2] even when the user is logged in and
has an associated user entry in /etc/passwd and group entry in /etc/group.

Examples:
* when `getLoginName` is called using a terminal emulator that doesn't
write login records to /var/run/utmp, or inside screen/tmux, `getlogin`
tends to return NULL pointers [3].
* `getGroupEntryForID` can throw a NULL pointer exception inside chroots or
other environments where the information in /etc/groups is not to be
considered reliable [4].

Since we can, let's give the above Haskell functions a type safe(r) api.

If the proposal gets rejected, I will just add a warning message to the
docstrings of the functions in question and permanently disable their tests
from the unix testsuite, since this is currently causing problems [5,6].

Discussion period: 2 weeks.


## Links
[1] https://github.com/haskell/unix/blob/master/System/Posix/User.hsc
[2] http://linux.die.net/man/3/getlogin
[3]
https://github.com/haskell/unix/blob/cad1ef27bb0a51bc68ebadb1297de1ae05bee9db/tests/all.T#L14-L18
[4] https://ghc.haskell.org/trac/ghc/ticket/8293
[5] http://www.haskell.org/pipermail/ghc-devs/2014-September/006420.html
[6] https://ghc.haskell.org/trac/ghc/ticket/1487#comment:23


## Details
* Another function in the same module that needs to change is
`getEffectiveUserName`, because it calls the function `getUserEntryForID`
mentioned before.

* The following functions don't need to change, since they return the empty
list if no entries are found:
  - getGroups (getgroups)
  - getAllGroupEntries (getgrent)
  - getAllUserEntries (getpwent)

* The rest of the functions in the module don't need to change either,
since they are not expected to return NULL pointers, according to their
respective man pages:
  - getRealUserID (getuid)
  - getRealGroupID (getgid)
  - getEffectiveUserID (geteuid)
  - getEffectiveGroupID (getegid)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20140926/bb4d0947/attachment.html>


More information about the Libraries mailing list