[project @ 2000-01-05 11:14:06 by rrt]
[ghc-hetmet.git] / ghc / docs / users_guide / posix.sgml
1 <Sect1 id="Posix-library">
2 <Title>The Posix library
3 </Title>
4
5 <Para>
6 <IndexTerm><Primary>Posix library</Primary></IndexTerm>
7 <IndexTerm><Primary>libraries, Posix</Primary></IndexTerm>
8 </Para>
9
10 <Para>
11 The <Literal>Posix</Literal> interface gives you access to the set of OS
12 services standardised by POSIX 1003.1b (or the <Emphasis>IEEE Portable
13 Operating System Interface for Computing Environments</Emphasis> - IEEE Std.
14 1003.1). The interface is accessed by <Literal>import Posix</Literal> and
15 adding <Literal>-syslib posix</Literal> on your command-line.
16 </Para>
17
18 <Sect2 id="Posix-data-types">
19 <Title>Posix data types
20 </Title>
21
22 <Para>
23 <IndexTerm><Primary>Posix, data types</Primary></IndexTerm>
24 </Para>
25
26 <Para>
27
28 <ProgramListing>
29 data ByteCount  -- instances of : Eq Ord Num Real Integral Ix Enum Show
30 </ProgramListing>
31
32 </Para>
33
34 <Para>
35 A <Literal>ByteCount</Literal> is a primitive of type <Literal>unsigned</Literal>. At a minimum,
36 an conforming implementation must support values in the range
37 <Literal>[0, UINT&lowbar;MAX]</Literal>.
38 </Para>
39
40 <Para>
41
42 <ProgramListing>
43 data ClockTick  -- instances of : Eq Ord Num Real Integral Ix Enum Show
44 </ProgramListing>
45
46 </Para>
47
48 <Para>
49 A <Literal>ClockTick</Literal> is a primitive of type <Literal>clock&lowbar;t</Literal>, which
50 is used to measure intervals of time in fractions of a second.  The 
51 resolution is determined by <Literal>getSysVar ClockTick</Literal>.
52 </Para>
53
54 <Para>
55
56 <ProgramListing>
57 data DeviceID  -- instances of : Eq Ord Num Real Integral Ix Enum Show
58 </ProgramListing>
59
60 </Para>
61
62 <Para>
63 A <Literal>DeviceID</Literal> is a primitive of type <Literal>dev&lowbar;t</Literal>.  It must
64 be an arithmetic type.
65 </Para>
66
67 <Para>
68
69 <ProgramListing>
70 data EpochTime -- instances of : Eq Ord Num Real Integral Ix Enum Show
71 </ProgramListing>
72
73 </Para>
74
75 <Para>
76 A <Literal>EpochTime</Literal> is a primitive of type <Literal>time&lowbar;t</Literal>, which is
77 used to measure seconds since the Epoch.  At a minimum, the implementation 
78 must support values in the range <Literal>[0, INT&lowbar;MAX]</Literal>.
79 </Para>
80
81 <Para>
82
83 <ProgramListing>
84 data FileID -- instances of : Eq Ord Num Real Integral Ix Enum Show
85 </ProgramListing>
86
87 </Para>
88
89 <Para>
90 A <Literal>FileID</Literal> is a primitive of type <Literal>ino&lowbar;t</Literal>.  It must
91 be an arithmetic type.
92 </Para>
93
94 <Para>
95
96 <ProgramListing>
97 data FileMode -- instances of : Eq Ord Num Real Integral Ix Enum Show
98 </ProgramListing>
99
100 </Para>
101
102 <Para>
103 A <Literal>FileMode</Literal> is a primitive of type <Literal>mode&lowbar;t</Literal>.
104 It must be an arithmetic type.
105 </Para>
106
107 <Para>
108
109 <ProgramListing>
110 data FileOffset -- instances of : Eq Ord Num Real Integral Ix Enum Show
111 </ProgramListing>
112
113 </Para>
114
115 <Para>
116 A <Literal>FileOffset</Literal> is a primitive of type <Literal>off&lowbar;t</Literal>.  It must
117 be an arithmetic type.
118 </Para>
119
120 <Para>
121
122 <ProgramListing>
123 data GroupID -- instances of : Eq Ord Num Real Integral Ix Enum Show
124 </ProgramListing>
125
126 </Para>
127
128 <Para>
129 A <Literal>GroupID</Literal> is a primitive of type <Literal>gid&lowbar;t</Literal>.  It must
130 be an arithmetic type.
131
132 <ProgramListing>
133 data Limit -- instances of : Eq Ord Num Real Integral Ix Enum Show
134 </ProgramListing>
135
136 </Para>
137
138 <Para>
139 A <Literal>Limit</Literal> is a primitive of type <Literal>long</Literal>.
140 At a minimum, the implementation must support values in the range 
141 <Literal>[LONG&lowbar;MIN, LONG&lowbar;MAX]</Literal>.
142 </Para>
143
144 <Para>
145
146 <ProgramListing>
147 data LinkCount -- instances of : Eq Ord Num Real Integral Ix Enum Show
148 </ProgramListing>
149
150 </Para>
151
152 <Para>
153 A <Literal>LinkCount</Literal> is a primitive of type <Literal>nlink&lowbar;t</Literal>.  It must
154 be an arithmetic type.
155 </Para>
156
157 <Para>
158
159 <ProgramListing>
160 data ProcessID -- instances of : Eq Ord Num Real Integral Ix Enum Show
161 type ProcessGroupID = ProcessID
162 </ProgramListing>
163
164 </Para>
165
166 <Para>
167 A <Literal>ProcessID</Literal> is a primitive of type <Literal>pid&lowbar;t</Literal>.  It
168 must be a signed arithmetic type.
169
170 <ProgramListing>
171 data UserID -- instances of : Eq Ord Num Real Integral Ix Enum Show
172 </ProgramListing>
173
174 </Para>
175
176 <Para>
177 A <Literal>UserID</Literal> is a primitive of type <Literal>uid&lowbar;t</Literal>.  It
178 must be an arithmetic type.
179 </Para>
180
181 <Para>
182
183 <ProgramListing>
184 data DirStream
185 </ProgramListing>
186
187 A <Literal>DirStream</Literal> is a primitive of type <Literal>DIR *</Literal>.
188 </Para>
189
190 <Para>
191
192 <ProgramListing>
193 data FileStatus
194 </ProgramListing>
195
196 A <Literal>FileStatus</Literal> is a primitive of type <Literal>struct stat</Literal>.
197 </Para>
198
199 <Para>
200
201 <ProgramListing>
202 data GroupEntry
203 </ProgramListing>
204
205 </Para>
206
207 <Para>
208 A <Literal>GroupEntry</Literal> is a primitive of type <Literal>struct group</Literal>.
209
210 <ProgramListing>
211 data ProcessTimes
212 </ProgramListing>
213
214 </Para>
215
216 <Para>
217 <Literal>ProcessTimes</Literal> is a primitive structure containing a
218 <Literal>clock&lowbar;t</Literal> and a <Literal>struct tms</Literal>.
219 </Para>
220
221 <Para>
222
223 <ProgramListing>
224 data SignalSet
225 </ProgramListing>
226
227 </Para>
228
229 <Para>
230 An <Literal>SignalSet</Literal> is a primitive of type <Literal>sigset&lowbar;t</Literal>.
231 </Para>
232
233 <Para>
234
235 <ProgramListing>
236 data SystemID
237 </ProgramListing>
238
239 </Para>
240
241 <Para>
242 A <Literal>SystemID</Literal> is a primitive of type <Literal>struct utsname</Literal>.
243 </Para>
244
245 <Para>
246
247 <ProgramListing>
248 data TerminalAttributes
249 </ProgramListing>
250
251 <Literal>TerminalAttributes</Literal> is a primitive of type <Literal>struct termios</Literal>.
252 </Para>
253
254 <Para>
255
256 <ProgramListing>
257 data UserEntry
258 </ProgramListing>
259
260 </Para>
261
262 <Para>
263 A <Literal>UserEntry</Literal> is a primitive of type <Literal>struct passwd</Literal>.
264 </Para>
265
266 <Para>
267
268 <ProgramListing>
269 data BaudRate = B0 | B50 | B75 | B110 | B134 | B150 | B200 | B300 | B600
270               | B1200 | B1800 | B2400 | B4800 | B9600 | B19200 | B38400
271               deriving (Eq, Show)
272
273 data Fd 
274
275 intToFd :: Int -&#62; Fd -- use with care.
276
277 data FdOption = AppendOnWrite
278               | CloseOnExec
279               | NonBlockingRead
280
281 data ControlCharacter = EndOfFile
282                       | EndOfLine
283                       | Erase
284                       | Interrupt
285                       | Kill
286                       | Quit
287                       | Suspend
288                       | Start
289                       | Stop
290
291 type ErrorCode = Int
292
293 type FileLock = (LockRequest, SeekMode, FileOffset, FileOffset)
294 --                            whence    start       length
295
296 data FlowAction = SuspendOutput | RestartOutput | TransmitStop | TransmitStart
297
298 data Handler = Default | Ignore | Catch (IO ())
299
300 data LockRequest = ReadLock | WriteLock | Unlock
301                  deriving (Eq, Show)
302
303 data OpenMode = ReadOnly | WriteOnly | ReadWrite
304
305 data PathVar = LinkLimit
306              | InputLineLimit
307              | InputQueueLimit
308              | FileNameLimit
309              | PathNameLimit
310              | PipeBufferLimit
311              | SetOwnerAndGroupIsRestricted
312              | FileNamesAreNotTruncated
313
314 data QueueSelector = InputQueue | OutputQueue | BothQueues
315
316 type Signal = Int
317
318 data SysVar = ArgumentLimit
319             | ChildLimit
320             | ClockTick
321             | GroupLimit
322             | OpenFileLimit
323             | PosixVersion
324             | HasSavedIDs
325             | HasJobControl
326
327 data TerminalMode = InterruptOnBreak       -- BRKINT
328                 | MapCRtoLF                -- ICRNL
329                 | IgnoreBreak              -- IGNBRK
330                 | IgnoreCR                 -- IGNCR
331                 | IgnoreParityErrors       -- IGNPAR
332                 | MapLFtoCR                -- INLCR
333                 | CheckParity              -- INPCK
334                 | StripHighBit             -- ISTRIP
335                 | StartStopInput           -- IXOFF
336                 | StartStopOutput          -- IXON
337                 | MarkParityErrors         -- PARMRK
338                 | ProcessOutput            -- OPOST
339                 | LocalMode                -- CLOCAL
340                 | ReadEnable               -- CREAD
341                 | TwoStopBits              -- CSTOPB
342                 | HangupOnClose            -- HUPCL
343                 | EnableParity             -- PARENB
344                 | OddParity                -- PARODD
345                 | EnableEcho               -- ECHO
346                 | EchoErase                -- ECHOE
347                 | EchoKill                 -- ECHOK
348                 | EchoLF                   -- ECHONL
349                 | ProcessInput             -- ICANON
350                 | ExtendedFunctions        -- IEXTEN
351                 | KeyboardInterrupts       -- ISIG
352                 | NoFlushOnInterrupt       -- NOFLSH
353                 | BackgroundWriteInterrupt -- TOSTOP
354
355 data TerminalState = Immediately | WhenDrained | WhenFlushed
356
357 data ProcessStatus = Exited ExitCode 
358                    | Terminated Signal 
359                    | Stopped Signal
360                    deriving (Eq, Show)
361 </ProgramListing>
362
363 </Para>
364
365 </Sect2>
366
367 <Sect2 id="Process-Primitives">
368 <Title>Posix Process Primitives
369 </Title>
370
371 <Para>
372
373 <ProgramListing>
374 forkProcess :: IO (Maybe ProcessID)
375 </ProgramListing>
376
377 </Para>
378
379 <Para>
380 <Literal>forkProcess</Literal> calls <Literal>fork</Literal>, returning
381 <Literal>Just pid</Literal> to the parent, where <Literal>pid</Literal> is the
382 ProcessID of the child, and returning <Literal>Nothing</Literal> to the
383 child.
384 </Para>
385
386 <Para>
387
388 <ProgramListing>
389 executeFile :: FilePath                   -- Command
390             -&#62; Bool                       -- Search PATH?
391             -&#62; [String]                   -- Arguments
392             -&#62; Maybe [(String, String)]   -- Environment
393             -&#62; IO ()
394 </ProgramListing>
395
396 </Para>
397
398 <Para>
399 <Literal>executeFile cmd args env</Literal> calls one of the
400 <Literal>execv*</Literal> family, depending on whether or not the current
401 PATH is to be searched for the command, and whether or not an
402 environment is provided to supersede the process's current
403 environment.  The basename (leading directory names suppressed) of
404 the command is passed to <Literal>execv*</Literal> as <Literal>arg[0]</Literal>;
405 the argument list passed to <Literal>executeFile</Literal> therefore begins 
406 with <Literal>arg[1]</Literal>.
407 </Para>
408
409 <Para>
410
411 <Screen>
412 Search PATH?    Supersede environ?      Call
413 ~~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~~      ~~~~~~~
414 False           False                   execv
415 False           True                    execve
416 True            False                   execvp
417 True            True                    execvpe*
418 </Screen>
419
420 </Para>
421
422 <Para>
423 Note that <Literal>execvpe</Literal> is not provided by the POSIX standard, and must
424 be written by hand.  Care must be taken to ensure that the search path
425 is extracted from the original environment, and not from the
426 environment to be passed on to the new image.
427 </Para>
428
429 <Para>
430 NOTE: In general, sharing open files between parent and child
431 processes is potential bug farm, and should be avoided unless you
432 really depend on this `feature' of POSIX' <Literal>fork()</Literal> semantics. Using
433 Haskell, there's the extra complication that arguments to
434 <Literal>executeFile</Literal> might come from files that are read lazily (using
435 <Literal>hGetContents</Literal>, or some such.) If this is the case, then for your own
436 sanity, please ensure that the arguments to <Literal>executeFile</Literal> have been
437 fully evaluated before calling <Literal>forkProcess</Literal> (followed by
438 <Literal>executeFile</Literal>.) Consider yourself warned :-)
439 </Para>
440
441 <Para>
442 A successful <Literal>executeFile</Literal> overlays the current process image with 
443 a new one, so it only returns on failure.
444 </Para>
445
446 <Para>
447
448 <ProgramListing>
449 runProcess :: FilePath                    -- Command
450            -&#62; [String]                    -- Arguments
451            -&#62; Maybe [(String, String)]    -- Environment (Nothing -&#62; Inherited)
452            -&#62; Maybe FilePath              -- Working directory (Nothing -&#62; inherited)
453            -&#62; Maybe Handle                -- stdin  (Nothing -&#62; inherited)
454            -&#62; Maybe Handle                -- stdout (Nothing -&#62; inherited)
455            -&#62; Maybe Handle                -- stderr (Nothing -&#62; inherited)
456            -&#62; IO ()
457 </ProgramListing>
458
459 </Para>
460
461 <Para>
462 <Literal>runProcess</Literal> is our candidate for the high-level OS-independent
463 primitive.
464 </Para>
465
466 <Para>
467 <Literal>runProcess cmd args env wd inhdl outhdl errhdl</Literal> runs <Literal>cmd</Literal>
468 (searching the current <Literal>PATH</Literal>) with arguments <Literal>args</Literal>.  If
469 <Literal>env</Literal> is <Literal>Just pairs</Literal>, the command is executed with the
470 environment specified by <Literal>pairs</Literal> of variables and values;
471 otherwise, the command is executed with the current environment.  If
472 <Literal>wd</Literal> is <Literal>Just dir</Literal>, the command is executed with working
473 directory <Literal>dir</Literal>; otherwise, the command is executed in the current
474 working directory.  If <Literal>&lcub;in,out,err</Literal>hdl&rcub; is <Literal>Just handle</Literal>, the
475 command is executed with the <Literal>Fd</Literal> for <Literal>std&lcub;in,out,err</Literal>&rcub;
476 attached to the specified <Literal>handle</Literal>; otherwise, the <Literal>Fd</Literal> for
477 <Literal>std&lcub;in,out,err</Literal>&rcub; is left unchanged.
478 </Para>
479
480 <Para>
481
482 <ProgramListing>
483 getProcessStatus :: Bool              -- Block?
484                  -&#62; Bool              -- Stopped processes?
485                  -&#62; ProcessID 
486                  -&#62; IO (Maybe ProcessStatus)
487 </ProgramListing>
488
489 </Para>
490
491 <Para>
492 <Literal>getProcessStatus blk stopped pid</Literal> calls <Literal>waitpid</Literal>, returning
493 <Literal>Just tc</Literal>, the <Literal>ProcessStatus</Literal> for process <Literal>pid</Literal> if it is
494 available, <Literal>Nothing</Literal> otherwise.  If <Literal>blk</Literal> is <Literal>False</Literal>, then
495 <Literal>WNOHANG</Literal> is set in the options for <Literal>waitpid</Literal>, otherwise not.
496 If <Literal>stopped</Literal> is <Literal>True</Literal>, then <Literal>WUNTRACED</Literal> is set in the
497 options for <Literal>waitpid</Literal>, otherwise not.
498 </Para>
499
500 <Para>
501
502 <ProgramListing>
503 getGroupProcessStatus :: Bool         -- Block?
504                       -&#62; Bool         -- Stopped processes?
505                       -&#62; ProcessGroupID 
506                       -&#62; IO (Maybe (ProcessID, ProcessStatus))
507 </ProgramListing>
508
509 </Para>
510
511 <Para>
512 <Literal>getGroupProcessStatus blk stopped pgid</Literal> calls <Literal>waitpid</Literal>,
513 returning <Literal>Just (pid, tc)</Literal>, the <Literal>ProcessID</Literal> and
514 <Literal>ProcessStatus</Literal> for any process in group <Literal>pgid</Literal> if one is
515 available, <Literal>Nothing</Literal> otherwise.  If <Literal>blk</Literal> is <Literal>False</Literal>, then
516 <Literal>WNOHANG</Literal> is set in the options for <Literal>waitpid</Literal>, otherwise not.
517 If <Literal>stopped</Literal> is <Literal>True</Literal>, then <Literal>WUNTRACED</Literal> is set in the
518 options for <Literal>waitpid</Literal>, otherwise not.
519 </Para>
520
521 <Para>
522
523 <ProgramListing>
524 getAnyProcessStatus :: Bool           -- Block?
525                     -&#62; Bool           -- Stopped processes?
526                     -&#62; IO (Maybe (ProcessID, ProcessStatus))
527 </ProgramListing>
528
529 </Para>
530
531 <Para>
532 <Literal>getAnyProcessStatus blk stopped</Literal> calls <Literal>waitpid</Literal>, returning
533 <Literal>Just (pid, tc)</Literal>, the <Literal>ProcessID</Literal> and <Literal>ProcessStatus</Literal> for any
534 child process if one is available, <Literal>Nothing</Literal> otherwise.  If
535 <Literal>blk</Literal> is <Literal>False</Literal>, then <Literal>WNOHANG</Literal> is set in the options for
536 <Literal>waitpid</Literal>, otherwise not.  If <Literal>stopped</Literal> is <Literal>True</Literal>, then
537 <Literal>WUNTRACED</Literal> is set in the options for <Literal>waitpid</Literal>, otherwise not.
538 </Para>
539
540 <Para>
541
542 <ProgramListing>
543 exitImmediately :: ExitCode -&#62; IO ()
544 </ProgramListing>
545
546 </Para>
547
548 <Para>
549 <Literal>exitImmediately status</Literal> calls <Literal>&lowbar;exit</Literal> to terminate the process
550 with the indicated exit <Literal>status</Literal>.
551 The operation never returns.
552 </Para>
553
554 <Para>
555
556 <ProgramListing>
557 getEnvironment :: IO [(String, String)]
558 </ProgramListing>
559
560 </Para>
561
562 <Para>
563 <Literal>getEnvironment</Literal> parses the environment variable mapping provided by
564 <Literal>environ</Literal>, returning <Literal>(variable, value)</Literal> pairs. 
565 The operation never fails.
566 </Para>
567
568 <Para>
569
570 <ProgramListing>
571 setEnvironment :: [(String, String)] -&#62; IO ()
572 </ProgramListing>
573
574 </Para>
575
576 <Para>
577 <Literal>setEnvironment</Literal> replaces the process environment with the provided
578 mapping of <Literal>(variable, value)</Literal> pairs. 
579 </Para>
580
581 <Para>
582
583 <ProgramListing>
584 getEnvVar :: String -&#62; IO String
585 </ProgramListing>
586
587 </Para>
588
589 <Para>
590 <Literal>getEnvVar var</Literal> returns the value associated with variable <Literal>var</Literal> 
591 in the current environment (identical functionality provided through
592 standard Haskell library function <Literal>System.getEnv</Literal>).
593 </Para>
594
595 <Para>
596 The operation may fail with:
597 </Para>
598
599 <Para>
600 <VariableList>
601
602 <VarListEntry>
603 <Term><Literal>NoSuchThing</Literal></Term>
604 <ListItem>
605 <Para>
606 The variable has no mapping in the current environment.
607 </Para>
608 </ListItem>
609 </VarListEntry>
610 </VariableList>
611 </Para>
612
613 <Para>
614
615 <ProgramListing>
616 setEnvVar :: String -&#62; String -&#62; IO ()
617 </ProgramListing>
618
619 </Para>
620
621 <Para>
622 <Literal>setEnvVar var val</Literal> sets the value associated with variable <Literal>var</Literal> 
623 in the current environment to be <Literal>val</Literal>.  Any previous mapping is 
624 superseded.
625 </Para>
626
627 <Para>
628
629 <ProgramListing>
630 removeEnvVar :: String -&#62; IO ()
631 </ProgramListing>
632
633 </Para>
634
635 <Para>
636 <Literal>removeEnvVar var</Literal> removes any value associated with variable <Literal>var</Literal> 
637 in the current environment.  Deleting a variable for which there is no mapping
638 does not generate an error.
639 </Para>
640
641 <Para>
642
643 <ProgramListing>
644 nullSignal :: Signal
645 nullSignal = 0
646
647 backgroundRead, sigTTIN        :: Signal
648 backgroundWrite, sigTTOU       :: Signal
649 continueProcess, sigCONT       :: Signal
650 floatingPointException, sigFPE :: Signal
651 illegalInstruction, sigILL     :: Signal
652 internalAbort, sigABRT         :: Signal
653 keyboardSignal, sigINT         :: Signal
654 keyboardStop, sigTSTP          :: Signal
655 keyboardTermination, sigQUIT   :: Signal
656 killProcess, sigKILL           :: Signal
657 lostConnection, sigHUP         :: Signal
658 openEndedPipe, sigPIPE         :: Signal
659 processStatusChanged, sigCHLD  :: Signal
660 realTimeAlarm, sigALRM         :: Signal
661 segmentationViolation, sigSEGV :: Signal
662 softwareStop, sigSTOP          :: Signal
663 softwareTermination, sigTERM   :: Signal
664 userDefinedSignal1, sigUSR1    :: Signal
665 userDefinedSignal2, sigUSR2    :: Signal
666
667 signalProcess :: Signal -&#62; ProcessID -&#62; IO ()
668 </ProgramListing>
669
670 </Para>
671
672 <Para>
673 <Literal>signalProcess int pid</Literal> calls <Literal>kill</Literal> to signal 
674 process <Literal>pid</Literal> with interrupt signal <Literal>int</Literal>.
675 </Para>
676
677 <Para>
678
679 <ProgramListing>
680 raiseSignal :: Signal -&#62; IO ()
681 </ProgramListing>
682
683 </Para>
684
685 <Para>
686 <Literal>raiseSignal int</Literal> calls <Literal>kill</Literal> to signal the current process
687 with interrupt signal <Literal>int</Literal>. 
688 </Para>
689
690 <Para>
691
692 <ProgramListing>
693 signalProcessGroup :: Signal -&#62; ProcessGroupID -&#62; IO ()
694 </ProgramListing>
695
696 </Para>
697
698 <Para>
699 <Literal>signalProcessGroup int pgid</Literal> calls <Literal>kill</Literal> to signal 
700 all processes in group <Literal>pgid</Literal> with interrupt signal <Literal>int</Literal>.
701 </Para>
702
703 <Para>
704
705 <ProgramListing>
706 setStoppedChildFlag :: Bool -&#62; IO Bool
707 </ProgramListing>
708
709 </Para>
710
711 <Para>
712 <Literal>setStoppedChildFlag bool</Literal> sets a flag which controls whether or
713 not the <Literal>NOCLDSTOP</Literal> option will be used the next time a signal
714 handler is installed for <Literal>SIGCHLD</Literal>.  If <Literal>bool</Literal> is <Literal>True</Literal> (the
715 default), <Literal>NOCLDSTOP</Literal> will not be used; otherwise it will be.  The
716 operation never fails.
717 </Para>
718
719 <Para>
720
721 <ProgramListing>
722 queryStoppedChildFlag :: IO Bool
723 </ProgramListing>
724
725 </Para>
726
727 <Para>
728 <Literal>queryStoppedChildFlag</Literal> queries the flag which
729 controls whether or not the <Literal>NOCLDSTOP</Literal> option will be used
730 the next time a signal handler is installed for <Literal>SIGCHLD</Literal>.
731 If <Literal>NOCLDSTOP</Literal> will be used, it returns <Literal>False</Literal>; 
732 otherwise (the default) it returns <Literal>True</Literal>.  
733 The operation never fails.
734 </Para>
735
736 <Para>
737
738 <ProgramListing>
739 emptySignalSet :: SignalSet
740 fullSignalSet  :: SignalSet
741 addSignal      :: Signal -&#62; SignalSet -&#62; SignalSet
742 deleteSignal   :: Signal -&#62; SignalSet -&#62; SignalSet
743 inSignalSet    :: Signal -&#62; SignalSet -&#62; Bool
744
745 installHandler :: Signal
746                -&#62; Handler 
747                -&#62; Maybe SignalSet       -- other signals to block
748                -&#62; IO Handler            -- old handler
749 </ProgramListing>
750
751 </Para>
752
753 <Para>
754 <Literal>installHandler int handler iset</Literal> calls <Literal>sigaction</Literal> to install an
755 interrupt handler for signal <Literal>int</Literal>.  If <Literal>handler</Literal> is <Literal>Default</Literal>,
756 <Literal>SIG&lowbar;DFL</Literal> is installed; if <Literal>handler</Literal> is <Literal>Ignore</Literal>, <Literal>SIG&lowbar;IGN</Literal> is
757 installed; if <Literal>handler</Literal> is <Literal>Catch action</Literal>, a handler is installed
758 which will invoke <Literal>action</Literal> in a new thread when (or shortly after) the
759 signal is received.  See <XRef LinkEnd="concurrent-haskell"> for details on how to communicate between
760 threads.
761 </Para>
762
763 <Para>
764 If <Literal>iset</Literal> is <Literal>Just s</Literal>, then the <Literal>sa&lowbar;mask</Literal> of the <Literal>sigaction</Literal> structure
765 is set to <Literal>s</Literal>; otherwise it is cleared.  The previously installed
766 signal handler for <Literal>int</Literal> is returned.
767 </Para>
768
769 <Para>
770
771 <ProgramListing>
772 getSignalMask :: IO SignalSet
773 </ProgramListing>
774
775 </Para>
776
777 <Para>
778 <Literal>getSignalMask</Literal> calls <Literal>sigprocmask</Literal> to determine the
779 set of interrupts which are currently being blocked.
780 </Para>
781
782 <Para>
783
784 <ProgramListing>
785 setSignalMask :: SignalSet -&#62; IO SignalSet
786 </ProgramListing>
787
788 </Para>
789
790 <Para>
791 <Literal>setSignalMask mask</Literal> calls <Literal>sigprocmask</Literal> with
792 <Literal>SIG&lowbar;SETMASK</Literal> to block all interrupts in <Literal>mask</Literal>.  The
793 previous set of blocked interrupts is returned.
794 </Para>
795
796 <Para>
797
798 <ProgramListing>
799 blockSignals :: SignalSet -&#62; IO SignalSet
800 </ProgramListing>
801
802 </Para>
803
804 <Para>
805 <Literal>setSignalMask mask</Literal> calls <Literal>sigprocmask</Literal> with
806 <Literal>SIG&lowbar;BLOCK</Literal> to add all interrupts in <Literal>mask</Literal> to the
807 set of blocked interrupts.  The previous set of blocked interrupts is returned.
808 </Para>
809
810 <Para>
811
812 <ProgramListing>
813 unBlockSignals :: SignalSet -&#62; IO SignalSet
814 </ProgramListing>
815
816 </Para>
817
818 <Para>
819 <Literal>setSignalMask mask</Literal> calls <Literal>sigprocmask</Literal> with
820 <Literal>SIG&lowbar;UNBLOCK</Literal> to remove all interrupts in <Literal>mask</Literal> from the
821 set of blocked interrupts.  The previous set of blocked interrupts is returned.
822 </Para>
823
824 <Para>
825
826 <ProgramListing>
827 getPendingSignals :: IO SignalSet
828 </ProgramListing>
829
830 </Para>
831
832 <Para>
833 <Literal>getPendingSignals</Literal> calls <Literal>sigpending</Literal> to obtain
834 the set of interrupts which have been received but are currently blocked.
835 </Para>
836
837 <Para>
838
839 <ProgramListing>
840 awaitSignal :: Maybe SignalSet -&#62; IO ()
841 </ProgramListing>
842
843 </Para>
844
845 <Para>
846 <Literal>awaitSignal iset</Literal> suspends execution until an interrupt is received.
847 If <Literal>iset</Literal> is <Literal>Just s</Literal>, <Literal>awaitSignal</Literal> calls <Literal>sigsuspend</Literal>, installing
848 <Literal>s</Literal> as the new signal mask before suspending execution; otherwise, it
849 calls <Literal>pause</Literal>.  <Literal>awaitSignal</Literal> returns on receipt of a signal.  If you
850 have installed any signal handlers with <Literal>installHandler</Literal>, it may be
851 wise to call <Literal>yield</Literal> directly after <Literal>awaitSignal</Literal> to ensure that the
852 signal handler runs as promptly.
853 </Para>
854
855 <Para>
856
857 <ProgramListing>
858 scheduleAlarm :: Int -&#62; IO Int
859 </ProgramListing>
860
861 </Para>
862
863 <Para>
864 <Literal>scheduleAlarm i</Literal> calls <Literal>alarm</Literal> to schedule a real time
865 alarm at least <Literal>i</Literal> seconds in the future.
866 </Para>
867
868 <Para>
869
870 <ProgramListing>
871 sleep :: Int -&#62; IO ()
872 </ProgramListing>
873
874 </Para>
875
876 <Para>
877 <Literal>sleep i</Literal> calls <Literal>sleep</Literal> to suspend execution of the
878 program until at least <Literal>i</Literal> seconds have elapsed or a signal is
879 received.
880 </Para>
881
882 </Sect2>
883
884 <Sect2 id="Process-Environment">
885 <Title>Posix Process Environment
886 </Title>
887
888 <Para>
889 <IndexTerm><Primary>Posix, process environment</Primary></IndexTerm>
890 </Para>
891
892 <Para>
893
894 <ProgramListing>
895 getProcessID :: IO ProcessID
896 </ProgramListing>
897
898 </Para>
899
900 <Para>
901 <Literal>getProcessID</Literal> calls <Literal>getpid</Literal> to obtain the <Literal>ProcessID</Literal> for
902 the current process.
903 </Para>
904
905 <Para>
906
907 <ProgramListing>
908 getParentProcessID :: IO ProcessID
909 </ProgramListing>
910
911 </Para>
912
913 <Para>
914 <Literal>getProcessID</Literal> calls <Literal>getppid</Literal> to obtain the <Literal>ProcessID</Literal> for
915 the parent of the current process.
916 </Para>
917
918 <Para>
919
920 <ProgramListing>
921 getRealUserID :: IO UserID
922 </ProgramListing>
923
924 </Para>
925
926 <Para>
927 <Literal>getRealUserID</Literal> calls <Literal>getuid</Literal> to obtain the real <Literal>UserID</Literal>
928 associated with the current process.
929 </Para>
930
931 <Para>
932
933 <ProgramListing>
934 getEffectiveUserID :: IO UserID
935 </ProgramListing>
936
937 </Para>
938
939 <Para>
940 <Literal>getRealUserID</Literal> calls <Literal>geteuid</Literal> to obtain the effective
941 <Literal>UserID</Literal> associated with the current process.
942 </Para>
943
944 <Para>
945
946 <ProgramListing>
947 setUserID :: UserID -&#62; IO ()
948 </ProgramListing>
949
950 </Para>
951
952 <Para>
953 <Literal>setUserID uid</Literal> calls <Literal>setuid</Literal> to set the real, effective, and
954 saved set-user-id associated with the current process to <Literal>uid</Literal>.
955 </Para>
956
957 <Para>
958
959 <ProgramListing>
960 getLoginName :: IO String
961 </ProgramListing>
962
963 </Para>
964
965 <Para>
966 <Literal>getLoginName</Literal> calls <Literal>getlogin</Literal> to obtain the login name
967 associated with the current process.
968 </Para>
969
970 <Para>
971
972 <ProgramListing>
973 getRealGroupID :: IO GroupID
974 </ProgramListing>
975
976 </Para>
977
978 <Para>
979 <Literal>getRealGroupID</Literal> calls <Literal>getgid</Literal> to obtain the real <Literal>GroupID</Literal>
980 associated with the current process.
981 </Para>
982
983 <Para>
984
985 <ProgramListing>
986 getEffectiveGroupID :: IO GroupID
987 </ProgramListing>
988
989 </Para>
990
991 <Para>
992 <Literal>getEffectiveGroupID</Literal> calls <Literal>getegid</Literal> to obtain the effective
993 <Literal>GroupID</Literal> associated with the current process.
994 </Para>
995
996 <Para>
997
998 <ProgramListing>
999 setGroupID :: GroupID -&#62; IO ()
1000 </ProgramListing>
1001
1002 </Para>
1003
1004 <Para>
1005 <Literal>setGroupID gid</Literal> calls <Literal>setgid</Literal> to set the real, effective, and
1006 saved set-group-id associated with the current process to <Literal>gid</Literal>.
1007 </Para>
1008
1009 <Para>
1010
1011 <ProgramListing>
1012 getGroups :: IO [GroupID]
1013 </ProgramListing>
1014
1015 </Para>
1016
1017 <Para>
1018 <Literal>getGroups</Literal> calls <Literal>getgroups</Literal> to obtain the list of
1019 supplementary <Literal>GroupID</Literal>s associated with the current process.
1020 </Para>
1021
1022 <Para>
1023
1024 <ProgramListing>
1025 getEffectiveUserName :: IO String
1026 </ProgramListing>
1027
1028 </Para>
1029
1030 <Para>
1031 <Literal>getEffectiveUserName</Literal> calls <Literal>cuserid</Literal> to obtain a name
1032 associated with the effective <Literal>UserID</Literal> of the process.
1033 </Para>
1034
1035 <Para>
1036
1037 <ProgramListing>
1038 getProcessGroupID :: IO ProcessGroupID
1039 </ProgramListing>
1040
1041 </Para>
1042
1043 <Para>
1044 <Literal>getProcessGroupID</Literal> calls <Literal>getpgrp</Literal> to obtain the
1045 <Literal>ProcessGroupID</Literal> for the current process.
1046 </Para>
1047
1048 <Para>
1049
1050 <ProgramListing>
1051 createProcessGroup :: ProcessID -&#62; IO ProcessGroupID
1052 </ProgramListing>
1053
1054 </Para>
1055
1056 <Para>
1057 <Literal>createProcessGroup pid</Literal> calls <Literal>setpgid</Literal> to make
1058 process <Literal>pid</Literal> a new process group leader.
1059 </Para>
1060
1061 <Para>
1062
1063 <ProgramListing>
1064 joinProcessGroup :: ProcessGroupID -&#62; IO ProcessGroupID
1065 </ProgramListing>
1066
1067 </Para>
1068
1069 <Para>
1070 <Literal>joinProcessGroup pgid</Literal> calls <Literal>setpgid</Literal> to set the
1071 <Literal>ProcessGroupID</Literal> of the current process to <Literal>pgid</Literal>.
1072 </Para>
1073
1074 <Para>
1075
1076 <ProgramListing>
1077 setProcessGroupID :: ProcessID -&#62; ProcessGroupID -&#62; IO ()
1078 </ProgramListing>
1079
1080 </Para>
1081
1082 <Para>
1083 <Literal>setProcessGroupID pid pgid</Literal> calls <Literal>setpgid</Literal> to set the
1084 <Literal>ProcessGroupID</Literal> for process <Literal>pid</Literal> to <Literal>pgid</Literal>.
1085 </Para>
1086
1087 <Para>
1088
1089 <ProgramListing>
1090 createSession :: IO ProcessGroupID
1091 </ProgramListing>
1092
1093 </Para>
1094
1095 <Para>
1096 <Literal>createSession</Literal> calls <Literal>setsid</Literal> to create a new session
1097 with the current process as session leader.
1098 </Para>
1099
1100 <Para>
1101
1102 <ProgramListing>
1103 systemName :: SystemID -&#62; String
1104 nodeName :: SystemID -&#62; String
1105 release :: SystemID -&#62; String
1106 version :: SystemID -&#62; String
1107 machine :: SystemID -&#62; String
1108
1109 getSystemID :: IO SystemID
1110 </ProgramListing>
1111
1112 </Para>
1113
1114 <Para>
1115 <Literal>getSystemID</Literal> calls <Literal>uname</Literal> to obtain information
1116 about the current operating system.
1117 </Para>
1118
1119 <Para>
1120
1121 <ProgramListing>
1122 &#62; epochTime :: IO EpochTime
1123 </ProgramListing>
1124
1125 </Para>
1126
1127 <Para>
1128 <Literal>epochTime</Literal> calls <Literal>time</Literal> to obtain the number of 
1129 seconds that have elapsed since the epoch (Jan 01 00:00:00 GMT 1970).
1130 </Para>
1131
1132 <Para>
1133
1134 <ProgramListing>
1135 elapsedTime     :: ProcessTimes -&#62; ClockTick
1136 userTime        :: ProcessTimes -&#62; ClockTick
1137 systemTime      :: ProcessTimes -&#62; ClockTick
1138 childUserTime   :: ProcessTimes -&#62; ClockTick
1139 childSystemTime :: ProcessTimes -&#62; ClockTick
1140
1141 getProcessTimes :: IO ProcessTimes
1142 </ProgramListing>
1143
1144 </Para>
1145
1146 <Para>
1147 <Literal>getProcessTimes</Literal> calls <Literal>times</Literal> to obtain time-accounting
1148 information for the current process and its children.
1149 </Para>
1150
1151 <Para>
1152
1153 <ProgramListing>
1154 getControllingTerminalName :: IO FilePath
1155 </ProgramListing>
1156
1157 </Para>
1158
1159 <Para>
1160 <Literal>getControllingTerminalName</Literal> calls <Literal>ctermid</Literal> to obtain
1161 a name associated with the controlling terminal for the process.  If a
1162 controlling terminal exists,
1163 <Literal>getControllingTerminalName</Literal> returns the name of the
1164 controlling terminal.
1165 </Para>
1166
1167 <Para>
1168 The operation may fail with:
1169 </Para>
1170
1171 <Para>
1172 <VariableList>
1173
1174 <VarListEntry>
1175 <Term><Literal>NoSuchThing</Literal></Term>
1176 <ListItem>
1177 <Para>
1178 There is no controlling terminal, or its name cannot be determined.
1179 </Para>
1180 </ListItem>
1181 </VarListEntry>
1182 <VarListEntry>
1183 <Term><Literal>SystemError</Literal></Term>
1184 <ListItem>
1185 <Para>
1186 Various other causes.
1187 </Para>
1188 </ListItem>
1189 </VarListEntry>
1190 </VariableList>
1191 </Para>
1192
1193 <Para>
1194
1195 <ProgramListing>
1196 getTerminalName :: Fd -&#62; IO FilePath
1197 </ProgramListing>
1198
1199 </Para>
1200
1201 <Para>
1202 <Literal>getTerminalName fd</Literal> calls <Literal>ttyname</Literal> to obtain a name associated
1203 with the terminal for <Literal>Fd</Literal> <Literal>fd</Literal>. If <Literal>fd</Literal> is associated
1204 with a terminal, <Literal>getTerminalName</Literal> returns the name of the
1205 terminal.
1206 </Para>
1207
1208 <Para>
1209 The operation may fail with:
1210 </Para>
1211
1212 <Para>
1213 <VariableList>
1214
1215 <VarListEntry>
1216 <Term><Literal>InappropriateType</Literal></Term>
1217 <ListItem>
1218 <Para>
1219 The channel is not associated with a terminal.
1220 </Para>
1221 </ListItem>
1222 </VarListEntry>
1223 <VarListEntry>
1224 <Term><Literal>NoSuchThing</Literal></Term>
1225 <ListItem>
1226 <Para>
1227 The channel is associated with a terminal, but it has no name.
1228 </Para>
1229 </ListItem>
1230 </VarListEntry>
1231 <VarListEntry>
1232 <Term><Literal>SystemError</Literal></Term>
1233 <ListItem>
1234 <Para>
1235 Various other causes.
1236 </Para>
1237 </ListItem>
1238 </VarListEntry>
1239 </VariableList>
1240 </Para>
1241
1242 <Para>
1243
1244 <ProgramListing>
1245 queryTerminal :: Fd -&#62; IO Bool
1246 </ProgramListing>
1247
1248 </Para>
1249
1250 <Para>
1251 <Literal>queryTerminal fd</Literal> calls <Literal>isatty</Literal> to determine whether or
1252 not <Literal>Fd</Literal> <Literal>fd</Literal> is associated with a terminal.
1253 </Para>
1254
1255 <Para>
1256
1257 <ProgramListing>
1258 getSysVar :: SysVar -&#62; IO Limit
1259 </ProgramListing>
1260
1261 </Para>
1262
1263 <Para>
1264 <Literal>getSysVar var</Literal> calls <Literal>sysconf</Literal> to obtain the
1265 dynamic value of the requested configurable system limit or option.
1266 For defined system limits, <Literal>getSysVar</Literal> returns the associated
1267 value.  For defined system options, the result of <Literal>getSysVar</Literal>
1268 is undefined, but not failure.
1269 </Para>
1270
1271 <Para>
1272 The operation may fail with:
1273 </Para>
1274
1275 <Para>
1276 <VariableList>
1277
1278 <VarListEntry>
1279 <Term><Literal>NoSuchThing</Literal></Term>
1280 <ListItem>
1281 <Para>
1282 The requested system limit or option is undefined.
1283 </Para>
1284 </ListItem>
1285 </VarListEntry>
1286 </VariableList>
1287 </Para>
1288
1289 </Sect2>
1290
1291 <Sect2 id="Files-and-Directories">
1292 <Title>Posix operations on files and directories
1293 </Title>
1294
1295 <Para>
1296 <IndexTerm><Primary>Posix, files and directories</Primary></IndexTerm>
1297 </Para>
1298
1299 <Para>
1300
1301 <ProgramListing>
1302 openDirStream :: FilePath -&#62; IO DirStream
1303 </ProgramListing>
1304
1305 </Para>
1306
1307 <Para>
1308 <Literal>openDirStream dir</Literal> calls <Literal>opendir</Literal> to obtain a
1309 directory stream for <Literal>dir</Literal>.
1310 </Para>
1311
1312 <Para>
1313
1314 <ProgramListing>
1315 readDirStream :: DirStream -&#62; IO String
1316 </ProgramListing>
1317
1318 </Para>
1319
1320 <Para>
1321 <Literal>readDirStream dp</Literal> calls <Literal>readdir</Literal> to obtain the
1322 next directory entry (<Literal>struct dirent</Literal>) for the open directory
1323 stream <Literal>dp</Literal>, and returns the <Literal>d&lowbar;name</Literal> member of that
1324 structure.
1325 </Para>
1326
1327 <Para>
1328 The operation may fail with:
1329 </Para>
1330
1331 <Para>
1332 <VariableList>
1333
1334 <VarListEntry>
1335 <Term><Literal>EOF</Literal></Term>
1336 <ListItem>
1337 <Para>
1338 End of file has been reached.
1339 </Para>
1340 </ListItem>
1341 </VarListEntry>
1342 <VarListEntry>
1343 <Term><Literal>SystemError</Literal></Term>
1344 <ListItem>
1345 <Para>
1346 Various other causes.
1347 </Para>
1348 </ListItem>
1349 </VarListEntry>
1350 </VariableList>
1351 </Para>
1352
1353 <Para>
1354
1355 <ProgramListing>
1356 rewindDirStream :: DirStream -&#62; IO ()
1357 </ProgramListing>
1358
1359 </Para>
1360
1361 <Para>
1362 <Literal>rewindDirStream dp</Literal> calls <Literal>rewinddir</Literal> to reposition
1363 the directory stream <Literal>dp</Literal> at the beginning of the directory.
1364 </Para>
1365
1366 <Para>
1367
1368 <ProgramListing>
1369 closeDirStream :: DirStream -&#62; IO ()
1370 </ProgramListing>
1371
1372 </Para>
1373
1374 <Para>
1375 <Literal>closeDirStream dp</Literal> calls <Literal>closedir</Literal> to close
1376 the directory stream <Literal>dp</Literal>.
1377 </Para>
1378
1379 <Para>
1380
1381 <ProgramListing>
1382 getWorkingDirectory :: IO FilePath
1383 </ProgramListing>
1384
1385 </Para>
1386
1387 <Para>
1388 <Literal>getWorkingDirectory</Literal> calls <Literal>getcwd</Literal> to obtain the name
1389 of the current working directory.
1390 </Para>
1391
1392 <Para>
1393
1394 <ProgramListing>
1395 changeWorkingDirectory :: FilePath -&#62; IO ()
1396 </ProgramListing>
1397
1398 </Para>
1399
1400 <Para>
1401 <Literal>changeWorkingDirectory dir</Literal> calls <Literal>chdir</Literal> to change
1402 the current working directory to <Literal>dir</Literal>.
1403 </Para>
1404
1405 <Para>
1406 <ProgramListing>
1407 nullFileMode       :: FileMode       -- ---------
1408 ownerReadMode      :: FileMode       -- r--------
1409 ownerWriteMode     :: FileMode       -- -w-------
1410 ownerExecuteMode   :: FileMode       -- --x------
1411 groupReadMode      :: FileMode       -- ---r-----
1412 groupWriteMode     :: FileMode       -- ----w----
1413 groupExecuteMode   :: FileMode       -- -----x---
1414 otherReadMode      :: FileMode       -- ------r--
1415 otherWriteMode     :: FileMode       -- -------w-
1416 otherExecuteMode   :: FileMode       -- --------x
1417 setUserIDMode      :: FileMode       -- --S------
1418 setGroupIDMode     :: FileMode       -- -----S---
1419                                
1420 stdFileMode        :: FileMode       -- rw-rw-rw-
1421                                
1422 ownerModes         :: FileMode       -- rwx------
1423 groupModes         :: FileMode       -- ---rwx---
1424 otherModes         :: FileMode       -- ------rwx
1425 accessModes        :: FileMode       -- rwxrwxrwx
1426
1427 unionFileModes     :: FileMode -&#62; FileMode -&#62; FileMode
1428 intersectFileModes :: FileMode -&#62; FileMode -&#62; FileMode
1429
1430 stdInput  :: Fd
1431 stdInput  = intToFd 0
1432
1433 stdOutput :: Fd
1434 stdOutput = intToFd 1
1435
1436 stdError  :: Fd
1437 stdError  = intToFd 2
1438
1439 data OpenFileFlags =
1440  OpenFileFlags {
1441     append    :: Bool,
1442     exclusive :: Bool,
1443     noctty    :: Bool,
1444     nonBlock  :: Bool,
1445     trunc     :: Bool
1446  }
1447
1448 openFd :: FilePath
1449        -&#62; OpenMode
1450        -&#62; Maybe FileMode  -- Just x =&#62; O_CREAT, Nothing =&#62; must exist
1451        -&#62; OpenFileFlags
1452        -&#62; IO Fd
1453 </ProgramListing>
1454 </Para>
1455
1456 <Para>
1457 <Literal>openFd path acc mode (OpenFileFlags app excl noctty nonblock trunc)</Literal> calls
1458 <Literal>open</Literal> to obtain a <Literal>Fd</Literal> for the file <Literal>path</Literal> with access
1459 mode <Literal>acc</Literal>.  If <Literal>mode</Literal> is <Literal>Just m</Literal>, the <Literal>O&lowbar;CREAT</Literal> flag is
1460 set and the file's permissions will be based on <Literal>m</Literal> if it does not
1461 already exist; otherwise, the <Literal>O&lowbar;CREAT</Literal> flag is not set.  The
1462 arguments <Literal>app</Literal>, <Literal>excl</Literal>, <Literal>noctty</Literal>, <Literal>nonblock</Literal>, and
1463 <Literal>trunc</Literal> control whether or not the flags <Literal>O&lowbar;APPEND</Literal>,
1464 <Literal>O&lowbar;EXCL</Literal>, <Literal>O&lowbar;NOCTTY</Literal>, <Literal>O&lowbar;NONBLOCK</Literal>, and <Literal>O&lowbar;TRUNC</Literal> are set,
1465 respectively.
1466 </Para>
1467
1468 <Para>
1469
1470 <ProgramListing>
1471 createFile :: FilePath -&#62; FileMode -&#62; IO Fd
1472 </ProgramListing>
1473
1474 </Para>
1475
1476 <Para>
1477 <Literal>createFile path mode</Literal> calls <Literal>creat</Literal> to obtain a <Literal>Fd</Literal>
1478 for file <Literal>path</Literal>, which will be created with permissions based on
1479 <Literal>mode</Literal> if it does not already exist.
1480 </Para>
1481
1482 <Para>
1483
1484 <ProgramListing>
1485 setFileCreationMask :: FileMode -&#62; IO FileMode
1486 </ProgramListing>
1487
1488 </Para>
1489
1490 <Para>
1491 <Literal>setFileCreationMask mode</Literal> calls <Literal>umask</Literal> to set
1492 the process's file creation mask to <Literal>mode</Literal>.  The previous file
1493 creation mask is returned.
1494 </Para>
1495
1496 <Para>
1497
1498 <ProgramListing>
1499 createLink :: FilePath -&#62; FilePath -&#62; IO ()
1500 </ProgramListing>
1501
1502 </Para>
1503
1504 <Para>
1505 <Literal>createLink old new</Literal> calls <Literal>link</Literal> to create a 
1506 new path, <Literal>new</Literal>, linked to an existing file, <Literal>old</Literal>.
1507
1508 <ProgramListing>
1509 createDirectory :: FilePath -&#62; FileMode -&#62; IO ()
1510 </ProgramListing>
1511
1512 </Para>
1513
1514 <Para>
1515 <Literal>createDirectory dir mode</Literal> calls <Literal>mkdir</Literal> to 
1516 create a new directory, <Literal>dir</Literal>, with permissions based on
1517 <Literal>mode</Literal>.
1518 </Para>
1519
1520 <Para>
1521
1522 <ProgramListing>
1523 createNamedPipe :: FilePath -&#62; FileMode -&#62; IO ()
1524 </ProgramListing>
1525
1526 </Para>
1527
1528 <Para>
1529 <Literal>createNamedPipe fifo mode</Literal> calls <Literal>mkfifo</Literal> to 
1530 create a new named pipe, <Literal>fifo</Literal>, with permissions based on
1531 <Literal>mode</Literal>.
1532 </Para>
1533
1534 <Para>
1535
1536 <ProgramListing>
1537 removeLink :: FilePath -&#62; IO ()
1538 </ProgramListing>
1539
1540 </Para>
1541
1542 <Para>
1543 <Literal>removeLink path</Literal> calls <Literal>unlink</Literal> to remove the link
1544 named <Literal>path</Literal>.
1545 </Para>
1546
1547 <Para>
1548
1549 <ProgramListing>
1550 removeDirectory :: FilePath -&#62; IO ()
1551 </ProgramListing>
1552
1553 </Para>
1554
1555 <Para>
1556 <Literal>removeDirectory dir</Literal> calls <Literal>rmdir</Literal> to remove the 
1557 directory named <Literal>dir</Literal>.
1558 </Para>
1559
1560 <Para>
1561
1562 <ProgramListing>
1563 rename :: FilePath -&#62; FilePath -&#62; IO ()
1564 </ProgramListing>
1565
1566 </Para>
1567
1568 <Para>
1569 <Literal>rename old new</Literal> calls <Literal>rename</Literal> to rename a 
1570 file or directory from <Literal>old</Literal> to <Literal>new</Literal>.
1571 </Para>
1572
1573 <Para>
1574
1575 <ProgramListing>
1576 fileMode          :: FileStatus -&#62; FileMode
1577                    
1578 fileID            :: FileStatus -&#62; FileID
1579 deviceID          :: FileStatus -&#62; DeviceID
1580                    
1581 linkCount         :: FileStatus -&#62; LinkCount
1582                    
1583 fileOwner         :: FileStatus -&#62; UserID
1584 fileGroup         :: FileStatus -&#62; GroupID
1585 fileSize          :: FileStatus -&#62; FileOffset
1586
1587 accessTime        :: FileStatus -&#62; EpochTime
1588 modificationTime  :: FileStatus -&#62; EpochTime
1589 statusChangeTime  :: FileStatus -&#62; EpochTime
1590
1591 isDirectory       :: FileStatus -&#62; Bool
1592 isCharacterDevice :: FileStatus -&#62; Bool
1593 isBlockDevice     :: FileStatus -&#62; Bool
1594 isRegularFile     :: FileStatus -&#62; Bool
1595 isNamedPipe       :: FileStatus -&#62; Bool
1596
1597 getFileStatus     :: FilePath -&#62; IO FileStatus
1598 </ProgramListing>
1599
1600 </Para>
1601
1602 <Para>
1603 <Literal>getFileStatus path</Literal> calls <Literal>stat</Literal> to get the
1604 <Literal>FileStatus</Literal> information for the file <Literal>path</Literal>.
1605 </Para>
1606
1607 <Para>
1608
1609 <ProgramListing>
1610 getFdStatus :: Fd -&#62; IO FileStatus
1611 </ProgramListing>
1612
1613 </Para>
1614
1615 <Para>
1616 <Literal>getFdStatus fd</Literal> calls <Literal>fstat</Literal> to get the
1617 <Literal>FileStatus</Literal> information for the file associated with
1618 <Literal>Fd</Literal> <Literal>fd</Literal>.
1619 </Para>
1620
1621 <Para>
1622
1623 <ProgramListing>
1624 queryAccess :: FilePath -&#62; Bool -&#62; Bool -&#62; Bool -&#62; IO Bool
1625 </ProgramListing>
1626
1627 </Para>
1628
1629 <Para>
1630 <Literal>queryAccess path r w x</Literal> calls <Literal>access</Literal> to test the access
1631 permissions for file <Literal>path</Literal>.  The three arguments, <Literal>r</Literal>, <Literal>w</Literal>,
1632 and <Literal>x</Literal> control whether or not <Literal>access</Literal> is called with
1633 <Literal>R&lowbar;OK</Literal>, <Literal>W&lowbar;OK</Literal>, and <Literal>X&lowbar;OK</Literal> respectively.
1634 </Para>
1635
1636 <Para>
1637
1638 <ProgramListing>
1639 queryFile :: FilePath -&#62; IO Bool
1640 </ProgramListing>
1641
1642 </Para>
1643
1644 <Para>
1645 <Literal>queryFile path</Literal> calls <Literal>access</Literal> with <Literal>F&lowbar;OK</Literal> to test for the
1646 existence for file <Literal>path</Literal>.
1647 </Para>
1648
1649 <Para>
1650
1651 <ProgramListing>
1652 setFileMode :: FilePath -&#62; FileMode -&#62; IO ()
1653 </ProgramListing>
1654
1655 </Para>
1656
1657 <Para>
1658 <Literal>setFileMode path mode</Literal> calls <Literal>chmod</Literal> to set the
1659 permission bits associated with file <Literal>path</Literal> to <Literal>mode</Literal>.
1660 </Para>
1661
1662 <Para>
1663
1664 <ProgramListing>
1665 setOwnerAndGroup :: FilePath -&#62; UserID -&#62; GroupID -&#62; IO ()
1666 </ProgramListing>
1667
1668 </Para>
1669
1670 <Para>
1671 <Literal>setOwnerAndGroup path uid gid</Literal> calls <Literal>chown</Literal> to
1672 set the <Literal>UserID</Literal> and <Literal>GroupID</Literal> associated with file
1673 <Literal>path</Literal> to <Literal>uid</Literal> and <Literal>gid</Literal>, respectively.
1674 </Para>
1675
1676 <Para>
1677
1678 <ProgramListing>
1679 setFileTimes :: FilePath -&#62; EpochTime -&#62; EpochTime -&#62; IO ()
1680 </ProgramListing>
1681
1682 </Para>
1683
1684 <Para>
1685 <Literal>setFileTimes path atime mtime</Literal> calls <Literal>utime</Literal> to
1686 set the access and modification times associated with file
1687 <Literal>path</Literal> to <Literal>atime</Literal> and <Literal>mtime</Literal>, respectively.
1688 </Para>
1689
1690 <Para>
1691
1692 <ProgramListing>
1693 touchFile :: FilePath -&#62; IO ()
1694 </ProgramListing>
1695
1696 </Para>
1697
1698 <Para>
1699 <Literal>touchFile path</Literal> calls <Literal>utime</Literal> to
1700 set the access and modification times associated with file
1701 <Literal>path</Literal> to the current time.
1702 </Para>
1703
1704 <Para>
1705
1706 <ProgramListing>
1707 getPathVar :: PathVar -&#62; FilePath -&#62; IO Limit
1708 </ProgramListing>
1709
1710 </Para>
1711
1712 <Para>
1713 <Literal>getPathVar var path</Literal> calls <Literal>pathconf</Literal> to obtain the
1714 dynamic value of the requested configurable file limit or option associated
1715 with file or directory <Literal>path</Literal>.  For
1716 defined file limits, <Literal>getPathVar</Literal> returns the associated
1717 value.  For defined file options, the result of <Literal>getPathVar</Literal>
1718 is undefined, but not failure.
1719 The operation may fail with:
1720 <VariableList>
1721
1722 <VarListEntry>
1723 <Term><Literal>NoSuchThing</Literal></Term>
1724 <ListItem>
1725 <Para>
1726 The requested file limit or option is undefined.
1727 </Para>
1728 </ListItem>
1729 </VarListEntry>
1730 <VarListEntry>
1731 <Term><Literal>SystemError</Literal></Term>
1732 <ListItem>
1733 <Para>
1734 Various other causes.
1735 </Para>
1736 </ListItem>
1737 </VarListEntry>
1738 </VariableList>
1739 </Para>
1740
1741 <Para>
1742
1743 <ProgramListing>
1744 getFdVar :: PathVar -&#62; Fd -&#62; IO Limit
1745 </ProgramListing>
1746
1747 </Para>
1748
1749 <Para>
1750 <Literal>getFdVar var fd</Literal> calls <Literal>fpathconf</Literal> to obtain the
1751 dynamic value of the requested configurable file limit or option associated
1752 with the file or directory attached to the open channel <Literal>fd</Literal>.
1753 For defined file limits, <Literal>getFdVar</Literal> returns the associated
1754 value.  For defined file options, the result of <Literal>getFdVar</Literal>
1755 is undefined, but not failure.
1756 </Para>
1757
1758 <Para>
1759 The operation may fail with:
1760 </Para>
1761
1762 <Para>
1763 <VariableList>
1764
1765 <VarListEntry>
1766 <Term><Literal>NoSuchThing</Literal></Term>
1767 <ListItem>
1768 <Para>
1769 The requested file limit or option is undefined.
1770 </Para>
1771 </ListItem>
1772 </VarListEntry>
1773 <VarListEntry>
1774 <Term><Literal>SystemError</Literal></Term>
1775 <ListItem>
1776 <Para>
1777 Various other causes.
1778 </Para>
1779 </ListItem>
1780 </VarListEntry>
1781 </VariableList>
1782 </Para>
1783
1784 </Sect2>
1785
1786 <Sect2 id="Input-Output">
1787 <Title>Posix Input and Output Primitives
1788 </Title>
1789
1790 <Para>
1791 <IndexTerm><Primary>Posix, input/output</Primary></IndexTerm>
1792 </Para>
1793
1794 <Para>
1795
1796 <ProgramListing>
1797 createPipe :: IO (Fd, Fd)
1798 </ProgramListing>
1799
1800 </Para>
1801
1802 <Para>
1803 <Literal>createPipe</Literal> calls <Literal>pipe</Literal> to create a pipe and returns a pair of
1804 <Literal>Fd</Literal>s, the first for reading and the second for writing.
1805 </Para>
1806
1807 <Para>
1808
1809 <ProgramListing>
1810 dup :: Fd -&#62; IO Fd
1811 </ProgramListing>
1812
1813 </Para>
1814
1815 <Para>
1816 <Literal>dup fd</Literal> calls <Literal>dup</Literal> to duplicate <Literal>Fd</Literal> <Literal>fd</Literal> to
1817 another <Literal>Fd</Literal>.
1818 </Para>
1819
1820 <Para>
1821
1822 <ProgramListing>
1823 dupTo :: Fd -&#62; Fd -&#62; IO ()
1824 </ProgramListing>
1825
1826 </Para>
1827
1828 <Para>
1829 <Literal>dupTo src dst</Literal> calls <Literal>dup2</Literal> to duplicate <Literal>Fd</Literal>
1830 <Literal>src</Literal> to <Literal>Fd</Literal> <Literal>dst</Literal>.
1831 </Para>
1832
1833 <Para>
1834
1835 <ProgramListing>
1836 fdClose :: Fd -&#62; IO ()
1837 </ProgramListing>
1838
1839 </Para>
1840
1841 <Para>
1842 <Literal>fdClose fd</Literal> calls <Literal>close</Literal> to close <Literal>Fd</Literal> <Literal>fd</Literal>.
1843 </Para>
1844
1845 <Para>
1846
1847 <ProgramListing>
1848 fdRead :: Fd -&#62; ByteCount -&#62; IO (String, ByteCount)
1849 </ProgramListing>
1850
1851 </Para>
1852
1853 <Para>
1854 <Literal>fdRead fd nbytes</Literal> calls <Literal>read</Literal> to read at most <Literal>nbytes</Literal>
1855 bytes from <Literal>Fd</Literal> <Literal>fd</Literal>, and returns the result as a string
1856 paired with the number of bytes actually read.
1857 </Para>
1858
1859 <Para>
1860 The operation may fail with:
1861 </Para>
1862
1863 <Para>
1864 <VariableList>
1865
1866 <VarListEntry>
1867 <Term><Literal>EOF</Literal></Term>
1868 <ListItem>
1869 <Para>
1870 End of file has been reached.
1871 </Para>
1872 </ListItem>
1873 </VarListEntry>
1874 <VarListEntry>
1875 <Term><Literal>SystemError</Literal></Term>
1876 <ListItem>
1877 <Para>
1878 Various other causes.
1879 </Para>
1880 </ListItem>
1881 </VarListEntry>
1882 </VariableList>
1883 </Para>
1884
1885 <Para>
1886
1887 <ProgramListing>
1888 fdWrite :: Fd -&#62; String -&#62; IO ByteCount
1889 </ProgramListing>
1890
1891 </Para>
1892
1893 <Para>
1894 <Literal>fdWrite fd s</Literal> calls <Literal>write</Literal> to write
1895 the string <Literal>s</Literal> to <Literal>Fd</Literal> <Literal>fd</Literal> as a
1896 contiguous sequence of bytes.  It returns the number of bytes successfully
1897 written.
1898 </Para>
1899
1900 <Para>
1901
1902 <ProgramListing>
1903 queryFdOption :: FdOption -&#62; Fd -&#62; IO Bool
1904 </ProgramListing>
1905
1906 </Para>
1907
1908 <Para>
1909 <Literal>getFdOption opt fd</Literal> calls <Literal>fcntl</Literal> to determine whether or
1910 not the flag associated with <Literal>FdOption</Literal> <Literal>opt</Literal> is set for
1911 <Literal>Fd</Literal> <Literal>fd</Literal>.
1912 </Para>
1913
1914 <Para>
1915
1916 <ProgramListing>
1917 setFdOption :: Fd -&#62; FdOption -&#62; Bool -&#62; IO ()
1918 </ProgramListing>
1919
1920 </Para>
1921
1922 <Para>
1923 <Literal>setFdOption fd opt val</Literal> calls <Literal>fcntl</Literal> to set the flag
1924 associated with <Literal>FdOption</Literal> <Literal>opt</Literal> on <Literal>Fd</Literal> <Literal>fd</Literal> to
1925 <Literal>val</Literal>.
1926 </Para>
1927
1928 <Para>
1929
1930 <ProgramListing>
1931 getLock :: Fd -&#62; FileLock -&#62; IO (Maybe (ProcessID, FileLock))
1932 </ProgramListing>
1933
1934 </Para>
1935
1936 <Para>
1937 <Literal>getLock fd lock</Literal> calls <Literal>fcntl</Literal> to get the first <Literal>FileLock</Literal>
1938 for <Literal>Fd</Literal> <Literal>fd</Literal> which blocks the <Literal>FileLock</Literal> <Literal>lock</Literal>.  If
1939 no such <Literal>FileLock</Literal> exists, <Literal>getLock</Literal> returns <Literal>Nothing</Literal>.
1940 Otherwise, it returns <Literal>Just (pid, block)</Literal>, where <Literal>block</Literal> is the
1941 blocking <Literal>FileLock</Literal> and <Literal>pid</Literal> is the <Literal>ProcessID</Literal> of the
1942 process holding the blocking <Literal>FileLock</Literal>.
1943 </Para>
1944
1945 <Para>
1946
1947 <ProgramListing>
1948 setLock :: Fd -&#62; FileLock -&#62; IO ()
1949 </ProgramListing>
1950
1951 </Para>
1952
1953 <Para>
1954 <Literal>setLock fd lock</Literal> calls <Literal>fcntl</Literal> with <Literal>F&lowbar;SETLK</Literal> to set or
1955 clear a lock segment for <Literal>Fd</Literal> <Literal>fd</Literal> as indicated by the
1956 <Literal>FileLock</Literal> <Literal>lock</Literal>.  <Literal>setLock</Literal> does not block, but fails with
1957 <Literal>SystemError</Literal> if the request cannot be satisfied immediately.
1958 </Para>
1959
1960 <Para>
1961
1962 <ProgramListing>
1963 waitToSetLock :: Fd -&#62; FileLock -&#62; IO ()
1964 </ProgramListing>
1965
1966 </Para>
1967
1968 <Para>
1969 <Literal>waitToSetLock fd lock</Literal> calls <Literal>fcntl</Literal> with <Literal>F&lowbar;SETLKW</Literal> to set
1970 or clear a lock segment for <Literal>Fd</Literal> <Literal>fd</Literal> as indicated by the
1971 <Literal>FileLock</Literal> <Literal>lock</Literal>. If the request cannot be satisfied
1972 immediately, <Literal>waitToSetLock</Literal> blocks until the request can be
1973 satisfied.
1974 </Para>
1975
1976 <Para>
1977
1978 <ProgramListing>
1979 fdSeek :: Fd -&#62; SeekMode -&#62; FileOffset -&#62; IO FileOffset
1980 </ProgramListing>
1981
1982 </Para>
1983
1984 <Para>
1985 <Literal>fdSeek fd whence offset</Literal> calls <Literal>lseek</Literal> to position the
1986 <Literal>Fd</Literal> <Literal>fd</Literal> at the given <Literal>offset</Literal> from the starting location
1987 indicated by <Literal>whence</Literal>.  It returns the resulting offset from the
1988 start of the file in bytes.
1989 </Para>
1990
1991 </Sect2>
1992
1993 <Sect2 id="Device-Specific-Functions">
1994 <Title>Posix, Device- and Class-Specific Functions
1995 </Title>
1996
1997 <Para>
1998 <IndexTerm><Primary>Posix, device and class-specific functions</Primary></IndexTerm>
1999 </Para>
2000
2001 <Para>
2002
2003 <ProgramListing>
2004 terminalMode    :: TerminalMode -&#62; TerminalAttributes -&#62; Bool
2005 withMode        :: TerminalAttributes -&#62; TerminalMode -&#62; TerminalAttributes
2006 withoutMode     :: TerminalAttributes -&#62; TerminalMode -&#62; TerminalAttributes
2007
2008 bitsPerByte     :: TerminalAttributes -&#62; Int
2009 withBits        :: TerminalAttributes -&#62; Int -&#62; TerminalAttributes
2010
2011 controlChar     :: TerminalAttributes -&#62; ControlCharacter -&#62; Maybe Char
2012 withCC          :: TerminalAttributes
2013                 -&#62; (ControlCharacter, Char)
2014                 -&#62; TerminalAttributes 
2015 withoutCC       :: TerminalAttributes 
2016                 -&#62; ControlCharacter 
2017                 -&#62; TerminalAttributes
2018                   
2019 inputTime       :: TerminalAttributes -&#62; Int
2020 withTime        :: TerminalAttributes -&#62; Int -&#62; TerminalAttributes
2021                   
2022 minInput        :: TerminalAttributes -&#62; Int
2023 withMinInput    :: TerminalAttributes -&#62; Int -&#62; TerminalAttributes
2024                   
2025 inputSpeed      :: TerminalAttributes -&#62; BaudRate
2026 withInputSpeed  :: TerminalAttributes -&#62; BaudRate -&#62; TerminalAttributes
2027                   
2028 outputSpeed     :: TerminalAttributes -&#62; BaudRate
2029 withOutputSpeed :: TerminalAttributes -&#62; BaudRate -&#62; TerminalAttributes
2030
2031 getTerminalAttributes :: Fd -&#62; IO TerminalAttributes
2032 </ProgramListing>
2033
2034 </Para>
2035
2036 <Para>
2037 <Literal>getTerminalAttributes fd</Literal> calls <Literal>tcgetattr</Literal> to obtain
2038 the <Literal>TerminalAttributes</Literal> associated with <Literal>Fd</Literal> <Literal>fd</Literal>.
2039 </Para>
2040
2041 <Para>
2042
2043 <ProgramListing>
2044 setTerminalAttributes :: Fd
2045                       -&#62; TerminalAttributes 
2046                       -&#62; TerminalState
2047                       -&#62; IO ()
2048 </ProgramListing>
2049
2050 </Para>
2051
2052 <Para>
2053 <Literal>setTerminalAttributes fd attr ts</Literal> calls <Literal>tcsetattr</Literal> to change
2054 the <Literal>TerminalAttributes</Literal> associated with <Literal>Fd</Literal> <Literal>fd</Literal> to
2055 <Literal>attr</Literal>, when the terminal is in the state indicated by <Literal>ts</Literal>.
2056 </Para>
2057
2058 <Para>
2059
2060 <ProgramListing>
2061 sendBreak :: Fd -&#62; Int -&#62; IO ()
2062 </ProgramListing>
2063
2064 </Para>
2065
2066 <Para>
2067 <Literal>sendBreak fd duration</Literal> calls <Literal>tcsendbreak</Literal> to transmit a
2068 continuous stream of zero-valued bits on <Literal>Fd</Literal> <Literal>fd</Literal> for the
2069 specified implementation-dependent <Literal>duration</Literal>.
2070 </Para>
2071
2072 <Para>
2073
2074 <ProgramListing>
2075 drainOutput :: Fd -&#62; IO ()
2076 </ProgramListing>
2077
2078 </Para>
2079
2080 <Para>
2081 <Literal>drainOutput fd</Literal> calls <Literal>tcdrain</Literal> to block until all output
2082 written to <Literal>Fd</Literal> <Literal>fd</Literal> has been transmitted.
2083 </Para>
2084
2085 <Para>
2086
2087 <ProgramListing>
2088 discardData :: Fd -&#62; QueueSelector -&#62; IO ()
2089 </ProgramListing>
2090
2091 </Para>
2092
2093 <Para>
2094 <Literal>discardData fd queues</Literal> calls <Literal>tcflush</Literal> to discard
2095 pending input and/or output for <Literal>Fd</Literal> <Literal>fd</Literal>,
2096 as indicated by the <Literal>QueueSelector</Literal> <Literal>queues</Literal>.
2097 </Para>
2098
2099 <Para>
2100
2101 <ProgramListing>
2102 controlFlow :: Fd -&#62; FlowAction -&#62; IO ()
2103 </ProgramListing>
2104
2105 </Para>
2106
2107 <Para>
2108 <Literal>controlFlow fd action</Literal> calls <Literal>tcflow</Literal> to control the 
2109 flow of data on <Literal>Fd</Literal> <Literal>fd</Literal>, as indicated by
2110 <Literal>action</Literal>.
2111 </Para>
2112
2113 <Para>
2114
2115 <ProgramListing>
2116 getTerminalProcessGroupID :: Fd -&#62; IO ProcessGroupID
2117 </ProgramListing>
2118
2119 </Para>
2120
2121 <Para>
2122 <Literal>getTerminalProcessGroupID fd</Literal> calls <Literal>tcgetpgrp</Literal> to
2123 obtain the <Literal>ProcessGroupID</Literal> of the foreground process group 
2124 associated with the terminal attached to <Literal>Fd</Literal> <Literal>fd</Literal>.
2125 </Para>
2126
2127 <Para>
2128
2129 <ProgramListing>
2130 setTerminalProcessGroupID :: Fd -&#62; ProcessGroupID -&#62; IO ()
2131 </ProgramListing>
2132
2133 </Para>
2134
2135 <Para>
2136 <Literal>setTerminalProcessGroupID fd pgid</Literal> calls <Literal>tcsetpgrp</Literal> to
2137 set the <Literal>ProcessGroupID</Literal> of the foreground process group 
2138 associated with the terminal attached to <Literal>Fd</Literal> 
2139 <Literal>fd</Literal> to <Literal>pgid</Literal>.
2140 </Para>
2141
2142 </Sect2>
2143
2144 <Sect2 id="System-Database">
2145 <Title>Posix System Databases
2146 </Title>
2147
2148 <Para>
2149 <IndexTerm><Primary>Posix, system databases</Primary></IndexTerm>
2150 </Para>
2151
2152 <Para>
2153
2154 <ProgramListing>
2155 groupName    :: GroupEntry -&#62; String
2156 groupID      :: GroupEntry -&#62; GroupID
2157 groupMembers :: GroupEntry -&#62; [String]
2158
2159 getGroupEntryForID :: GroupID -&#62; IO GroupEntry
2160 </ProgramListing>
2161
2162 </Para>
2163
2164 <Para>
2165 <Literal>getGroupEntryForID gid</Literal> calls <Literal>getgrgid</Literal> to obtain
2166 the <Literal>GroupEntry</Literal> information associated with <Literal>GroupID</Literal>
2167 <Literal>gid</Literal>.
2168 </Para>
2169
2170 <Para>
2171 The operation may fail with:
2172 </Para>
2173
2174 <Para>
2175 <VariableList>
2176
2177 <VarListEntry>
2178 <Term><Literal>NoSuchThing</Literal></Term>
2179 <ListItem>
2180 <Para>
2181 There is no group entry for the GroupID.
2182 </Para>
2183 </ListItem>
2184 </VarListEntry>
2185 </VariableList>
2186 </Para>
2187
2188 <Para>
2189
2190 <ProgramListing>
2191 getGroupEntryForName :: String -&#62; IO GroupEntry
2192 </ProgramListing>
2193
2194 </Para>
2195
2196 <Para>
2197 <Literal>getGroupEntryForName name</Literal> calls <Literal>getgrnam</Literal> to obtain
2198 the <Literal>GroupEntry</Literal> information associated with the group called
2199 <Literal>name</Literal>.
2200 </Para>
2201
2202 <Para>
2203 The operation may fail with:
2204 </Para>
2205
2206 <Para>
2207 <VariableList>
2208
2209 <VarListEntry>
2210 <Term><Literal>NoSuchThing</Literal></Term>
2211 <ListItem>
2212 <Para>
2213 There is no group entry for the name.
2214 </Para>
2215 </ListItem>
2216 </VarListEntry>
2217 </VariableList>
2218 </Para>
2219
2220 <Para>
2221
2222 <ProgramListing>
2223 userName      :: UserEntry -&#62; String
2224 userID        :: UserEntry -&#62; UserID
2225 userGroupID   :: UserEntry -&#62; GroupID
2226 homeDirectory :: UserEntry -&#62; String
2227 userShell     :: UserEntry -&#62; String
2228
2229 getUserEntryForID :: UserID -&#62; IO UserEntry
2230 </ProgramListing>
2231
2232 </Para>
2233
2234 <Para>
2235 <Literal>getUserEntryForID gid</Literal> calls <Literal>getpwuid</Literal> to obtain
2236 the <Literal>UserEntry</Literal> information associated with <Literal>UserID</Literal>
2237 <Literal>uid</Literal>.
2238 The operation may fail with:
2239 </Para>
2240
2241 <Para>
2242 <VariableList>
2243
2244 <VarListEntry>
2245 <Term><Literal>NoSuchThing</Literal></Term>
2246 <ListItem>
2247 <Para>
2248 There is no user entry for the UserID.
2249 </Para>
2250 </ListItem>
2251 </VarListEntry>
2252 </VariableList>
2253 </Para>
2254
2255 <Para>
2256
2257 <ProgramListing>
2258 getUserEntryForName :: String -&#62; IO UserEntry
2259 </ProgramListing>
2260
2261 </Para>
2262
2263 <Para>
2264 <Literal>getUserEntryForName name</Literal> calls <Literal>getpwnam</Literal> to obtain
2265 the <Literal>UserEntry</Literal> information associated with the user login
2266 <Literal>name</Literal>.
2267 </Para>
2268
2269 <Para>
2270 The operation may fail with:
2271 </Para>
2272
2273 <Para>
2274 <VariableList>
2275
2276 <VarListEntry>
2277 <Term><Literal>NoSuchThing</Literal></Term>
2278 <ListItem>
2279 <Para>
2280 There is no user entry for the name.
2281 </Para>
2282 </ListItem>
2283 </VarListEntry>
2284 </VariableList>
2285 </Para>
2286
2287 </Sect2>
2288
2289 <Sect2 id="Error-reporting-and-handling">
2290 <Title>POSIX Errors
2291 </Title>
2292
2293 <Para>
2294 <IndexTerm><Primary>Posix, errors</Primary></IndexTerm>
2295 </Para>
2296
2297 <Para>
2298
2299 <ProgramListing>
2300 getErrorCode :: IO ErrorCode
2301 </ProgramListing>
2302
2303 </Para>
2304
2305 <Para>
2306 <Literal>getErrorCode</Literal> returns the current value of the external
2307 variable <Literal>errno</Literal>.  It never fails.
2308 </Para>
2309
2310 <Para>
2311
2312 <ProgramListing>
2313 setErrorCode :: ErrorCode -&#62; IO ()
2314 </ProgramListing>
2315
2316 </Para>
2317
2318 <Para>
2319 <Literal>setErrorCode err</Literal> sets the external
2320 variable <Literal>errno</Literal> to <Literal>err</Literal>.  It never fails.
2321 </Para>
2322
2323 <Para>
2324
2325 <ProgramListing>
2326 noError :: ErrorCode
2327 noError = 0
2328
2329 argumentListTooLong, e2BIG              :: ErrorCode
2330 badFd, eBADF                            :: ErrorCode
2331 brokenPipe, ePIPE                       :: ErrorCode
2332 directoryNotEmpty, eNOTEMPTY            :: ErrorCode
2333 execFormatError, eNOEXEC                :: ErrorCode
2334 fileAlreadyExists, eEXIST               :: ErrorCode
2335 fileTooLarge, eFBIG                     :: ErrorCode
2336 filenameTooLong, eNAMETOOLONG           :: ErrorCode
2337 improperLink, eXDEV                     :: ErrorCode
2338 inappropriateIOControlOperation, eNOTTY :: ErrorCode
2339 inputOutputError, eIO                   :: ErrorCode
2340 interruptedOperation, eINTR             :: ErrorCode
2341 invalidArgument, eINVAL                 :: ErrorCode
2342 invalidSeek, eSPIPE                     :: ErrorCode
2343 isADirectory, eISDIR                    :: ErrorCode
2344 noChildProcess, eCHILD                  :: ErrorCode
2345 noLocksAvailable, eNOLCK                :: ErrorCode
2346 noSpaceLeftOnDevice, eNOSPC             :: ErrorCode
2347 noSuchOperationOnDevice, eNODEV         :: ErrorCode
2348 noSuchDeviceOrAddress, eNXIO            :: ErrorCode
2349 noSuchFileOrDirectory, eNOENT           :: ErrorCode
2350 noSuchProcess, eSRCH                    :: ErrorCode
2351 notADirectory, eNOTDIR                  :: ErrorCode
2352 notEnoughMemory, eNOMEM                 :: ErrorCode
2353 operationNotImplemented, eNOSYS         :: ErrorCode
2354 operationNotPermitted, ePERM            :: ErrorCode
2355 permissionDenied, eACCES                :: ErrorCode
2356 readOnlyFileSystem, eROFS               :: ErrorCode
2357 resourceBusy, eBUSY                     :: ErrorCode
2358 resourceDeadlockAvoided, eDEADLK        :: ErrorCode
2359 resourceTemporarilyUnavailable, eAGAIN  :: ErrorCode
2360 tooManyLinks, eMLINK                    :: ErrorCode
2361 tooManyOpenFiles, eMFILE                :: ErrorCode
2362 tooManyOpenFilesInSystem, eNFILE        :: ErrorCode
2363 </ProgramListing>
2364
2365 </Para>
2366
2367 </Sect2>
2368
2369 </Sect1>