shithub: mc

ref: 3a5ddf0610add4ea0663c4bf2d7f569ac723ad81
dir: /doc/api/libstd/files.txt/

View raw version
{
        title:  File Handling
        description:    libstd: File Handling
}

File Handling
-------------


    pkg std =
            type dir = struct
            ;;

            /* seek options */
            const Seekset	: whence 
            const Seekcur	: whence 
            const Seekend	: whence 

            /* open options */
            const Ordonly  	: fdopt 
            const Owronly  	: fdopt 
            const Ordwr    	: fdopt 
            const Otrunc   	: fdopt 
            const Ocreat   	: fdopt 
            const Oappend  	: fdopt 
            const Odir	: fdopt 

            /* directory handling */
            const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))
            const dirread	: (d : dir# -> std.option(byte[:]))
            const dirclose	: (d : dir# -> void)
            const dirname	: (p : byte[:] -> byte[:])
            const mkdir	: (path : byte[:], mode : int64 -> int64)
            const mkpath	: (p : byte[:] -> bool)
            const chdir	: (path : byte[:] -> bool)

            /* file handling */
            const open	: (path : byte[:], opts : fdopt -> std.result(fd, errno))
            const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> std.result(fd, errno))
            const mktemp	: (base : byte[:], opts : fdopt, mode : int64 -> std.result((fd, byte[:]), errno)
            const close	: (fd : fd -> int64)
            const creat	: (path : byte[:], mode : int64 -> fd)
            const read	: (fd : fd, buf : byte[:] -> size)
            const write	: (fd : fd, buf : byte[:] -> size)
            const seek	: (fd : fd, delta : off, whence : whence -> off)
            const pipe	: (fds : fd[2]# -> int64)
            const dup2	: (ofd : fd, nfd : fd -> fd)
            const remove	: (path : byte[:] -> bool)
            const unlink	: (path : byte[:] -> int)

            /* path manipulation */
            const basename	: (p : byte[:] -> byte[:])
            const pathcat	: (a : byte[:], b : byte[:] -> byte[:])
            const pathjoin	: (p : byte[:][:] -> byte[:])
            const pathnorm	: (p : byte[:] -> byte[:])
            const getcwd : (-> byte[:])

            /* file properties */
            const fmtime	: (f : byte[:]	-> result(time, errno))
            const fsize	: (f : byte[:]	-> result(off, errno))
            const fexists	: (f : byte[:]	-> bool)
            const fisdir	: (f : byte[:]	-> bool)

            /* convenience functions */
            const slurp : (path : byte[:] -> result(byte[:], byte[:]))
            const fslurp : (path : fd -> result(byte[:], byte[:]))
            const blat : (path : byte[:], buf : byte[:], perm : int64 -> bool)
            const fblat : (f : fd, buf : byte[:] -> bool)
    ;;


Data Types and Constants
------------------------

Libstd's file APIs are generally relatively thin wrappers around the host OS
functions. They are a portable subset of this functionality, designed for both
ease of use and portability.

    type dir = struct
    ;;

The directory struct represents the current state of a directory walk.

    /* seek options */
    const Seekset	: whence 
    const Seekcur	: whence 
    const Seekend	: whence 

These are a set of values which describe from where to seek within the file.

    /* open options */
    const Oread  	: fdopt 
    const Owrite  	: fdopt 
    const Ordwr    	: fdopt 
    const Otrunc   	: fdopt 
    const Ocreat   	: fdopt 

These are a set of options that are passed to the open variants describing
what mode to open the file in. These are bit masks which be OR'ed together to
combine them.

`Oread` and `Owrite` request permission to read and write the file, respectively.
`Ordwr` is a convenience flag which ors read and write together. `Otrunc`
indicates that the file should be truncated to zero bytes in length before it
is opened. `Ocreat` indicates that the file should be created if it does not
exist instead of returning an error. `Odir` indicates that this file should
be opened as a directory.

`Ocreat` does not create the path leading to it, and will return an error if
that path does not exist.


Directories
-----------

    const diropen	: (p : byte[:] -> std.result(dir#, byte[:]))

The `diropen` function opens a path as a directory, and returns a pointer
to an object which tracks the state of the directory, allowing for reading
file names one by one from this directory.

Returns: Either a directory wrapped up in the `\`Ok` branch of the result,
or a string describing the failure reason in the `\`Fail` branch.

    const dirread	: (d : dir# -> result(option(byte[:]), errno)

The `dirread` reads a single entry from the directory, opened with `diropen`,
returning it as a string. 

Returns `\`Some entry`, or `\`None` at the end of the directory.

    const dirclose	: (d : dir# -> void)

`dirclose` closes a directory for reading. This frees all associated
resources, returning them to the system. The directory passed in must have
been opened with `diropen`.

Returns: Nothing.

    const mkdir	: (path : byte[:], mode : int64 -> errno)

`mkdir` creates the directory specified in `path`. with the mode `mode`. It
requires the parent directory to exist and be writable. Absolute paths will
be created relative to the root of the file system, and relative paths will
be created relative to the current working directory, as usual.

If the directory already exists, this is counted as a failure to create the
directory.

Returns: Enone on success, or the error that caused the failure if it fails.

    const mkpath	: (path : byte[:] -> errno)

`mkpath` creates a full path specified by `path`. It creates all of the
path components required to create the full path specified. It requires
the parent of the first directory entry that is not currently in existence
to be writable.

Absolute paths will be created relative to the root of the file system, and
relative paths will be created relative to the current working directory, as
usual.

Returns: Enone on success, or the error that caused the directory creation
to fail on failure.

    const chdir	: (path : byte[:] -> bool)

Chdir changes the current working directory to the path specified in `path`.

Returns: True on success, false on failure.

Files
-----

    const open	: (path : byte[:], opts : fdopt -> result(fd, errno))
    const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> result(fd, errno))

Open opens the file `path` for I/O according to the flags reqeusted in `opts`,
and returns a result containing the file descriptor or error. The mode is a
combination of the modes specified above: `Oread`,   `Owrite`, `Ordwr`,
`Otrunc`, or `Ocreat`.

Openmode is similar to open, however, if Ocreate is passed, it the file
requested will be created with the permissions passed in.

Returns: either a valid file descriptor on success, or an error describing why
the open failed on failure.

    const mktemp : (base : byte[:], opts : fdopt, mode : int64 -> std.result((fd, byte[:]), errno)

Mktemp is similar to openmode, however instead of taking a full path as
its first argument, it generates a unique name for a file in temporary
storage by appending a random string to the base name `base`. The mode
provided is in addition to the implicit Ocreat | Oexcl.

Returns: Either a successful result containing the tuple of file descriptor
opened and path generated, or an error describing the failure. The path
is allocated with `std.slalloc`, and must be freed by the caller using
`std.slfree`. The file descriptor must be closed as ususal.


    const close	: (fd : fd -> void)

Closes closes the file descriptor. If the file descriptor is valid, close
is guaranteed to close it. If it is not valid, this is a no-op.

    const read	: (fd : fd, buf : byte[:] -> result(size, errno))

Reads up to the length of `buf` from the file descriptor `fd`, at the current
offset within the file, advancing the offset by the count of bytes read. The
buffer may not be filled entirely when the read completes. For example, when
reading from a console, often only one line will be returned at a time.

Conventionally, `0` bytes are returned at the end of the file.

Returns: Either the number of bytes read on success, or the error that caused
a failure reading on failure.

    const write	: (fd : fd, buf : byte[:] -> result(size, errno))

Write writes up to the length of `buf` to the file descriptor, writing the
bytes at the current offset. The offset is advanced by the number of bytes
that were written, extending the file size if necessary. Write is not
guaranteed to write the full buffer.

Returns: The number of bytes written on success, or the error that caused
the failure on error.

    const seek	: (fd : fd, delta : off, whence : whence -> result(off, errno))

Seek changes the current offset within the file descriptor `fd` by `delta`.
This delta can be treated in three different ways, depending on the value of
`whence.

If `whence` is Seekset, then `delta` is treated as an absolute value to seek
to, and the offset is set to `delta`. If `whence` is `Seekcur`, then `delta`
is added to the current offset.  If `whence` is `Seekend`, then `delta` is
added to the size of the file.

Returns: Either the new offset within the file on success, or the error that
occurred on failure.

    const pipe	: (fds : fd[2]# -> errno)

Pipe creates a unidirectional channel for communication between processes.
Two file descriptors are returned in the array fd. Data written to fd[1] is
available in fd[0]. The pipe may or may not be buffered.

Returns: Enone on success, otherwise, returns the error that caused this
call to fail.

    const dup2	: (ofd : fd, nfd : fd -> result(fd, errno))

Dup2 copies the old fd `ofd` to the new fd `nfd`. If the file descriptor
`nfd` is already open, then it is implicitly closed by this call before
the fd is copied. This is done atomically.

Returns: Either the new fd used, on success, or an error describing the
failure.

    const remove	: (path : byte[:] -> errno)

Remove removes the file specified from the directory in which it is contained.
The user must have write permissions for the directory in order to remove
files from it. If `path` is a directory, it must be empty.

Returns: Enone on success, otherwise the error that caused the failure.

Path Manipulation
-----------------
    const basename	: (p : byte[:] -> byte[:])
    const dirname	: (p : byte[:] -> byte[:])

Given a string of the form "foo/bar/baz", `dirname()` returns the directory
component of it -- in other words, everything up to the final `/`. It ignores
trailing slashes. It 

The caller is responsible for freeing the path with `slfree`.

For example, `dirname("foo/bar//")` will return `"foo/bar"`.

    const pathcat	: (a : byte[:], b : byte[:] -> byte[:])

Pathcat joins two paths together, using '/' as a directory
separator. The paths are normalized before being returned. This
call is shorthand for `std.pathjoin([a, b][:])`.

The caller is responsible for freeing the path with `slfree`.

Returns: A concatenated path.

    const pathjoin	: (p : byte[:][:] -> byte[:])

Pathcat joins a list of paths together, using '/' as a directory
separator. The paths are normalized before being returned. This
call is shorthand for `std.pathjoin([a, b][:])`.

The caller is responsible for freeing the path with `slfree`.

Returns: A concatenated path.

    const pathnorm	: (p : byte[:] -> byte[:])

Pathnorm does a purely lexical normalization of the path. It removes
redundant components, doubled `/` characters, and similar. The returned
path is equivalent to the original input path.

The caller is responsible for freeing the path with `slfree`.

Returns: A new normalized path.

    const getcwd : (-> byte[:])

Returns the current working directory of the program. The caller is
responsible for freeing the path with `slfree`.

Returns: A string representing the working directory.

File Properties
---------------

    const fmtime	: (f : byte[:]	-> result(time, errno))

Returns either the last modification time of the file `f`, or
the error that was encountered extracting this information.

    const fsize	: (f : byte[:]	-> result(off, errno))

Returns either the size in bytes of the file `f`, or
the error that was encountered extracting this information.

    const fexists	: (f : byte[:]	-> bool)

Returns `true` if the file is able to be `stat`ed, or `false`
if this fails.

    const fisdir	: (f : byte[:]	-> bool)

Returns `true` if the file is a directory that is able to be `stat`ed, or
`false` if this fails.

Convenience Functions
---------------------

    const slurp : (path : byte[:] -> result(byte[:], errno))

Reads all bytes from `path` until the end of file.

Returns either the file data, or the failure encountered.

    const fslurp : (fd : fd -> result(byte[:], errno))

Reads all bytes from the file descriptor `fd` until the end of file.

Returns either the file data, or the failure encountered.

    const blat : (path : byte[:], buf : byte[:], perm : int64 -> bool)

Creates the file `path` with permissions `perm`, and writes as much of
`buf` as it can into it.

Returns Enone if no errors were encountered. Otherwise, the error is returned.

    const fblat : (f : fd, buf : byte[:] -> bool)

Writes as much of `buf` as it can into the file descriptor `fd`.

Returns Enone if no errors were encountered. Otherwise, the error is returned.