    {-# LINE 1 "System/DiskSpace.hsc" #-}
    {-# LANGUAGE CPP #-}

    {- |
    Module      : System.DiskSpace

    Stability   : provisional
    Portability : portable
    -}

    module System.DiskSpace
        ( DiskUsage(..)
        , getDiskUsage
        , getAvailSpace
        ) where

    {-# LINE 17 "System/DiskSpace.hsc" #-}

    import Foreign
    import Foreign.C

    foreign import ccall safe statvfs :: CString -> Ptr a -> IO CInt

    type FsBlkCnt = Word64
    {-# LINE 26 "System/DiskSpace.hsc" #-}

    getDiskUsage :: FilePath -> IO DiskUsage
    getDiskUsage FilePath
    path =
        FilePath -> (CString -> IO DiskUsage) -> IO DiskUsage
    forall a. FilePath -> (CString -> IO a) -> IO a
    withCString FilePath
    path ((CString -> IO DiskUsage) -> IO DiskUsage)
    -> (CString -> IO DiskUsage) -> IO DiskUsage
    forall a b. (a -> b) -> a -> b
    $ \CString
    cPath ->
            Int -> (Ptr (ZonkAny 0) -> IO DiskUsage) -> IO DiskUsage
    forall a b. Int -> (Ptr a -> IO b) -> IO b
    allocaBytes ((Int
    112)) ((Ptr (ZonkAny 0) -> IO DiskUsage) -> IO DiskUsage)
    -> (Ptr (ZonkAny 0) -> IO DiskUsage) -> IO DiskUsage
    forall a b. (a -> b) -> a -> b
    $ \Ptr (ZonkAny 0)
    stat -> do
    {-# LINE 30 "System/DiskSpace.hsc" #-}
                throwErrnoPathIfMinus1_ "getDiskUsage" path $ statvfs cPath stat
                bsize  <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) stat :: IO CULong
    {-# LINE 32 "System/DiskSpace.hsc" #-}
                frsize <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) stat :: IO CULong
    {-# LINE 33 "System/DiskSpace.hsc" #-}
                blocks <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) stat :: IO FsBlkCnt
    {-# LINE 34 "System/DiskSpace.hsc" #-}
                bfree  <- ((\hsc_ptr -> peekByteOff hsc_ptr 24)) stat :: IO FsBlkCnt
    {-# LINE 35 "System/DiskSpace.hsc" #-}
                bavail <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) stat :: IO FsBlkCnt
    {-# LINE 36 "System/DiskSpace.hsc" #-}
                let frsize' = fromIntegral frsize
                return DiskUsage
                    { diskTotal = frsize' * fromIntegral blocks
                    , diskFree  = frsize' * fromIntegral bfree
                    , diskAvail = frsize' * fromIntegral bavail
                    , blockSize = fromIntegral bsize
                    }

    {-# LINE 61 "System/DiskSpace.hsc" #-}

    -- | Disk usage information. All fields are in bytes.
    data DiskUsage = DiskUsage
        { DiskUsage -> Integer
    diskTotal :: Integer -- ^ The total size of the file system.
        , DiskUsage -> Integer
    diskFree  :: Integer -- ^ The amount of free space. You probably want to
                               --   use 'diskAvail' instead.
        , DiskUsage -> Integer
    diskAvail :: Integer -- ^ The amount of space available to the user.
                               --   Might be less than 'diskFree'. On Windows,
                               --   this is always equal to 'diskFree'.
                               --   This is what most tools report as free
                               --   space (e.g. the unix @df@ tool).
        , DiskUsage -> Int
    blockSize :: Int     -- ^ The optimal block size for I/O in this volume.
                               --   Some operating systems report incorrect values
                               --   for this field.
        }
      deriving (Int -> DiskUsage -> ShowS
    [DiskUsage] -> ShowS
    DiskUsage -> FilePath
    (Int -> DiskUsage -> ShowS)
    -> (DiskUsage -> FilePath)
    -> ([DiskUsage] -> ShowS)
    -> Show DiskUsage
    forall a.
    (Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DiskUsage -> ShowS
    showsPrec :: Int -> DiskUsage -> ShowS
    $cshow :: DiskUsage -> FilePath
    show :: DiskUsage -> FilePath
    $cshowList :: [DiskUsage] -> ShowS
    showList :: [DiskUsage] -> ShowS
    Show, DiskUsage -> DiskUsage -> Bool
    (DiskUsage -> DiskUsage -> Bool)
    -> (DiskUsage -> DiskUsage -> Bool) -> Eq DiskUsage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DiskUsage -> DiskUsage -> Bool
    == :: DiskUsage -> DiskUsage -> Bool
    $c/= :: DiskUsage -> DiskUsage -> Bool
    /= :: DiskUsage -> DiskUsage -> Bool
    Eq)

    -- | Retrieve disk usage information about a volume. The volume is
    -- specified with the @FilePath@ argument. The path can refer to the root
    -- directory or any other directory inside the volume.
    -- Unix systems also accept arbitrary files, but this
    -- does not work under Windows and therefore should be avoided if
    -- portability is desired.
    getDiskUsage :: FilePath -> IO DiskUsage

    -- | A convenience function that directly returns the 'diskAvail' field from
    -- the result of 'getDiskUsage'. If a large amount of data is to be written
    -- in a directory, calling this function for that directory can be used to
    -- determine whether the operation will fail because of insufficient disk
    -- space.
    getAvailSpace :: FilePath -> IO Integer
    getAvailSpace :: FilePath -> IO Integer
    getAvailSpace = (DiskUsage -> Integer) -> IO DiskUsage -> IO Integer
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap DiskUsage -> Integer
    diskAvail (IO DiskUsage -> IO Integer)
    -> (FilePath -> IO DiskUsage) -> FilePath -> IO Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> IO DiskUsage
    getDiskUsage