Wrap posix_fadvise(2) and posix_fallocate(2)
[packages/unix.git] / System / Posix / Fcntl.hsc
1 {-# LANGUAGE CApiFFI #-}
2 #ifdef __GLASGOW_HASKELL__
3 {-# LANGUAGE Trustworthy #-}
4 #endif
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module      :  System.Posix.Fcntl
8 -- Copyright   :  (c) The University of Glasgow 2014
9 -- License     :  BSD-style (see the file LICENSE)
10 --
11 -- Maintainer  :  libraries@haskell.org
12 -- Stability   :  provisional
13 -- Portability :  non-portable (requires POSIX)
14 --
15 -- POSIX file control support
16 --
17 -----------------------------------------------------------------------------
18
19 #include "HsUnix.h"
20
21 module System.Posix.Fcntl (
22     -- * File allocation
23     Advice(..), fileAdvise,
24     fileAllocate,
25   ) where
26
27 #if HAVE_POSIX_FALLOCATE || HAVE_POSIX_FADVISE
28 import Foreign.C
29 #endif
30 import System.Posix.Types
31
32 #if !HAVE_POSIX_FALLOCATE
33 import System.IO.Error ( ioeSetLocation )
34 import GHC.IO.Exception ( unsupportedOperation )
35 #endif
36
37 -- -----------------------------------------------------------------------------
38 -- File control
39
40 -- | Advice parameter for 'fileAdvise' operation.
41 --
42 -- For more details, see documentation of @posix_fadvise(2)@.
43 data Advice
44   = AdviceNormal
45   | AdviceRandom
46   | AdviceSequential
47   | AdviceWillNeed
48   | AdviceDontNeed
49   | AdviceNoReuse
50   deriving Eq
51
52 -- | Performs @posix_fadvise(2)@ operation on file-descriptor.
53 --
54 -- If platform does not provide @posix_fadvise(2)@ 'fileAdvise'
55 -- becomes a no-op.
56 --
57 -- (use @#if HAVE_POSIX_FADVISE@ CPP guard to detect availability)
58 --
59 -- /Since: 2.7.1.0/
60 fileAdvise :: Fd -> FileOffset -> FileOffset -> Advice -> IO ()
61 #if HAVE_POSIX_FADVISE
62 fileAdvise fd off len adv = do
63   throwErrnoIfMinus1_ "fileAdvise" (c_posix_fadvise (fromIntegral fd) (fromIntegral off) (fromIntegral len) (packAdvice adv))
64
65 foreign import capi safe "fcntl.h posix_fadvise"
66   c_posix_fadvise :: CInt -> COff -> COff -> CInt -> IO CInt
67
68 packAdvice :: Advice -> CInt
69 packAdvice AdviceNormal     = (#const POSIX_FADV_NORMAL)
70 packAdvice AdviceRandom     = (#const POSIX_FADV_RANDOM)
71 packAdvice AdviceSequential = (#const POSIX_FADV_SEQUENTIAL)
72 packAdvice AdviceWillNeed   = (#const POSIX_FADV_WILLNEED)
73 packAdvice AdviceDontNeed   = (#const POSIX_FADV_DONTNEED)
74 packAdvice AdviceNoReuse    = (#const POSIX_FADV_NOREUSE)
75 #else
76 fileAdvise _ _ _ _ = return ()
77 #endif
78
79 -- | Performs @posix_fallocate(2)@ operation on file-descriptor.
80 --
81 -- Throws 'IOError' (\"unsupported operation\") if platform does not
82 -- provide @posix_fallocate(2)@.
83 --
84 -- (use @#if HAVE_POSIX_FALLOCATE@ CPP guard to detect availability).
85 --
86 -- /Since: 2.7.1.0/
87 fileAllocate :: Fd -> FileOffset -> FileOffset -> IO ()
88 #if HAVE_POSIX_FALLOCATE
89 fileAllocate fd off len = do
90   throwErrnoIfMinus1_ "fileAllocate" (c_posix_fallocate (fromIntegral fd) (fromIntegral off) (fromIntegral len))
91
92 foreign import capi safe "fcntl.h posix_fallocate"
93   c_posix_fallocate :: CInt -> COff -> COff -> IO CInt
94 #else
95 {-# WARNING fileAllocate
96     "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_POSIX_FALLOCATE@)" #-}
97 fileAllocate _ _ _ = ioError (ioeSetLocation unsupportedOperation
98                               "fileAllocate")
99 #endif