Movatterモバイル変換


[0]ホーム

URL:


{-# LANGUAGE Trustworthy #-}{-# LANGUAGE CPP, NoImplicitPrelude #-}------------------------------------------------------------------------------- |-- Module      :  GHC.IO.Handle.FD-- Copyright   :  (c) The University of Glasgow, 1994-2008-- License     :  see libraries/base/LICENSE---- Maintainer  :  libraries@haskell.org-- Stability   :  internal-- Portability :  non-portable---- Handle operations implemented by file descriptors (FDs)-------------------------------------------------------------------------------moduleGHC.IO.Handle.FD(stdin,stdout,stderr,openFile,openBinaryFile,openFileBlocking,mkHandleFromFD,fdToHandle,fdToHandle',handleToFd)whereimportGHC.BaseimportGHC.ShowimportData.MaybeimportData.TypeableimportForeign.C.TypesimportGHC.MVarimportGHC.IOimportGHC.IO.EncodingimportGHC.IO.DeviceasIODeviceimportGHC.IO.ExceptionimportGHC.IO.IOModeimportGHC.IO.Handle.TypesimportGHC.IO.Handle.InternalsimportqualifiedGHC.IO.FDasFDimportqualifiedSystem.Posix.InternalsasPosix-- ----------------------------------------------------------------------------- Standard Handles-- Three handles are allocated during program initialisation.  The first-- two manage input or output from the Haskell program's standard input-- or output channel respectively.  The third manages output to the-- standard error channel. These handles are initially open.-- | A handle managing input from the Haskell program's standard input channel.stdin::Handle{-# NOINLINEstdin#-}stdin=unsafePerformIO$do-- ToDo: acquire locksetBinaryModeFD.stdinenc<-getLocaleEncodingmkHandleFD.stdin"<stdin>"ReadHandleTrue(Justenc)nativeNewlineMode{-translate newlines-}(JuststdHandleFinalizer)Nothing-- | A handle managing output to the Haskell program's standard output channel.stdout::Handle{-# NOINLINEstdout#-}stdout=unsafePerformIO$do-- ToDo: acquire locksetBinaryModeFD.stdoutenc<-getLocaleEncodingmkHandleFD.stdout"<stdout>"WriteHandleTrue(Justenc)nativeNewlineMode{-translate newlines-}(JuststdHandleFinalizer)Nothing-- | A handle managing output to the Haskell program's standard error channel.stderr::Handle{-# NOINLINEstderr#-}stderr=unsafePerformIO$do-- ToDo: acquire locksetBinaryModeFD.stderrenc<-getLocaleEncodingmkHandleFD.stderr"<stderr>"WriteHandleFalse{-stderr is unbuffered-}(Justenc)nativeNewlineMode{-translate newlines-}(JuststdHandleFinalizer)NothingstdHandleFinalizer::FilePath->MVarHandle__->IO()stdHandleFinalizerfpm=doh_<-takeMVarmflushWriteBufferh_casehaTypeh_ofClosedHandle->return()_other->closeTextCodecsh_putMVarm(ioe_finalizedHandlefp)-- We have to put the FDs into binary mode on Windows to avoid the newline-- translation that the CRT IO library does.setBinaryMode::FD.FD->IO()#if defined(mingw32_HOST_OS)setBinaryModefd=do_<-setmode(FD.fdFDfd)Truereturn()#elsesetBinaryMode_=return()#endif#if defined(mingw32_HOST_OS)foreignimportccallunsafe"__hscore_setmode"setmode::CInt->Bool->IOCInt#endif-- ----------------------------------------------------------------------------- Opening and Closing FilesaddFilePathToIOError::String->FilePath->IOException->IOExceptionaddFilePathToIOErrorfunfpioe=ioe{ioe_location=fun,ioe_filename=Justfp}-- | Computation 'openFile' @file mode@ allocates and returns a new, open-- handle to manage the file @file@.  It manages input if @mode@-- is 'ReadMode', output if @mode@ is 'WriteMode' or 'AppendMode',-- and both input and output if mode is 'ReadWriteMode'.---- If the file does not exist and it is opened for output, it should be-- created as a new file.  If @mode@ is 'WriteMode' and the file-- already exists, then it should be truncated to zero length.-- Some operating systems delete empty files, so there is no guarantee-- that the file will exist following an 'openFile' with @mode@-- 'WriteMode' unless it is subsequently written to successfully.-- The handle is positioned at the end of the file if @mode@ is-- 'AppendMode', and otherwise at the beginning (in which case its-- internal position is 0).-- The initial buffer mode is implementation-dependent.---- This operation may fail with:----  * 'isAlreadyInUseError' if the file is already open and cannot be reopened;----  * 'isDoesNotExistError' if the file does not exist; or----  * 'isPermissionError' if the user does not have permission to open the file.---- Note: if you will be working with files containing binary data, you'll want to-- be using 'openBinaryFile'.openFile::FilePath->IOMode->IOHandleopenFilefpim=catchException(openFile'fpimdEFAULT_OPEN_IN_BINARY_MODETrue)(\e->ioError(addFilePathToIOError"openFile"fpe))-- | Like 'openFile', but opens the file in ordinary blocking mode.-- This can be useful for opening a FIFO for writing: if we open in-- non-blocking mode then the open will fail if there are no readers,-- whereas a blocking open will block until a reader appear.---- @since 4.4.0.0openFileBlocking::FilePath->IOMode->IOHandleopenFileBlockingfpim=catchException(openFile'fpimdEFAULT_OPEN_IN_BINARY_MODEFalse)(\e->ioError(addFilePathToIOError"openFile"fpe))-- | Like 'openFile', but open the file in binary mode.-- On Windows, reading a file in text mode (which is the default)-- will translate CRLF to LF, and writing will translate LF to CRLF.-- This is usually what you want with text files.  With binary files-- this is undesirable; also, as usual under Microsoft operating systems,-- text mode treats control-Z as EOF.  Binary mode turns off all special-- treatment of end-of-line and end-of-file characters.-- (See also 'hSetBinaryMode'.)openBinaryFile::FilePath->IOMode->IOHandleopenBinaryFilefpm=catchException(openFile'fpmTrueTrue)(\e->ioError(addFilePathToIOError"openBinaryFile"fpe))openFile'::String->IOMode->Bool->Bool->IOHandleopenFile'filepathiomodebinarynon_blocking=do-- first open the file to get an FD(fd,fd_type)<-FD.openFilefilepathiomodenon_blockingmb_codec<-ifbinarythenreturnNothingelsefmapJustgetLocaleEncoding-- then use it to make a HandlemkHandleFromFDfdfd_typefilepathiomodeFalse{- do not *set* non-blocking mode -}mb_codec`onException`IODevice.closefd-- NB. don't forget to close the FD if mkHandleFromFD fails, otherwise-- this FD leaks.-- ASSERT: if we just created the file, then fdToHandle' won't fail-- (so we don't need to worry about removing the newly created file--  in the event of an error).-- ----------------------------------------------------------------------------- Converting file descriptors from/to HandlesmkHandleFromFD::FD.FD->IODeviceType->FilePath-- a string describing this file descriptor (e.g. the filename)->IOMode->Bool--  *set* non-blocking mode on the FD->MaybeTextEncoding->IOHandlemkHandleFromFDfd0fd_typefilepathiomodeset_non_blockingmb_codec=do#if !defined(mingw32_HOST_OS)-- turn on non-blocking modefd<-ifset_non_blockingthenFD.setNonBlockingModefd0Trueelsereturnfd0#elselet_=set_non_blocking-- warning suppressionfd<-returnfd0#endifletnl|isJustmb_codec=nativeNewlineMode|otherwise=noNewlineTranslationcasefd_typeofDirectory->ioException(IOErrorNothingInappropriateType"openFile""is a directory"NothingNothing)Stream-- only *Streams* can be DuplexHandles.  Other read/write-- Handles must share a buffer.|ReadWriteMode<-iomode->mkDuplexHandlefdfilepathmb_codecnl_other->mkFileHandlefdfilepathiomodemb_codecnl-- | Old API kept to avoid breaking clientsfdToHandle'::CInt->MaybeIODeviceType->Bool-- is_socket on Win, non-blocking on Unix->FilePath->IOMode->Bool-- binary->IOHandlefdToHandle'fdintmb_typeis_socketfilepathiomodebinary=doletmb_stat=casemb_typeofNothing->Nothing-- mkFD will do the stat:JustRegularFile->Nothing-- no stat required for streams etc.:Justother->Just(other,0,0)(fd,fd_type)<-FD.mkFDfdintiomodemb_statis_socketis_socketenc<-ifbinarythenreturnNothingelsefmapJustgetLocaleEncodingmkHandleFromFDfdfd_typefilepathiomodeis_socketenc-- | Turn an existing file descriptor into a Handle.  This is used by-- various external libraries to make Handles.---- Makes a binary Handle.  This is for historical reasons; it should-- probably be a text Handle with the default encoding and newline-- translation instead.fdToHandle::Posix.FD->IOHandlefdToHandlefdint=doiomode<-Posix.fdGetModefdint(fd,fd_type)<-FD.mkFDfdintiomodeNothingFalse{-is_socket-}-- NB. the is_socket flag is False, meaning that:--  on Windows we're guessing this is not a socket (XXX)False{-is_nonblock-}-- file descriptors that we get from external sources are-- not put into non-blocking mode, because that would affect-- other users of the file descriptorletfd_str="<file descriptor: "++showfd++">"mkHandleFromFDfdfd_typefd_striomodeFalse{-non-block-}Nothing-- bin mode-- | Turn an existing Handle into a file descriptor. This function throws an-- IOError if the Handle does not reference a file descriptor.handleToFd::Handle->IOFD.FDhandleToFdh=casehofFileHandle_mv->doHandle__{haDevice=dev}<-readMVarmvcasecastdevofJustfd->returnfdNothing->throwErr"not a file descriptor"DuplexHandle{}->throwErr"not a file handle"wherethrowErrmsg=ioException$IOError(Justh)InappropriateType"handleToFd"msgNothingNothing-- ----------------------------------------------------------------------------- Are files opened by default in text or binary mode, if the user doesn't-- specify?dEFAULT_OPEN_IN_BINARY_MODE::BooldEFAULT_OPEN_IN_BINARY_MODE=False

[8]ページ先頭

©2009-2025 Movatter.jp