rawfilepath-0.2.4: Use RawFilePath instead of FilePath

Copyright(C) XT et al. 2017
LicenseBSD-style (see the file LICENSE)
Maintainere@xtendo.org
Stabilityexperimental
PortabilityPOSIX
Safe HaskellNone
LanguageHaskell2010

RawFilePath

Description

Welcome to RawFilePath, a small part of the Haskell community's effort to purge String for the Greater Good.

With this package, you can interact with the Unix system without the file path encoding issue or the StringByteString conversion overhead.

Rationale

Traditional String is notorious:

  • 24 bytes (three words) required for one character (the List constructor, the actual Char value, and the pointer to the next List constructor). 24x memory consumption.
  • Heap fragmentation causing malloc/free overhead
  • A lot of pointer chasing for reading, devastating the cache hit rate
  • A lot of pointer chasing plus a lot of heap object allocation for manipulation (appending, slicing, etc.)
  • Completely unnecessary but mandatory conversions and memory allocation when the data is sent to or received from the outside world

String has another problematic nature to serve as a file path data type: Encoding blindness. All functions that return FilePath would actually take a series of bytes returned by a syscall and somehow magically "decode" it into a String which is surprising because no encoding information was given. Of course there is no magic and it's an abject fail. FilePath just wouldn't work.

Usage

This is the top-level module that re-exports the sub-modules. Therefore, you can

import RawFilePath

to import all functions.

Synopsis

Documentation

doesPathExist :: RawFilePath -> IO Bool #

Test whether the given path points to an existing filesystem object. If the user lacks necessary permissions to search the parent directories, this function may return false even if the file does actually exist.

doesDirectoryExist :: RawFilePath -> IO Bool #

Return True if the argument file exists and is either a directory or a symbolic link to a directory, and False otherwise.

doesFileExist :: RawFilePath -> IO Bool #

Return True if the argument file exists and is not a directory, and False otherwise.

getHomeDirectory :: IO (Maybe RawFilePath) #

Returns the current user's home directory. More specifically, the value of the HOME environment variable.

The directory returned is expected to be writable by the current user, but note that it isn't generally considered good practice to store application-specific data here; use getXdgDirectory or getAppUserDataDirectory instead.

The operation may fail with:

  • UnsupportedOperation The operating system has no notion of home directory.
  • isDoesNotExistError The home directory for the current user does not exist, or cannot be found.

getTemporaryDirectory :: IO ByteString #

Return the current directory for temporary files. It first returns the value of the TMPDIR environment variable or "/tmp" if the variable isn't defined.

listDirectory #

Arguments

:: RawFilePath

The path of directory to inspect

-> IO [RawFilePath]

A list of files in the directory

Get a list of files in the specified directory, excluding "." and ".."

ghci> listDirectory "/"
["home","sys","var","opt","lib64","sbin","usr","srv","dev","lost+found","bin","tmp","run","root","boot","proc","etc","lib"]

getDirectoryFiles #

Arguments

:: RawFilePath

The path of directory to inspect

-> IO [RawFilePath]

A list of files in the directory

Get a list of files in the specified directory, including "." and ".."

ghci> getDirectoryFiles "/"
["home","sys","var","opt","..","lib64","sbin","usr","srv","dev","lost+found","mnt","bin","tmp","run","root","boot",".","proc","etc","lib"]

getDirectoryFilesRecursive #

Arguments

:: RawFilePath

The path of directory to inspect

-> IO [RawFilePath]

A list of relative paths

Recursively get all files in all subdirectories of the specified directory.

*System.RawFilePath> getDirectoryFilesRecursive "src"
["src/System/RawFilePath.hs"]

createDirectory :: RawFilePath -> IO () #

Create a new directory.

ghci> createDirectory "/tmp/mydir"
ghci> getDirectoryFiles "/tmp/mydir"
[".",".."]
ghci> createDirectory "/tmp/mydir/anotherdir"
ghci> getDirectoryFiles "/tmp/mydir"
[".","..","anotherdir"]

createDirectoryIfMissing #

Arguments

:: Bool

Create parent directories or not

-> RawFilePath

The path of the directory to create

-> IO () 

Create a new directory if it does not already exist. If the first argument is True the function will also create all parent directories when they are missing.

removeFile :: RawFilePath -> IO () #

Remove a file. This function internally calls unlink. If the file does not exist, an exception is thrown.

tryRemoveFile :: RawFilePath -> IO () #

A function that "tries" to remove a file. If the file does not exist, nothing happens.

removeDirectory :: RawFilePath -> IO () #

