xmonad / xmonad-contrib

Contributed modules for xmonad
https://xmonad.org
BSD 3-Clause "New" or "Revised" License
584 stars 274 forks source link

Add more portable way of getting hostname in Layout.OnHost #899

Closed cacharle closed 1 week ago

cacharle commented 1 month ago

It seems like it currently only checks for the HOST environment variable. It would be nice if it could check /etc/hostname or other environment variables.

Maybe use Network.HostName? https://hackage.haskell.org/package/hostname-1.0/docs/src/Network-HostName.html#getHostName

https://github.com/xmonad/xmonad-contrib/blob/eb7268451c017eeb56258b97effacc3050c8461d/XMonad/Layout/OnHost.hs#L119

geekosaur commented 1 month ago

The commit log may be of interest (it looks like I added this before we moved to GitHub, so there's no PR and the commit description is a little wonky):

commit c691988bbfe4c267a2e562689cc9640e53a1ec88
Author: Brandon S Allbery KF8NH <allbery.b@gmail.com>
Date:   Tue Mar 20 03:09:12 2012 +0000

    XMonad.Layout.OnHost allows host-specific modifications to a layout, which

    is otherwise very difficult to do.  Similarly to X.L.PerWorkspace, it provides
    onHost, onHosts, modHost, and modHosts layout modifiers.  It attempts to do
    smart hostname comparison, such that short names will be matched with short
    names and FQDNs with FQDNs.

    This module currently requires that $HOST be set in the environment.
    You can use System.Posix.Env.setEnv to do so in xmonad.hs if need be.
    (Properly, this should be done via the network library, but I'm trying to
    avoid adding that dependency.)  An alternative would be to shell out to
    get the name, but that has considerable portability hurdles.

The hostname package doesn't look terrible, but any additional dependency requires some discussion. (Probably not much in this case.)

slotThe commented 1 month ago

Would shelling out really be that much of a pain in terms of portability? I'd guess (well, hope :)) that all systems we still support have a hostname in path.

In either case, the relevant code in that package seems to small (most of it is MS Windows stuff) that vendoring sounds like a better option to me, should we choose to go down that route:

type HostName = String

foreign import ccall unsafe "gethostname" gethostname :: CString -> CSize -> IO CInt

getHostName :: IO HostName
getHostName = allocaArray0 size $ \cstr -> do
        throwErrnoIfMinus1_ "getHostName" $ gethostname cstr (fromIntegral size)
        peekCString cstr
    where size = 256
geekosaur commented 1 month ago

Probably re vendoring. Back then there were issues both with getting a hostname (on some systems you had to parse uname -a output) and with gethostname only working if the network was up, but in 2024 I'm not sure either problem exists any more. Suppose we'll find out.