1 (* Copyright (C
) 2011,2017 Matthew Fluet
.
2 * Copyright (C
) 1999-2008 Henry Cejtin
, Matthew Fluet
, Suresh
3 * Jagannathan
, and Stephen Weeks
.
4 * Copyright (C
) 1997-2000 NEC Research Institute
.
6 * MLton is released under a BSD
-style license
.
7 * See the file MLton
-LICENSE for details
.
10 structure PosixProcEnv
: POSIX_PROC_ENV
=
12 structure Prim
= PrimitiveFFI
.Posix
.ProcEnv
13 structure FileDesc
= PrePosix
.FileDesc
14 structure GId
= PrePosix
.GId
15 structure PId
= PrePosix
.PId
16 structure UId
= PrePosix
.UId
18 structure Error
= PosixError
19 structure SysCall
= Error
.SysCall
20 structure CS
= CUtil
.C_String
21 structure CSS
= CUtil
.C_StringArray
23 type file_desc
= FileDesc
.t
28 val uidToWord
= C_UId
.castToSysWord
o UId
.toRep
29 val wordToUid
= UId
.fromRep
o C_UId
.castFromSysWord
30 val gidToWord
= C_GId
.castToSysWord
o GId
.toRep
31 val wordToGid
= GId
.fromRep
o C_GId
.castFromSysWord
36 val getpgrp
= PId
.fromRep
o getpgrp (* No error checking required
*)
37 val getegid
= GId
.fromRep
o getegid (* No error checking required
*)
38 val geteuid
= UId
.fromRep
o geteuid (* No error checking required
*)
39 val getgid
= GId
.fromRep
o getgid (* No error checking required
*)
40 val getpid
= PId
.fromRep
o getpid (* No error checking required
*)
41 val getppid
= PId
.fromRep
o getppid (* No error checking required
*)
42 val getuid
= UId
.fromRep
o getuid (* No error checking required
*)
43 val setgid
= fn gid
=> let val gid
= GId
.toRep gid
44 in SysCall
.simple (fn () => setgid gid
)
46 val setuid
= fn uid
=> let val uid
= UId
.toRep uid
47 in SysCall
.simple (fn () => setuid uid
)
52 (PId
.fromRep
o SysCall
.simpleResult
')
53 ({errVal
= C_PId
.castFromFixedInt ~
1}, Prim
.setsid
)
59 val n
= Prim
.getgroupsN ()
60 val a
: C_GId
.t array
= Array
.alloc (C_Int
.toInt n
)
62 (Prim
.getgroups (n
, a
), fn n
=>
63 (GId
.listFromRep
o ArraySlice
.toList
)
64 (ArraySlice
.slice (a
, 0, SOME (C_Int
.toInt n
))))
69 ({errVal
= CUtil
.C_Pointer
.null
}, fn () =>
70 (Prim
.getlogin (), fn cs
=>
73 fun setpgid
{pid
, pgid
} =
75 val pid
= case pid
of NONE
=> 0 | SOME pid
=> PId
.toRep pid
76 val pgid
= case pgid
of NONE
=> 0 | SOME pgid
=> PId
.toRep pgid
79 (fn () => Prim
.setpgid (pid
, pgid
))
85 (Prim
.uname (), fn _
=>
86 [("sysname", CS
.toString (Prim
.Uname
.getSysName ())),
87 ("nodename", CS
.toString (Prim
.Uname
.getNodeName ())),
88 ("release", CS
.toString (Prim
.Uname
.getRelease ())),
89 ("version", CS
.toString (Prim
.Uname
.getVersion ())),
90 ("machine", CS
.toString (Prim
.Uname
.getMachine ()))]))
98 if n
= C_Int
.fromInt ~
1
103 (Prim
.SC_2_CHAR_TERM
,"2_CHAR_TERM") ::?
104 (Prim
.SC_2_C_BIND
,"2_C_BIND") ::?
105 (Prim
.SC_2_C_DEV
,"2_C_DEV") ::?
106 (Prim
.SC_2_FORT_DEV
,"2_FORT_DEV") ::?
107 (Prim
.SC_2_FORT_RUN
,"2_FORT_RUN") ::?
108 (Prim
.SC_2_LOCALEDEF
,"2_LOCALEDEF") ::?
109 (Prim
.SC_2_PBS
,"2_PBS") ::?
110 (Prim
.SC_2_PBS_ACCOUNTING
,"2_PBS_ACCOUNTING") ::?
111 (Prim
.SC_2_PBS_CHECKPOINT
,"2_PBS_CHECKPOINT") ::?
112 (Prim
.SC_2_PBS_LOCATE
,"2_PBS_LOCATE") ::?
113 (Prim
.SC_2_PBS_MESSAGE
,"2_PBS_MESSAGE") ::?
114 (Prim
.SC_2_PBS_TRACK
,"2_PBS_TRACK") ::?
115 (Prim
.SC_2_SW_DEV
,"2_SW_DEV") ::?
116 (Prim
.SC_2_UPE
,"2_UPE") ::?
117 (Prim
.SC_2_VERSION
,"2_VERSION") ::?
118 (Prim
.SC_ADVISORY_INFO
,"ADVISORY_INFO") ::?
119 (Prim
.SC_AIO_LISTIO_MAX
,"AIO_LISTIO_MAX") ::?
120 (Prim
.SC_AIO_MAX
,"AIO_MAX") ::?
121 (Prim
.SC_AIO_PRIO_DELTA_MAX
,"AIO_PRIO_DELTA_MAX") ::?
122 (Prim
.SC_ARG_MAX
,"ARG_MAX") ::?
123 (Prim
.SC_ASYNCHRONOUS_IO
,"ASYNCHRONOUS_IO") ::?
124 (Prim
.SC_ATEXIT_MAX
,"ATEXIT_MAX") ::?
125 (Prim
.SC_AVPHYS_PAGES
,"AVPHYS_PAGES") ::?
126 (Prim
.SC_BARRIERS
,"BARRIERS") ::?
127 (Prim
.SC_BC_BASE_MAX
,"BC_BASE_MAX") ::?
128 (Prim
.SC_BC_DIM_MAX
,"BC_DIM_MAX") ::?
129 (Prim
.SC_BC_SCALE_MAX
,"BC_SCALE_MAX") ::?
130 (Prim
.SC_BC_STRING_MAX
,"BC_STRING_MAX") ::?
131 (Prim
.SC_CHILD_MAX
,"CHILD_MAX") ::?
132 (Prim
.SC_CLK_TCK
,"CLK_TCK") ::?
133 (Prim
.SC_CLOCK_SELECTION
,"CLOCK_SELECTION") ::?
134 (Prim
.SC_COLL_WEIGHTS_MAX
,"COLL_WEIGHTS_MAX") ::?
135 (Prim
.SC_CPUTIME
,"CPUTIME") ::?
136 (Prim
.SC_DELAYTIMER_MAX
,"DELAYTIMER_MAX") ::?
137 (Prim
.SC_EXPR_NEST_MAX
,"EXPR_NEST_MAX") ::?
138 (Prim
.SC_FSYNC
,"FSYNC") ::?
139 (Prim
.SC_GETGR_R_SIZE_MAX
,"GETGR_R_SIZE_MAX") ::?
140 (Prim
.SC_GETPW_R_SIZE_MAX
,"GETPW_R_SIZE_MAX") ::?
141 (Prim
.SC_HOST_NAME_MAX
,"HOST_NAME_MAX") ::?
142 (Prim
.SC_IOV_MAX
,"IOV_MAX") ::?
143 (Prim
.SC_IPV6
,"IPV6") ::?
144 (Prim
.SC_JOB_CONTROL
,"JOB_CONTROL") ::?
145 (Prim
.SC_LINE_MAX
,"LINE_MAX") ::?
146 (Prim
.SC_LOGIN_NAME_MAX
,"LOGIN_NAME_MAX") ::?
147 (Prim
.SC_MAPPED_FILES
,"MAPPED_FILES") ::?
148 (Prim
.SC_MEMLOCK
,"MEMLOCK") ::?
149 (Prim
.SC_MEMLOCK_RANGE
,"MEMLOCK_RANGE") ::?
150 (Prim
.SC_MEMORY_PROTECTION
,"MEMORY_PROTECTION") ::?
151 (Prim
.SC_MESSAGE_PASSING
,"MESSAGE_PASSING") ::?
152 (Prim
.SC_MONOTONIC_CLOCK
,"MONOTONIC_CLOCK") ::?
153 (Prim
.SC_MQ_OPEN_MAX
,"MQ_OPEN_MAX") ::?
154 (Prim
.SC_MQ_PRIO_MAX
,"MQ_PRIO_MAX") ::?
155 (Prim
.SC_NGROUPS_MAX
,"NGROUPS_MAX") ::?
156 (Prim
.SC_NPROCESSORS_CONF
,"NPROCESSORS_CONF") ::?
157 (Prim
.SC_NPROCESSORS_ONLN
,"NPROCESSORS_ONLN") ::?
158 (Prim
.SC_OPEN_MAX
,"OPEN_MAX") ::?
159 (Prim
.SC_PAGESIZE
,"PAGESIZE") ::?
160 (Prim
.SC_PAGE_SIZE
,"PAGE_SIZE") ::?
161 (Prim
.SC_PHYS_PAGES
,"PHYS_PAGES") ::?
162 (Prim
.SC_PRIORITIZED_IO
,"PRIORITIZED_IO") ::?
163 (Prim
.SC_PRIORITY_SCHEDULING
,"PRIORITY_SCHEDULING") ::?
164 (Prim
.SC_RAW_SOCKETS
,"RAW_SOCKETS") ::?
165 (Prim
.SC_READER_WRITER_LOCKS
,"READER_WRITER_LOCKS") ::?
166 (Prim
.SC_REALTIME_SIGNALS
,"REALTIME_SIGNALS") ::?
167 (Prim
.SC_REGEXP
,"REGEXP") ::?
168 (Prim
.SC_RE_DUP_MAX
,"RE_DUP_MAX") ::?
169 (Prim
.SC_RTSIG_MAX
,"RTSIG_MAX") ::?
170 (Prim
.SC_SAVED_IDS
,"SAVED_IDS") ::?
171 (Prim
.SC_SEMAPHORES
,"SEMAPHORES") ::?
172 (Prim
.SC_SEM_NSEMS_MAX
,"SEM_NSEMS_MAX") ::?
173 (Prim
.SC_SEM_VALUE_MAX
,"SEM_VALUE_MAX") ::?
174 (Prim
.SC_SHARED_MEMORY_OBJECTS
,"SHARED_MEMORY_OBJECTS") ::?
175 (Prim
.SC_SHELL
,"SHELL") ::?
176 (Prim
.SC_SIGQUEUE_MAX
,"SIGQUEUE_MAX") ::?
177 (Prim
.SC_SPAWN
,"SPAWN") ::?
178 (Prim
.SC_SPIN_LOCKS
,"SPIN_LOCKS") ::?
179 (Prim
.SC_SPORADIC_SERVER
,"SPORADIC_SERVER") ::?
180 (Prim
.SC_SS_REPL_MAX
,"SS_REPL_MAX") ::?
181 (Prim
.SC_STREAM_MAX
,"STREAM_MAX") ::?
182 (Prim
.SC_SYMLOOP_MAX
,"SYMLOOP_MAX") ::?
183 (Prim
.SC_SYNCHRONIZED_IO
,"SYNCHRONIZED_IO") ::?
184 (Prim
.SC_THREADS
,"THREADS") ::?
185 (Prim
.SC_THREAD_ATTR_STACKADDR
,"THREAD_ATTR_STACKADDR") ::?
186 (Prim
.SC_THREAD_ATTR_STACKSIZE
,"THREAD_ATTR_STACKSIZE") ::?
187 (Prim
.SC_THREAD_CPUTIME
,"THREAD_CPUTIME") ::?
188 (Prim
.SC_THREAD_DESTRUCTOR_ITERATIONS
,"THREAD_DESTRUCTOR_ITERATIONS") ::?
189 (Prim
.SC_THREAD_KEYS_MAX
,"THREAD_KEYS_MAX") ::?
190 (Prim
.SC_THREAD_PRIORITY_SCHEDULING
,"THREAD_PRIORITY_SCHEDULING") ::?
191 (Prim
.SC_THREAD_PRIO_INHERIT
,"THREAD_PRIO_INHERIT") ::?
192 (Prim
.SC_THREAD_PRIO_PROTECT
,"THREAD_PRIO_PROTECT") ::?
193 (Prim
.SC_THREAD_PROCESS_SHARED
,"THREAD_PROCESS_SHARED") ::?
194 (Prim
.SC_THREAD_SAFE_FUNCTIONS
,"THREAD_SAFE_FUNCTIONS") ::?
195 (Prim
.SC_THREAD_SPORADIC_SERVER
,"THREAD_SPORADIC_SERVER") ::?
196 (Prim
.SC_THREAD_STACK_MIN
,"THREAD_STACK_MIN") ::?
197 (Prim
.SC_THREAD_THREADS_MAX
,"THREAD_THREADS_MAX") ::?
198 (Prim
.SC_TIMEOUTS
,"TIMEOUTS") ::?
199 (Prim
.SC_TIMERS
,"TIMERS") ::?
200 (Prim
.SC_TIMER_MAX
,"TIMER_MAX") ::?
201 (Prim
.SC_TRACE
,"TRACE") ::?
202 (Prim
.SC_TRACE_EVENT_FILTER
,"TRACE_EVENT_FILTER") ::?
203 (Prim
.SC_TRACE_EVENT_NAME_MAX
,"TRACE_EVENT_NAME_MAX") ::?
204 (Prim
.SC_TRACE_INHERIT
,"TRACE_INHERIT") ::?
205 (Prim
.SC_TRACE_LOG
,"TRACE_LOG") ::?
206 (Prim
.SC_TRACE_NAME_MAX
,"TRACE_NAME_MAX") ::?
207 (Prim
.SC_TRACE_SYS_MAX
,"TRACE_SYS_MAX") ::?
208 (Prim
.SC_TRACE_USER_EVENT_MAX
,"TRACE_USER_EVENT_MAX") ::?
209 (Prim
.SC_TTY_NAME_MAX
,"TTY_NAME_MAX") ::?
210 (Prim
.SC_TYPED_MEMORY_OBJECTS
,"TYPED_MEMORY_OBJECTS") ::?
211 (Prim
.SC_TZNAME_MAX
,"TZNAME_MAX") ::?
212 (Prim
.SC_V6_ILP32_OFF32
,"V6_ILP32_OFF32") ::?
213 (Prim
.SC_V6_ILP32_OFFBIG
,"V6_ILP32_OFFBIG") ::?
214 (Prim
.SC_V6_LP64_OFF64
,"V6_LP64_OFF64") ::?
215 (Prim
.SC_V6_LPBIG_OFFBIG
,"V6_LPBIG_OFFBIG") ::?
216 (Prim
.SC_VERSION
,"VERSION") ::?
217 (Prim
.SC_XBS5_ILP32_OFF32
,"XBS5_ILP32_OFF32") ::?
218 (Prim
.SC_XBS5_ILP32_OFFBIG
,"XBS5_ILP32_OFFBIG") ::?
219 (Prim
.SC_XBS5_LP64_OFF64
,"XBS5_LP64_OFF64") ::?
220 (Prim
.SC_XBS5_LPBIG_OFFBIG
,"XBS5_LPBIG_OFFBIG") ::?
221 (Prim
.SC_XOPEN_CRYPT
,"XOPEN_CRYPT") ::?
222 (Prim
.SC_XOPEN_ENH_I18N
,"XOPEN_ENH_I18N") ::?
223 (Prim
.SC_XOPEN_LEGACY
,"XOPEN_LEGACY") ::?
224 (Prim
.SC_XOPEN_REALTIME
,"XOPEN_REALTIME") ::?
225 (Prim
.SC_XOPEN_REALTIME_THREADS
,"XOPEN_REALTIME_THREADS") ::?
226 (Prim
.SC_XOPEN_SHM
,"XOPEN_SHM") ::?
227 (Prim
.SC_XOPEN_STREAMS
,"XOPEN_STREAMS") ::?
228 (Prim
.SC_XOPEN_UNIX
,"XOPEN_UNIX") ::?
229 (Prim
.SC_XOPEN_VERSION
,"XOPEN_VERSION") ::?
234 case List.find (fn (_
, s
') => s
= s
') sysconfNames
of
235 NONE
=> Error
.raiseSys Error
.inval
237 (SysWord
.fromLargeInt
o C_Long
.toLarge
o SysCall
.simpleResult
')
238 ({errVal
= C_Long
.fromInt ~
1}, fn () => Prim
.sysconf n
)
242 structure Times
= Prim
.Times
245 (* syconf is not implemented on MinGW
;
246 * we don
't want a SysErr during Basis Library initialization
.
248 if (let open Primitive
.MLton
.Platform
.OS
in host
= MinGW
end)
250 else SysWord
.toLargeIntX (sysconf
"CLK_TCK")
252 fun cvt (clocks
: C_Clock
.t
) =
253 Time
.fromTicks (LargeInt
.quot
254 (LargeInt
.* (C_Clock
.toLargeInt clocks
,
255 Time
.ticksPerSecond
),
260 ({errVal
= C_Clock
.castFromFixedInt ~
1}, fn () =>
261 (Prim
.times (), fn elapsed
=>
262 {elapsed
= cvt elapsed
,
263 utime
= cvt (Times
.getUTime ()),
264 stime
= cvt (Times
.getSTime ()),
265 cutime
= cvt (Times
.getCUTime ()),
266 cstime
= cvt (Times
.getCSTime ())}))
269 fun environ () = CSS
.toList (Prim
.environGet ())
273 val cs
= Prim
.getenv (NullString
.nullTerm name
)
275 if CUtil
.C_Pointer
.isNull cs
277 else SOME (CS
.toString cs
)
280 fun ctermid () = CS
.toString (Prim
.ctermid ())
282 fun isatty fd
= (Prim
.isatty (FileDesc
.toRep fd
)) <> C_Int
.zero
286 ({errVal
= CUtil
.C_Pointer
.null
}, fn () =>
287 (Prim
.ttyname (FileDesc
.toRep fd
), fn cs
=>