Remove a directory. The target directory needs to be empty; Otherwise an exception will be thrown.

removeDirectoryRecursive :: RawFilePath -> IO () #

Remove an existing directory dir together with its contents and subdirectories. Within this directory, symbolic links are removed without affecting their targets.

class StreamType c #

The class of types that determine the standard stream of a sub-process. You can decide how to initialize the standard streams (stdin, stdout, and stderr) of a sub-process with the instances of this class.

Instances
StreamType UseHandle # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> UseHandle -> IO FD

willCreateHandle :: UseHandle -> Bool

StreamType NoStream # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> NoStream -> IO FD

willCreateHandle :: NoStream -> Bool

StreamType Inherit # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> Inherit -> IO FD

willCreateHandle :: Inherit -> Bool

StreamType CreatePipe # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> CreatePipe -> IO FD

willCreateHandle :: CreatePipe -> Bool

data UseHandle #

Use the supplied Handle.

Constructors

UseHandle Handle 
Instances
Show UseHandle # 
Instance details

Defined in RawFilePath.Process.Common

StreamType UseHandle # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> UseHandle -> IO FD

willCreateHandle :: UseHandle -> Bool

data NoStream #

No stream handle will be passed. Use when you don't want to communicate with a stream. For example, to run something silently.

Constructors

NoStream 
Instances
Show NoStream # 
Instance details

Defined in RawFilePath.Process.Common

StreamType NoStream # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> NoStream -> IO FD

willCreateHandle :: NoStream -> Bool

data Inherit #

Inherit the parent (current) process handle. The child will share the stream. For example, if the child writes anything to stdout, it will all go to the parent's stdout.

Constructors

Inherit 
Instances
Show Inherit # 
Instance details

Defined in RawFilePath.Process.Common

StreamType Inherit # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> Inherit -> IO FD

willCreateHandle :: Inherit -> Bool

data CreatePipe #

Create a new pipe for the stream. You get a new Handle.

Constructors

CreatePipe 
Instances
Show CreatePipe # 
Instance details

Defined in RawFilePath.Process.Common

StreamType CreatePipe # 
Instance details

Defined in RawFilePath.Process.Common

Methods

mbFd :: FD -> CreatePipe -> IO FD

willCreateHandle :: CreatePipe -> Bool

data Process stdin stdout stderr #

The process type. The three type variables denote how its standard streams were initialized.

data ProcessConf stdin stdout stderr #

The process configuration that is needed for creating new processes. Use proc to make one.

proc #

Arguments

:: RawFilePath

Command to run

-> [ByteString]

Arguments to the command

-> ProcessConf Inherit Inherit Inherit 

Create a process configuration with the default settings.

setStdin :: StreamType newStdin => ProcessConf oldStdin stdout stderr -> newStdin -> ProcessConf newStdin stdout stderr infixl 4 #

Control how the standard input of the process will be initialized.

setStdout :: StreamType newStdout => ProcessConf stdin oldStdout stderr -> newStdout -> ProcessConf stdin newStdout stderr infixl 4 #

Control how the standard output of the process will be initialized.

setStderr :: StreamType newStderr => ProcessConf stdin stdout oldStderr -> newStderr -> ProcessConf stdin stdout newStderr infixl 4 #

Control how the standard error of the process will be initialized.

processStdin :: Process CreatePipe stdout stderr -> Handle #

Take a process and return its standard input handle.

processStdout :: Process stdin CreatePipe stderr -> Handle #

Take a process and return its standard output handle.

processStderr :: Process stdin stdout CreatePipe -> Handle #

Take a process and return its standard error handle.

startProcess :: (StreamType stdin, StreamType stdout, StreamType stderr) => ProcessConf stdin stdout stderr -> IO (Process stdin stdout stderr) #

Start a new sub-process with the given configuration.

stopProcess :: Process stdin stdout stderr -> IO ExitCode #

Stop a sub-process. For now it simply calls terminateProcess and then waitForProcess.

waitForProcess :: Process stdin stdout stderr -> IO ExitCode #

Wait (block) for a sub-process to exit and obtain its exit code.

terminateProcess :: Process stdin stdout stderr -> IO () #

Terminate a sub-process by sending SIGTERM to it.

callProcess :: ProcessConf stdin stdout stderr -> IO ExitCode #

Create a new process with the given configuration, and wait for it to finish.

readProcessWithExitCode :: ProcessConf stdin stdout stderr -> IO (ExitCode, ByteString, ByteString) #

Fork an external process, read its standard output and standard error strictly, blocking until the process terminates, and return them with the process exit code.

type RawFilePath = ByteString #

A literal POSIX file path