Skip to content

Commit 0fd1b59

Browse files
Add a module for the "id" coreutil
1 parent b75664a commit 0fd1b59

2 files changed

Lines changed: 144 additions & 0 deletions

File tree

src/Streamly/Coreutils/Id.hs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
-- |
2+
-- Module : Streamly.Coreutils.Id
3+
-- Copyright : (c) 2022 Composewell Technologies
4+
-- License : BSD-3-Clause
5+
-- Maintainer : streamly@composewell.com
6+
-- Stability : experimental
7+
-- Portability : GHC
8+
--
9+
-- Experimental alternative wrapper API over System.Posix.User.
10+
--
11+
-- Shorter names, closer to shell commands.
12+
-- Int for user-id/group-id for covnenience.
13+
-- Adds one missing function
14+
--
15+
-- Functions to get and set the user and group id of the current process.
16+
--
17+
-- Substitutes the functionality of the @id@ and @whoami@ coreutils commands.
18+
--
19+
-- This is a Posix only module.
20+
21+
-- TODO: create a portable module with "idNum" and "idName" commands to print
22+
-- the current user id, name.
23+
--
24+
-- Can separate process API and the user DB API.
25+
26+
module Streamly.Coreutils.Id
27+
(
28+
uid
29+
, euid
30+
, gid
31+
, egid
32+
, uid2name
33+
, gid2name
34+
-- , groups
35+
)
36+
where
37+
38+
import System.Posix (getGroupEntryForID)
39+
import Prelude hiding (id)
40+
import qualified System.Posix.User as Posix
41+
42+
------------------------------------------------------
43+
-- Current process settings
44+
------------------------------------------------------
45+
46+
-- | Return current process real user id.
47+
--
48+
-- id -ru
49+
uid :: IO Int
50+
uid = fromIntegral <$> Posix.getRealUserID
51+
52+
-- | Return current process real group id.
53+
--
54+
-- id -rg
55+
gid :: IO Int
56+
gid = fromIntegral <$> Posix.getRealGroupID
57+
58+
-- | Return current process effective user id.
59+
--
60+
-- id -u
61+
euid :: IO Int
62+
euid = fromIntegral <$> Posix.getEffectiveUserID
63+
64+
-- | Return current process effective group id.
65+
--
66+
-- id -g
67+
egid :: IO Int
68+
egid = fromIntegral <$> Posix.getEffectiveGroupID
69+
70+
-- | Get groups associated with the current process.
71+
--
72+
-- id -G
73+
groups :: IO [Int]
74+
groups = fmap fromIntegral <$> Posix.getGroups
75+
76+
-- | The original login name of the process. Note: the current user name may
77+
-- change by setuid but login name remains the same.
78+
logname :: IO String
79+
logname = Posix.getLoginName
80+
81+
------------------------------------------------------
82+
-- These should go to user database module?
83+
------------------------------------------------------
84+
85+
-- XXX We can parse the passwd file ourselves instead of using C code
86+
-- XXX Use an Compact Array/OsString instead?
87+
88+
{-
89+
-- getpwuid
90+
uid2pwent =
91+
92+
-- getgrgid
93+
gid2grent =
94+
95+
-- getpwnam
96+
name2pwent =
97+
98+
-- getgrnam
99+
name2grent =
100+
101+
-- Stream the entries.
102+
getpwents =
103+
-}
104+
105+
-- | Convert numeric user id to user name.
106+
uid2name :: Int -> IO String
107+
uid2name i = do
108+
-- XXX fromIntegral downcast
109+
pw <- Posix.getUserEntryForID (fromIntegral i)
110+
return (Posix.userName pw)
111+
112+
-- XXX Use an Compact Array/OsString instead?
113+
114+
-- | Convert numeric group id to group name.
115+
gid2name :: Int -> IO String
116+
gid2name i = do
117+
-- XXX fromIntegral downcast
118+
pw <- Posix.getGroupEntryForID (fromIntegral i)
119+
return (Posix.groupName pw)
120+
121+
-- Note there is no uid2groups as anyway the groups file has the user name. We
122+
-- search by name even if uid is provided. So we can convert uid to name and
123+
-- then search.
124+
125+
-- | List all the groups in which a uid occurs. Returns (gid, group name).
126+
--
127+
-- id -Gn <user>
128+
user2groups :: Int -> [(Int, String)]
129+
user2groups = undefined
130+
131+
-- | Current process user name.
132+
--
133+
-- id -un
134+
whoami :: IO String
135+
whoami = uid >>= uid2name
136+
137+
-- | Current process group names.
138+
--
139+
-- id -Gn
140+
groupNames :: IO [String]
141+
groupNames = do
142+
xs <- Posix.getGroups
143+
fmap Posix.groupName <$> mapM getGroupEntryForID xs

streamly-coreutils.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ library
124124
, Streamly.Coreutils.Directory
125125
, Streamly.Coreutils.Dirname
126126
, Streamly.Coreutils.FileTest
127+
, Streamly.Coreutils.Id
127128
, Streamly.Coreutils.Ln
128129
, Streamly.Coreutils.Cut
129130
, Streamly.Coreutils.Ls

0 commit comments

Comments
 (0)