1
{-# LANGUAGE ForeignFunctionInterface #-}
2
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
3
-----------------------------------------------------------------------------
5
-- Module : System.Posix.Files
6
-- Copyright : (c) The University of Glasgow 2002
7
-- License : BSD-style (see the file libraries/base/LICENSE)
9
-- Maintainer : libraries@haskell.org
10
-- Stability : provisional
11
-- Portability : non-portable (requires POSIX)
13
-- Functions defined by the POSIX standards for manipulating and querying the
14
-- file system. Names of underlying POSIX functions are indicated whenever
15
-- possible. A more complete documentation of the POSIX functions together
16
-- with a more detailed description of different error conditions are usually
17
-- available in the system's manual pages or from
18
-- <http://www.unix.org/version3/online.html> (free registration required).
20
-- When a function that calls an underlying POSIX function fails, the errno
21
-- code is converted to an 'IOError' using 'Foreign.C.Error.errnoToIOError'.
22
-- For a list of which errno codes may be generated, consult the POSIX
23
-- documentation for the underlying function.
25
-----------------------------------------------------------------------------
27
module System.Posix.Files (
29
-- FileMode exported by System.Posix.Types
30
unionFileModes, intersectFileModes,
32
ownerReadMode, ownerWriteMode, ownerExecuteMode, ownerModes,
33
groupReadMode, groupWriteMode, groupExecuteMode, groupModes,
34
otherReadMode, otherWriteMode, otherExecuteMode, otherModes,
35
setUserIDMode, setGroupIDMode,
36
stdFileMode, accessModes,
38
blockSpecialMode, characterSpecialMode, namedPipeMode, regularFileMode,
39
directoryMode, symbolicLinkMode, socketMode,
41
-- ** Setting file modes
42
setFileMode, setFdMode, setFileCreationMask,
44
-- ** Checking file existence and permissions
45
fileAccess, fileExist,
49
-- ** Obtaining file status
50
getFileStatus, getFdStatus, getSymbolicLinkStatus,
51
-- ** Querying file status
52
deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup,
53
specialDeviceID, fileSize, accessTime, modificationTime,
55
isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,
56
isDirectory, isSymbolicLink, isSocket,
63
createLink, removeLink,
66
createSymbolicLink, readSymbolicLink,
71
-- * Changing file ownership
72
setOwnerAndGroup, setFdOwnerAndGroup,
74
setSymbolicLinkOwnerAndGroup,
77
-- * Changing file timestamps
78
setFileTimes, touchFile,
80
-- * Setting file sizes
81
setFileSize, setFdSize,
83
-- * Find system-specific limits for a file
84
PathVar(..), getPathVar, getFdPathVar,
89
import System.Posix.Error
90
import System.Posix.Types
91
import System.IO.Unsafe
93
import System.Posix.Internals
94
import Foreign hiding (unsafePerformIO)
97
-- -----------------------------------------------------------------------------
100
-- The abstract type 'FileMode', constants and operators for
101
-- manipulating the file modes defined by POSIX.
104
nullFileMode :: FileMode
107
-- | Owner has read permission.
108
ownerReadMode :: FileMode
109
ownerReadMode = (#const S_IRUSR)
111
-- | Owner has write permission.
112
ownerWriteMode :: FileMode
113
ownerWriteMode = (#const S_IWUSR)
115
-- | Owner has execute permission.
116
ownerExecuteMode :: FileMode
117
ownerExecuteMode = (#const S_IXUSR)
119
-- | Group has read permission.
120
groupReadMode :: FileMode
121
groupReadMode = (#const S_IRGRP)
123
-- | Group has write permission.
124
groupWriteMode :: FileMode
125
groupWriteMode = (#const S_IWGRP)
127
-- | Group has execute permission.
128
groupExecuteMode :: FileMode
129
groupExecuteMode = (#const S_IXGRP)
131
-- | Others have read permission.
132
otherReadMode :: FileMode
133
otherReadMode = (#const S_IROTH)
135
-- | Others have write permission.
136
otherWriteMode :: FileMode
137
otherWriteMode = (#const S_IWOTH)
139
-- | Others have execute permission.
140
otherExecuteMode :: FileMode
141
otherExecuteMode = (#const S_IXOTH)
143
-- | Set user ID on execution.
144
setUserIDMode :: FileMode
145
setUserIDMode = (#const S_ISUID)
147
-- | Set group ID on execution.
148
setGroupIDMode :: FileMode
149
setGroupIDMode = (#const S_ISGID)
151
-- | Owner, group and others have read and write permission.
152
stdFileMode :: FileMode
153
stdFileMode = ownerReadMode .|. ownerWriteMode .|.
154
groupReadMode .|. groupWriteMode .|.
155
otherReadMode .|. otherWriteMode
157
-- | Owner has read, write and execute permission.
158
ownerModes :: FileMode
159
ownerModes = (#const S_IRWXU)
161
-- | Group has read, write and execute permission.
162
groupModes :: FileMode
163
groupModes = (#const S_IRWXG)
165
-- | Others have read, write and execute permission.
166
otherModes :: FileMode
167
otherModes = (#const S_IRWXO)
169
-- | Owner, group and others have read, write and execute permission.
170
accessModes :: FileMode
171
accessModes = ownerModes .|. groupModes .|. otherModes
173
-- | Combines the two file modes into one that contains modes that appear in
175
unionFileModes :: FileMode -> FileMode -> FileMode
176
unionFileModes m1 m2 = m1 .|. m2
178
-- | Combines two file modes into one that only contains modes that appear in
180
intersectFileModes :: FileMode -> FileMode -> FileMode
181
intersectFileModes m1 m2 = m1 .&. m2
183
fileTypeModes :: FileMode
184
fileTypeModes = (#const S_IFMT)
186
blockSpecialMode :: FileMode
187
blockSpecialMode = (#const S_IFBLK)
189
characterSpecialMode :: FileMode
190
characterSpecialMode = (#const S_IFCHR)
192
namedPipeMode :: FileMode
193
namedPipeMode = (#const S_IFIFO)
195
regularFileMode :: FileMode
196
regularFileMode = (#const S_IFREG)
198
directoryMode :: FileMode
199
directoryMode = (#const S_IFDIR)
201
symbolicLinkMode :: FileMode
202
symbolicLinkMode = (#const S_IFLNK)
204
socketMode :: FileMode
205
socketMode = (#const S_IFSOCK)
207
-- | @setFileMode path mode@ changes permission of the file given by @path@
208
-- to @mode@. This operation may fail with 'throwErrnoPathIfMinus1_' if @path@
209
-- doesn't exist or if the effective user ID of the current process is not that
210
-- of the file's owner.
212
-- Note: calls @chmod@.
213
setFileMode :: FilePath -> FileMode -> IO ()
215
withCString name $ \s -> do
216
throwErrnoPathIfMinus1_ "setFileMode" name (c_chmod s m)
218
-- | @setFdMode fd mode@ acts like 'setFileMode' but uses a file descriptor
219
-- @fd@ instead of a 'FilePath'.
221
-- Note: calls @fchmod@.
222
setFdMode :: Fd -> FileMode -> IO ()
223
setFdMode (Fd fd) m =
224
throwErrnoIfMinus1_ "setFdMode" (c_fchmod fd m)
226
foreign import ccall unsafe "fchmod"
227
c_fchmod :: CInt -> CMode -> IO CInt
229
-- | @setFileCreationMask mode@ sets the file mode creation mask to @mode@.
230
-- Modes set by this operation are subtracted from files and directories upon
231
-- creation. The previous file creation mask is returned.
233
-- Note: calls @umask@.
234
setFileCreationMask :: FileMode -> IO FileMode
235
setFileCreationMask mask = c_umask mask
237
-- -----------------------------------------------------------------------------
240
-- | @fileAccess name read write exec@ checks if the file (or other file system
241
-- object) @name@ can be accessed for reading, writing and\/or executing. To
242
-- check a permission set the corresponding argument to 'True'.
244
-- Note: calls @access@.
245
fileAccess :: FilePath -> Bool -> Bool -> Bool -> IO Bool
246
fileAccess name readOK writeOK execOK = access name flags
248
flags = read_f .|. write_f .|. exec_f
249
read_f = if readOK then (#const R_OK) else 0
250
write_f = if writeOK then (#const W_OK) else 0
251
exec_f = if execOK then (#const X_OK) else 0
253
-- | Checks for the existence of the file.
255
-- Note: calls @access@.
256
fileExist :: FilePath -> IO Bool
258
withCString name $ \s -> do
259
r <- c_access s (#const F_OK)
262
else do err <- getErrno
265
else throwErrnoPath "fileExist" name
267
access :: FilePath -> CMode -> IO Bool
269
withCString name $ \s -> do
270
r <- c_access s (fromIntegral flags)
273
else do err <- getErrno
276
else throwErrnoPath "fileAccess" name
278
-- -----------------------------------------------------------------------------
281
-- | POSIX defines operations to get information, such as owner, permissions,
282
-- size and access times, about a file. This information is represented by the
283
-- 'FileStatus' type.
285
-- Note: see @chmod@.
286
newtype FileStatus = FileStatus (ForeignPtr CStat)
288
-- | ID of the device on which this file resides.
289
deviceID :: FileStatus -> DeviceID
291
fileID :: FileStatus -> FileID
292
-- | File mode (such as permissions).
293
fileMode :: FileStatus -> FileMode
294
-- | Number of hard links to this file.
295
linkCount :: FileStatus -> LinkCount
297
fileOwner :: FileStatus -> UserID
299
fileGroup :: FileStatus -> GroupID
300
-- | Describes the device that this file represents.
301
specialDeviceID :: FileStatus -> DeviceID
302
-- | Size of the file in bytes. If this file is a symbolic link the size is
303
-- the length of the pathname it contains.
304
fileSize :: FileStatus -> FileOffset
305
-- | Time of last access.
306
accessTime :: FileStatus -> EpochTime
307
-- | Time of last modification.
308
modificationTime :: FileStatus -> EpochTime
309
-- | Time of last status change (i.e. owner, group, link count, mode, etc.).
310
statusChangeTime :: FileStatus -> EpochTime
312
deviceID (FileStatus stat) =
313
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_dev)
314
fileID (FileStatus stat) =
315
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_ino)
316
fileMode (FileStatus stat) =
317
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_mode)
318
linkCount (FileStatus stat) =
319
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_nlink)
320
fileOwner (FileStatus stat) =
321
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_uid)
322
fileGroup (FileStatus stat) =
323
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_gid)
324
specialDeviceID (FileStatus stat) =
325
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_rdev)
326
fileSize (FileStatus stat) =
327
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_size)
328
accessTime (FileStatus stat) =
329
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_atime)
330
modificationTime (FileStatus stat) =
331
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_mtime)
332
statusChangeTime (FileStatus stat) =
333
unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_ctime)
335
-- | Checks if this file is a block device.
336
isBlockDevice :: FileStatus -> Bool
337
-- | Checks if this file is a character device.
338
isCharacterDevice :: FileStatus -> Bool
339
-- | Checks if this file is a named pipe device.
340
isNamedPipe :: FileStatus -> Bool
341
-- | Checks if this file is a regular file device.
342
isRegularFile :: FileStatus -> Bool
343
-- | Checks if this file is a directory device.
344
isDirectory :: FileStatus -> Bool
345
-- | Checks if this file is a symbolic link device.
346
isSymbolicLink :: FileStatus -> Bool
347
-- | Checks if this file is a socket device.
348
isSocket :: FileStatus -> Bool
351
(fileMode stat `intersectFileModes` fileTypeModes) == blockSpecialMode
352
isCharacterDevice stat =
353
(fileMode stat `intersectFileModes` fileTypeModes) == characterSpecialMode
355
(fileMode stat `intersectFileModes` fileTypeModes) == namedPipeMode
357
(fileMode stat `intersectFileModes` fileTypeModes) == regularFileMode
359
(fileMode stat `intersectFileModes` fileTypeModes) == directoryMode
360
isSymbolicLink stat =
361
(fileMode stat `intersectFileModes` fileTypeModes) == symbolicLinkMode
363
(fileMode stat `intersectFileModes` fileTypeModes) == socketMode
365
-- | @getFileStatus path@ calls gets the @FileStatus@ information (user ID,
366
-- size, access times, etc.) for the file @path@.
368
-- Note: calls @stat@.
369
getFileStatus :: FilePath -> IO FileStatus
370
getFileStatus path = do
371
fp <- mallocForeignPtrBytes (#const sizeof(struct stat))
372
withForeignPtr fp $ \p ->
373
withCString path $ \s ->
374
throwErrnoPathIfMinus1_ "getFileStatus" path (c_stat s p)
375
return (FileStatus fp)
377
-- | @getFdStatus fd@ acts as 'getFileStatus' but uses a file descriptor @fd@.
379
-- Note: calls @fstat@.
380
getFdStatus :: Fd -> IO FileStatus
381
getFdStatus (Fd fd) = do
382
fp <- mallocForeignPtrBytes (#const sizeof(struct stat))
383
withForeignPtr fp $ \p ->
384
throwErrnoIfMinus1_ "getFdStatus" (c_fstat fd p)
385
return (FileStatus fp)
387
-- | Acts as 'getFileStatus' except when the 'FilePath' refers to a symbolic
388
-- link. In that case the @FileStatus@ information of the symbolic link itself
389
-- is returned instead of that of the file it points to.
391
-- Note: calls @lstat@.
392
getSymbolicLinkStatus :: FilePath -> IO FileStatus
393
getSymbolicLinkStatus path = do
394
fp <- mallocForeignPtrBytes (#const sizeof(struct stat))
395
withForeignPtr fp $ \p ->
396
withCString path $ \s ->
397
throwErrnoPathIfMinus1_ "getSymbolicLinkStatus" path (c_lstat s p)
398
return (FileStatus fp)
400
foreign import ccall unsafe "__hsunix_lstat"
401
c_lstat :: CString -> Ptr CStat -> IO CInt
403
-- | @createNamedPipe fifo mode@
404
-- creates a new named pipe, @fifo@, with permissions based on
405
-- @mode@. May fail with 'throwErrnoPathIfMinus1_' if a file named @name@
406
-- already exists or if the effective user ID of the current process doesn't
407
-- have permission to create the pipe.
409
-- Note: calls @mkfifo@.
410
createNamedPipe :: FilePath -> FileMode -> IO ()
411
createNamedPipe name mode = do
412
withCString name $ \s ->
413
throwErrnoPathIfMinus1_ "createNamedPipe" name (c_mkfifo s mode)
415
-- | @createDevice path mode dev@ creates either a regular or a special file
416
-- depending on the value of @mode@ (and @dev@). @mode@ will normally be either
417
-- 'blockSpecialMode' or 'characterSpecialMode'. May fail with
418
-- 'throwErrnoPathIfMinus1_' if a file named @name@ already exists or if the
419
-- effective user ID of the current process doesn't have permission to create
422
-- Note: calls @mknod@.
423
createDevice :: FilePath -> FileMode -> DeviceID -> IO ()
424
createDevice path mode dev =
425
withCString path $ \s ->
426
throwErrnoPathIfMinus1_ "createDevice" path (c_mknod s mode dev)
428
foreign import ccall unsafe "__hsunix_mknod"
429
c_mknod :: CString -> CMode -> CDev -> IO CInt
431
-- -----------------------------------------------------------------------------
434
-- | @createLink old new@ creates a new path, @new@, linked to an existing file,
437
-- Note: calls @link@.
438
createLink :: FilePath -> FilePath -> IO ()
439
createLink name1 name2 =
440
withCString name1 $ \s1 ->
441
withCString name2 $ \s2 ->
442
throwErrnoPathIfMinus1_ "createLink" name1 (c_link s1 s2)
444
-- | @removeLink path@ removes the link named @path@.
446
-- Note: calls @unlink@.
447
removeLink :: FilePath -> IO ()
449
withCString name $ \s ->
450
throwErrnoPathIfMinus1_ "removeLink" name (c_unlink s)
452
-- -----------------------------------------------------------------------------
455
-- | @createSymbolicLink file1 file2@ creates a symbolic link named @file2@
456
-- which points to the file @file1@.
458
-- Symbolic links are interpreted at run-time as if the contents of the link
459
-- had been substituted into the path being followed to find a file or directory.
461
-- Note: calls @symlink@.
462
createSymbolicLink :: FilePath -> FilePath -> IO ()
463
createSymbolicLink file1 file2 =
464
withCString file1 $ \s1 ->
465
withCString file2 $ \s2 ->
466
throwErrnoPathIfMinus1_ "createSymbolicLink" file1 (c_symlink s1 s2)
468
foreign import ccall unsafe "symlink"
469
c_symlink :: CString -> CString -> IO CInt
471
-- ToDo: should really use SYMLINK_MAX, but not everyone supports it yet,
472
-- and it seems that the intention is that SYMLINK_MAX is no larger than
474
#if !defined(PATH_MAX)
475
-- PATH_MAX is not defined on systems with unlimited path length.
477
#define PATH_MAX 4096
480
-- | Reads the @FilePath@ pointed to by the symbolic link and returns it.
482
-- Note: calls @readlink@.
483
readSymbolicLink :: FilePath -> IO FilePath
484
readSymbolicLink file =
485
allocaArray0 (#const PATH_MAX) $ \buf -> do
486
withCString file $ \s -> do
487
len <- throwErrnoPathIfMinus1 "readSymbolicLink" file $
488
c_readlink s buf (#const PATH_MAX)
489
peekCStringLen (buf,fromIntegral len)
491
foreign import ccall unsafe "readlink"
492
c_readlink :: CString -> CString -> CSize -> IO CInt
494
-- -----------------------------------------------------------------------------
497
-- | @rename old new@ renames a file or directory from @old@ to @new@.
499
-- Note: calls @rename@.
500
rename :: FilePath -> FilePath -> IO ()
502
withCString name1 $ \s1 ->
503
withCString name2 $ \s2 ->
504
throwErrnoPathIfMinus1_ "rename" name1 (c_rename s1 s2)
506
foreign import ccall unsafe "rename"
507
c_rename :: CString -> CString -> IO CInt
509
-- -----------------------------------------------------------------------------
512
-- | @setOwnerAndGroup path uid gid@ changes the owner and group of @path@ to
513
-- @uid@ and @gid@, respectively.
515
-- If @uid@ or @gid@ is specified as -1, then that ID is not changed.
517
-- Note: calls @chown@.
518
setOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO ()
519
setOwnerAndGroup name uid gid = do
520
withCString name $ \s ->
521
throwErrnoPathIfMinus1_ "setOwnerAndGroup" name (c_chown s uid gid)
523
foreign import ccall unsafe "chown"
524
c_chown :: CString -> CUid -> CGid -> IO CInt
526
-- | Acts as 'setOwnerAndGroup' but uses a file descriptor instead of a
529
-- Note: calls @fchown@.
530
setFdOwnerAndGroup :: Fd -> UserID -> GroupID -> IO ()
531
setFdOwnerAndGroup (Fd fd) uid gid =
532
throwErrnoIfMinus1_ "setFdOwnerAndGroup" (c_fchown fd uid gid)
534
foreign import ccall unsafe "fchown"
535
c_fchown :: CInt -> CUid -> CGid -> IO CInt
538
-- | Acts as 'setOwnerAndGroup' but does not follow symlinks (and thus
539
-- changes permissions on the link itself).
541
-- Note: calls @lchown@.
542
setSymbolicLinkOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO ()
543
setSymbolicLinkOwnerAndGroup name uid gid = do
544
withCString name $ \s ->
545
throwErrnoPathIfMinus1_ "setSymbolicLinkOwnerAndGroup" name
548
foreign import ccall unsafe "lchown"
549
c_lchown :: CString -> CUid -> CGid -> IO CInt
552
-- -----------------------------------------------------------------------------
555
-- | @setFileTimes path atime mtime@ sets the access and modification times
556
-- associated with file @path@ to @atime@ and @mtime@, respectively.
558
-- Note: calls @utime@.
559
setFileTimes :: FilePath -> EpochTime -> EpochTime -> IO ()
560
setFileTimes name atime mtime = do
561
withCString name $ \s ->
562
allocaBytes (#const sizeof(struct utimbuf)) $ \p -> do
563
(#poke struct utimbuf, actime) p atime
564
(#poke struct utimbuf, modtime) p mtime
565
throwErrnoPathIfMinus1_ "setFileTimes" name (c_utime s p)
567
-- | @touchFile path@ sets the access and modification times associated with
568
-- file @path@ to the current time.
570
-- Note: calls @utime@.
571
touchFile :: FilePath -> IO ()
573
withCString name $ \s ->
574
throwErrnoPathIfMinus1_ "touchFile" name (c_utime s nullPtr)
576
-- -----------------------------------------------------------------------------
577
-- Setting file sizes
579
-- | Truncates the file down to the specified length. If the file was larger
580
-- than the given length before this operation was performed the extra is lost.
582
-- Note: calls @truncate@.
583
setFileSize :: FilePath -> FileOffset -> IO ()
584
setFileSize file off =
585
withCString file $ \s ->
586
throwErrnoPathIfMinus1_ "setFileSize" file (c_truncate s off)
588
foreign import ccall unsafe "truncate"
589
c_truncate :: CString -> COff -> IO CInt
591
-- | Acts as 'setFileSize' but uses a file descriptor instead of a 'FilePath'.
593
-- Note: calls @ftruncate@.
594
setFdSize :: Fd -> FileOffset -> IO ()
595
setFdSize (Fd fd) off =
596
throwErrnoIfMinus1_ "setFdSize" (c_ftruncate fd off)
598
-- -----------------------------------------------------------------------------
599
-- pathconf()/fpathconf() support
602
= FileSizeBits {- _PC_FILESIZEBITS -}
603
| LinkLimit {- _PC_LINK_MAX -}
604
| InputLineLimit {- _PC_MAX_CANON -}
605
| InputQueueLimit {- _PC_MAX_INPUT -}
606
| FileNameLimit {- _PC_NAME_MAX -}
607
| PathNameLimit {- _PC_PATH_MAX -}
608
| PipeBufferLimit {- _PC_PIPE_BUF -}
609
-- These are described as optional in POSIX:
610
{- _PC_ALLOC_SIZE_MIN -}
611
{- _PC_REC_INCR_XFER_SIZE -}
612
{- _PC_REC_MAX_XFER_SIZE -}
613
{- _PC_REC_MIN_XFER_SIZE -}
614
{- _PC_REC_XFER_ALIGN -}
615
| SymbolicLinkLimit {- _PC_SYMLINK_MAX -}
616
| SetOwnerAndGroupIsRestricted {- _PC_CHOWN_RESTRICTED -}
617
| FileNamesAreNotTruncated {- _PC_NO_TRUNC -}
618
| VDisableChar {- _PC_VDISABLE -}
619
| AsyncIOAvailable {- _PC_ASYNC_IO -}
620
| PrioIOAvailable {- _PC_PRIO_IO -}
621
| SyncIOAvailable {- _PC_SYNC_IO -}
623
pathVarConst :: PathVar -> CInt
624
pathVarConst v = case v of
625
LinkLimit -> (#const _PC_LINK_MAX)
626
InputLineLimit -> (#const _PC_MAX_CANON)
627
InputQueueLimit -> (#const _PC_MAX_INPUT)
628
FileNameLimit -> (#const _PC_NAME_MAX)
629
PathNameLimit -> (#const _PC_PATH_MAX)
630
PipeBufferLimit -> (#const _PC_PIPE_BUF)
631
SetOwnerAndGroupIsRestricted -> (#const _PC_CHOWN_RESTRICTED)
632
FileNamesAreNotTruncated -> (#const _PC_NO_TRUNC)
633
VDisableChar -> (#const _PC_VDISABLE)
636
SyncIOAvailable -> (#const _PC_SYNC_IO)
638
SyncIOAvailable -> error "_PC_SYNC_IO not available"
642
AsyncIOAvailable -> (#const _PC_ASYNC_IO)
644
AsyncIOAvailable -> error "_PC_ASYNC_IO not available"
648
PrioIOAvailable -> (#const _PC_PRIO_IO)
650
PrioIOAvailable -> error "_PC_PRIO_IO not available"
654
FileSizeBits -> (#const _PC_FILESIZEBITS)
656
FileSizeBits -> error "_PC_FILESIZEBITS not available"
660
SymbolicLinkLimit -> (#const _PC_SYMLINK_MAX)
662
SymbolicLinkLimit -> error "_PC_SYMLINK_MAX not available"
666
-- | @getPathVar var path@ obtains the dynamic value of the requested
667
-- configurable file limit or option associated with file or directory @path@.
668
-- For defined file limits, @getPathVar@ returns the associated
669
-- value. For defined file options, the result of @getPathVar@
670
-- is undefined, but not failure.
672
-- Note: calls @pathconf@.
673
getPathVar :: FilePath -> PathVar -> IO Limit
674
getPathVar name v = do
675
withCString name $ \ nameP ->
676
throwErrnoPathIfMinus1 "getPathVar" name $
677
c_pathconf nameP (pathVarConst v)
679
foreign import ccall unsafe "pathconf"
680
c_pathconf :: CString -> CInt -> IO CLong
683
-- | @getFdPathVar var fd@ obtains the dynamic value of the requested
684
-- configurable file limit or option associated with the file or directory
685
-- attached to the open channel @fd@. For defined file limits, @getFdPathVar@
686
-- returns the associated value. For defined file options, the result of
687
-- @getFdPathVar@ is undefined, but not failure.
689
-- Note: calls @fpathconf@.
690
getFdPathVar :: Fd -> PathVar -> IO Limit
691
getFdPathVar (Fd fd) v =
692
throwErrnoIfMinus1 "getFdPathVar" $
693
c_fpathconf fd (pathVarConst v)
695
foreign import ccall unsafe "fpathconf"
696
c_fpathconf :: CInt -> CInt -> IO CLong