text:
# Lua/APR binding documentation

The [Lua/APR binding] [homepage] aims to bring most of the functionality in the
[Apache Portable Runtime (APR)] [apr_wiki] to the small and flexible
[programming language Lua] [lua_wiki]. This document contains the documentation
for the Lua/APR binding. Some notes about this documentation:

 - Most of the documentation is based on the [official APR documentation]
   [apr_docs] but I've had to consult the APR source code here and there when
   the official documentation didn't suffice. If anything seems amiss [please
   let me know](mailto:peter@peterodding.com).

 - The entries for all functions are automatically generated from the C and Lua
   source code of the binding to prevent that documentation and implementation
   become out of sync.

 The base64 format uses the printable
characters `A-Z`, `a-z`, `0-9`, `+` and `/` to encode binary data. This can
be useful when your data is used in a context that isn't 8-bit clean, for
example in e-mail attachments and [data:] [data_uris] URLs. You can read
more about base64 encoding in [this] [base64] Wikipedia article.

[base64]: http://en.wikipedia.org/wiki/Base64
[data_uris]: http://en.wikipedia.org/wiki/Data_URI_scheme

###  `apr.base64_encode(plain) → coded`

Encode the string <tt>*plain*</tt> using base64 encoding. On success the coded string
is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. As an
example, here is how to convert an image file into a [data: URL]
[data_uris]:

    > image = io.open 'lua-logo.png'
    > encoded_data = apr.base64_encode(image:read '*a')
    > data_url = 'data:image/png;base64,' .. encoded_data
    > = ''
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAm5JREFUOMt9k01LW0EUhp+Z5CaxatSbljRioaQgmCIKoUo3XXRRF241tUuhIEgWIgRSKzhtNLZbKf0BulL6C1x234WgoS0otIoWP4Ji48ed3Dtd9CoSW18YBs45z8uZjyOokVKqGQgBzZZlHQshHM/zGqrVaiCRSGyOjOwmhXDngZgxjAUvwLm5uXC5XI5Ho9G98fHxQ2AXVNS3/QFQLBZjdXXuu7MzegCE4IO4CiulfoK6LSUTxvAcaPX9t4Vg0fMoSskbYxj14ysBgN7e3oRSahPepoUwn4FnQONFd11d8cZstvexbUderq0dKCk5iUTEL63lqCgWi3eklE4+fxYWghXg7tU7aWmJsLExRlNTGIC+voWD5eWtDqUcY9v2sXRdtyGfzx9JyataGKCtLXoJA7S3x2JSOhNKqf1yuXxPuq57DGAML/iHVld3WVpaA6BU2mNxce2yNhgMnkrLsgIw2wLEC4Wn1wyMgaGhT9j2ezo7P7K/fwIQB2VXq9VT6XleFIRXC05OPrncM5mHDAykGB19dLXEC4VCASml/A35I2CL/+jkRHN6qkkm7YvQFqhDx3GapNZa+59iIRAQZLM9DA93U6k4DA6miMVukU4n0NrDtusIhQIIwfyFt1BKtaVSqZ1MptQoBF+AJDdrwxjSs7NhEQwGHamU2iqVSg9AHRpDP7B+A7xuDP3GTB2dn5/X53K5ivQH6HuhUOgA9dUYuo3hNbAKaH+tGiMm/uamvk1PT99PpVI7AKJmEpPAtlLqzH9EPy8MwMzMTEJrHfh75Ix7zcA3abUsy9VaG8AGDgEHiNbX1+/lcrnK1fo/txYAMvuVJrYAAAAASUVORK5CYII=" width=16 height=16 alt="Lua logo">

This is what the result looks like (might not work in older web browsers):
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAm5JREFUOMt9k01LW0EUhp+Z5CaxatSbljRioaQgmCIKoUo3XXRRF241tUuhIEgWIgRSKzhtNLZbKf0BulL6C1x234WgoS0otIoWP4Ji48ed3Dtd9CoSW18YBs45z8uZjyOokVKqGQgBzZZlHQshHM/zGqrVaiCRSGyOjOwmhXDngZgxjAUvwLm5uXC5XI5Ho9G98fHxQ2AXVNS3/QFQLBZjdXXuu7MzegCE4IO4CiulfoK6LSUTxvAcaPX9t4Vg0fMoSskbYxj14ysBgN7e3oRSahPepoUwn4FnQONFd11d8cZstvexbUderq0dKCk5iUTEL63lqCgWi3eklE4+fxYWghXg7tU7aWmJsLExRlNTGIC+voWD5eWtDqUcY9v2sXRdtyGfzx9JyataGKCtLXoJA7S3x2JSOhNKqf1yuXxPuq57DGAML/iHVld3WVpaA6BU2mNxce2yNhgMnkrLsgIw2wLEC4Wn1wyMgaGhT9j2ezo7P7K/fwIQB2VXq9VT6XleFIRXC05OPrncM5mHDAykGB19dLXEC4VCASml/A35I2CL/+jkRHN6qkkm7YvQFqhDx3GapNZa+59iIRAQZLM9DA93U6k4DA6miMVukU4n0NrDtusIhQIIwfyFt1BKtaVSqZ1MptQoBF+AJDdrwxjSs7NhEQwGHamU2iqVSg9AHRpDP7B+A7xuDP3GTB2dn5/X53K5ivQH6HuhUOgA9dUYuo3hNbAKaH+tGiMm/uamvk1PT99PpVI7AKJmEpPAtlLqzH9EPy8MwMzMTEJrHfh75Ix7zcA3abUsy9VaG8AGDgEHiNbX1+/lcrnK1fo/txYAMvuVJrYAAAAASUVORK5CYII=" width=16 height=16 alt="Lua logo">

*This function is binary safe.*

###  `apr.base64_decode(coded) → plain`

Decode the base64 encoded string <tt>*coded*</tt>. On success the decoded string is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is binary safe.*

## Cryptography routines

These functions support the [MD5] [md5] and [SHA1] [sha1] cryptographic hash
functions. You can also use them to encrypt plain text passwords using a
[salt] [salt], validate plain text passwords against their encrypted, salted
digest and read passwords from standard input while masking the characters
typed by the user.

The MD5 and SHA1 functions can be used to hash binary data. This is useful
because the hash is only 16 or 32 bytes long, yet it still changes
significantly when the binary data changes by just one byte.

If that doesn't look useful consider the following scenario: The Lua authors
have just finished a new release of Lua and are about to publish the source
code on <http://lua.org>. Before they publish the [tarball] [tar] they first
calculate its MD5 and SHA1 hashes. They then publish the archive and hashes
on the [downloads page] [lua_downloads]. When a user downloads the tarball
they can verify whether it was corrupted or manipulated since it was
published on <http://lua.org> by comparing the published hash against the
hash of the tarball they just downloaded:

    > handle = io.open('lua-5.1.4.tar.gz', 'rb')
    > data = handle:read('*a'); handle:close()
    > = apr.md5(data) == 'd0870f2de55d59c1c8419f36e8fac150'
    true
    > = apr.sha1(data) == '2b11c8e60306efb7f0734b747588f57995493db7'
    true

[md5]: http://en.wikipedia.org/wiki/MD5
[sha1]: http://en.wikipedia.org/wiki/SHA1
[salt]: http://en.wikipedia.org/wiki/Salt_(cryptography)
[tar]: http://en.wikipedia.org/wiki/Tar_(file_format)
[lua_downloads]: http://www.lua.org/ftp/

###  `apr.md5(input [, binary]) → digest`

Calculate the [MD5] [md5] message digest of the string <tt>*input*</tt>. On success
the digest is returned as a string of 32 hexadecimal characters, or a string
of 16 bytes if <tt>*binary*</tt> evaluates to <tt>*true*</tt>. Otherwise a <tt>*nil*</tt> followed by an
error message is returned.

*This function is binary safe.*

###  `apr.md5_encode(password, salt) → digest`

Encode the string <tt>*password*</tt> using the [MD5] [md5] algorithm and a [salt]
[salt] string. On success the digest is returned, otherwise a <tt>*nil*</tt> followed
by an error message is returned.

*This function is not binary safe.*

###  `apr.password_validate(password, digest) → valid`

Validate the string <tt>*password*</tt> against a <tt>*digest*</tt> created by one of the
APR-supported algorithms ([MD5] [md5] and [SHA1] [sha1]). On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

Hashes created by crypt are supported only on platforms that provide
[crypt(3)] [crypt_fun], so don't rely on that function unless you know that
your application will be run only on platforms that support it. On platforms
that don't support crypt(3), this falls back to a clear text string
comparison.

[crypt_fun]: http://linux.die.net/man/3/crypt

*This function is not binary safe.*

###  `apr.password_get(prompt) → password`

Display the string <tt>*prompt*</tt> on the command-line prompt and read in a password
from standard input. If your platform allows it, the typed password will be
masked by a placeholder like `*`. On success the password is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

###  `apr.md5_init() → md5_context`

Create and return an object that can be used to calculate [MD5] [md5]
message digests in steps. If an error occurs a <tt>*nil*</tt> followed by an error
message is returned. This can be useful when you want to calculate message
digests of large inputs, for example files like [ISO images] [isoimg] and
backups:

    > function md5_file(path, binary)
    >>  local handle = assert(io.open(path, 'rb'))
    >>  local context = assert(apr.md5_init())
    >>  while true do
    >>    local block = handle:read(1024 * 1024)
    >>    if not block then break end
    >>    assert(context:update(block))
    >>  end
    >>  return context:digest(binary)
    >> end
    >
    > md5_file 'ubuntu-10.04-desktop-i386.iso'
    'd044a2a0c8103fc3e5b7e18b0f7de1c8'

[isoimg]: http://en.wikipedia.org/wiki/ISO_image

###  `md5_context:update(input) → status`

Continue an [MD5] [md5] message digest operation by processing another
message block and updating the context. On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is binary safe.*

###  `md5_context:digest([binary]) → digest`

End an [MD5] [md5] message digest operation. On success the digest is
returned as a string of 32 hexadecimal characters, or a string of 16 bytes
if <tt>*binary*</tt> evaluates to <tt>*true*</tt>. Otherwise a <tt>*nil*</tt> followed by an error message
is returned.

If you want to re-use the context object after calling this method
see [md5\_context:reset()](#md5_context:reset).

###  `md5_context:reset() → status`

Use this method to reset the context after calling [md5\_context:digest()](#md5_context:digest).
This enables you to re-use the same context to perform another message
digest calculation. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by
an error message is returned.

###  `apr.sha1(input [, binary]) → digest`

Calculate the [SHA1] [sha1] message digest of the string <tt>*input*</tt>. On success
the digest is returned as a string of 40 hexadecimal characters, or a string
of 20 bytes if <tt>*binary*</tt> evaluates to <tt>*true*</tt>. Otherwise a <tt>*nil*</tt> followed by an
error message is returned.

*This function is binary safe.*

###  `apr.sha1_init() → sha1_context`

Create and return an object that can be used to calculate [SHA1] [sha1]
message digests in steps. See also the example for [apr.md5\_init()](#apr.md5_init).

###  `sha1_context:update(input) → status`

Continue an [SHA1] [sha1] message digest operation by processing another
message block and updating the context.

*This function is binary safe.*

###  `sha1_context:digest([binary]) → digest`

End an [SHA1] [sha1] message digest operation. On success the digest is
returned as a string of 40 hexadecimal characters, or a string of 20 bytes
if <tt>*binary*</tt> evaluates to <tt>*true*</tt>. Otherwise a <tt>*nil*</tt> followed by an error message
is returned.

If you want to re-use the context object after calling this method
see [sha1\_context:reset()](#sha1_context:reset).

###  `sha1_context:reset() → status`

Use this method to reset the context after calling [sha1\_context:digest()](#sha1_context:digest).
This enables you to re-use the same context to perform another message
digest calculation.

## Date parsing

###  `apr.date_parse_http(string) → time`

Parses an [HTTP] [http] date in one of three standard forms:

 - `'Sun, 06 Nov 1994 08:49:37 GMT'` - [RFC 822] [rfc822], updated by [RFC 1123][rfc1123]
 - `'Sunday, 06-Nov-94 08:49:37 GMT'` - [RFC 850] [rfc850], obsoleted by [RFC 1036][rfc1036]
 - `'Sun Nov  6 08:49:37 1994'` - ANSI C's [asctime()] [asctime] format

On success the date is returned as a number like documented under [time
routines](#time_routines). If the date string is out of range or invalid <tt>*nil*</tt>
is returned.

[http]: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
[rfc822]: http://tools.ietf.org/html/rfc822
[rfc1123]: http://tools.ietf.org/html/rfc1123
[rfc850]: http://tools.ietf.org/html/rfc850
[rfc1036]: http://tools.ietf.org/html/rfc1036
[asctime]: http://linux.die.net/man/3/asctime

*This function is not binary safe.*

###  `apr.date_parse_rfc(string) → time`

Parses a string resembling an [RFC 822] [rfc822] date. This is meant to be
lenient in its parsing of dates and hence will parse a wider range of dates
than [apr.date\_parse\_http()](#apr.date_parse_http).

The prominent mailer (or poster, if mailer is unknown) that has been seen in
the wild is included for the unknown formats:

 - `'Sun, 06 Nov 1994 08:49:37 GMT'` - [RFC 822] [rfc822], updated by [RFC 1123] [rfc1123]
 - `'Sunday, 06-Nov-94 08:49:37 GMT'` - [RFC 850] [rfc850], obsoleted by [RFC 1036] [rfc1036]
 - `'Sun Nov  6 08:49:37 1994'` - ANSI C's [asctime()] [asctime] format
 - `'Sun, 6 Nov 1994 08:49:37 GMT'` - [RFC 822] [rfc822], updated by [RFC 1123] [rfc1123]
 - `'Sun, 06 Nov 94 08:49:37 GMT'` - [RFC 822] [rfc822]
 - `'Sun, 6 Nov 94 08:49:37 GMT'` - [RFC 822] [rfc822]
 - `'Sun, 06 Nov 94 08:49 GMT'` - Unknown<EMAIL_ADDRESS> - `'Sun, 6 Nov 94 08:49 GMT'` - Unknown<EMAIL_ADDRESS> - `'Sun, 06 Nov 94 8:49:37 GMT'` - Unknown [Elm 70.85]
 - `'Sun, 6 Nov 94 8:49:37 GMT'` - Unknown [Elm 70.85]

On success the date is returned as a number like documented under [time
routines](#time_routines). If the date string is out of range or invalid <tt>*nil*</tt>
is returned.

*This function is not binary safe.*

## Relational database drivers

The APR DBD module makes it possible to query relational database engines
like [SQLite] [sqlite], [MySQL] [mysql], [PostgreSQL] [pgsql], [Oracle]
[oracle], [ODBC] [odbc] and [FreeTDS] [freetds]. This module currently has
some drawbacks which appear to be unavoidable given the design of the Apache
Portable Runtime DBD framework:

 - Booleans and numbers are returned as strings because result set types are
   not known to the Lua/APR binding (and type guessing is too error prone)

 - String arguments and results are not binary safe, this means they will
   be truncated at the first zero byte (see the [apr-dev mailing list]
   [apr_dev] thread ["current dbd initiatives"] [dbd_binary_discuss] for
   discussion about this limitation of APR)

Note that if you control the data going into the database you can overcome
the second limitation by using APR's built in support for
[Base64 encoding](#base64_encoding).

### Installing drivers

On Debian/Ubuntu Linux you can install one or more of the following packages
to enable support for the corresponding database driver (dependencies will
be installed automatically by the package management system):

 - [libaprutil1-dbd-sqlite3][sqlite3_pkg]
 - [libaprutil1-dbd-mysql](http://packages.ubuntu.com/lucid/libaprutil1-dbd-mysql)
 - [libaprutil1-dbd-pgsql](http://packages.ubuntu.com/lucid/libaprutil1-dbd-pgsql)
 - [libaprutil1-dbd-odbc](http://packages.ubuntu.com/lucid/libaprutil1-dbd-odbc)
 - [libaprutil1-dbd-freetds](http://packages.ubuntu.com/lucid/libaprutil1-dbd-freetds)

### Debugging "DSO load failed" errors

In my initial tests on Ubuntu I installed [libaprutil1-dbd-sqlite3]
[sqlite3_pkg] but kept getting an error when trying to load the driver:

    $ lua -e "print(require('apr').dbd('sqlite3'))"
    nil  DSO load failed  EDSOOPEN

After a while I found the problem using [LD_DEBUG] [ld_debug]:

    $ LD_DEBUG=libs lua -e "require('apr').dbd('sqlite3')" 2>&1 | grep undefined
    /usr/lib/apr-util-1/apr_dbd_sqlite3-1.so: error: symbol lookup error: undefined symbol: apr_pool_cleanup_null (fatal)

Having identified the problem, finding a workaround was easy:

    $ export LD_PRELOAD='/usr/lib/libapr-1.so.0:/usr/lib/libaprutil-1.so.0'
    $ lua -e "print(require('apr').dbd('sqlite3'))"
    database driver (0x853bdfc)

[sqlite]: http://en.wikipedia.org/wiki/SQLite
[mysql]: http://en.wikipedia.org/wiki/MySQL
[pgsql]: http://en.wikipedia.org/wiki/PostgreSQL
[oracle]: http://en.wikipedia.org/wiki/Oracle_Database
[odbc]: http://en.wikipedia.org/wiki/ODBC
[freetds]: http://en.wikipedia.org/wiki/FreeTDS
[apr_dev]: http://apr.apache.org/mailing-lists.html
[dbd_binary_discuss]: http://marc.info/?l=apr-dev&m=114969441721086&w=2
[sqlite3_pkg]: http://packages.ubuntu.com/lucid/libaprutil1-dbd-sqlite3
[ld_debug]: http://www.wlug.org.nz/LD_DEBUG

###  `apr.dbd(name) → driver`

Create a database driver object. The string <tt>*name*</tt> decides which database
engine to use. On success the driver object is returned, otherwise a <tt>*nil*</tt>
followed by an error message is returned. Currently supported engines
include:

 - `'mysql'`
 - `'pgsql'`
 - `'sqlite3'`
 - `'sqlite2'`
 - `'oracle'`
 - `'freetds'`
 - `'odbc'`

Note that in its default configuration the Apache Portable Runtime uses
dynamic loading to load database drivers which means [apr.dbd()](#apr.dbd) can fail
because a driver can't be loaded.

###  `driver:open(params) → status`

Open a connection to a backend. The string <tt>*params*</tt> contains the arguments to
the driver (implementation-dependent). On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned. The syntax of
<tt>*params*</tt> is as follows:

 - __PostgreSQL:__ <tt>*params*</tt> is passed directly to the [PQconnectdb()]
   [pqconnectdb] function, check the PostgreSQL documentation for more
   details on the syntax

 - __SQLite2:__ <tt>*params*</tt> is split on a colon, with the first part used as the
   filename and the second part converted to an integer and used as the file
   mode

 - __SQLite3:__ <tt>*params*</tt> is passed directly to the [sqlite3_open()]
   [sqlite3_open] function as a filename to be opened, check the SQLite3
   documentation for more details (hint: if <tt>*params*</tt> is `':memory:'` a
   private, temporary in-memory database is created for the connection)

 - __Oracle:__ <tt>*params*</tt> can have 'user', 'pass', 'dbname' and 'server' keys,
   each followed by an equal sign and a value. Such key/value pairs can be
   delimited by space, CR, LF, tab, semicolon, vertical bar or comma

 - __MySQL:__ <tt>*params*</tt> can have 'host', 'port', 'user', 'pass', 'dbname',
   'sock', 'flags' 'fldsz', 'group' and 'reconnect' keys, each followed by
   an equal sign and a value. Such key/value pairs can be delimited by
   space, CR, LF, tab, semicolon, vertical bar or comma. For now, 'flags'
   can only recognize `CLIENT_FOUND_ROWS` (check MySQL manual for details).
   The value associated with 'fldsz' determines maximum amount of memory (in
   bytes) for each of the fields in the result set of prepared statements.
   By default, this value is 1 MB. The value associated with 'group'
   determines which group from configuration file to use (see
   `MYSQL_READ_DEFAULT_GROUP` option of [mysql_options()] [mysql_options] in
   MySQL manual). Reconnect is set to 1 by default (i.e. <tt>*true*</tt>)

 - __FreeTDS:__ <tt>*params*</tt> can have 'username', 'password', 'appname',
   'dbname', 'host', 'charset', 'lang' and 'server' keys, each followed by
   an equal sign and a value

 [pqconnectdb]: http://www.postgresql.org/docs/current/interactive/libpq-connect.html#LIBPQ-PQCONNECTDB
 [sqlite3_open]: http://www.sqlite.org/c3ref/open.html
 [mysql_options]: http://dev.mysql.com/doc/refman/5.5/en/mysql-options.html

*This function is not binary safe.*

###  `driver:dbname(name) → status`

Select the database <tt>*name*</tt>. On succes <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt>
followed by an error message is returned. Not supported for all drivers
(e.g. SQLite by definition only knows a single database).

*This function is not binary safe.*

###  `driver:driver() → name`

Get the name of the database driver. Returns one of the strings listed for
[apr.dbd()](#apr.dbd).

###  `driver:check() → status`

Check the status of the database connection. When the connection is still
alive <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

###  `driver:query(sql) → status, affected_rows`

Execute an SQL query that doesn't return a result set. On success <tt>*true*</tt>
followed by the number of affected rows is returned, otherwise a <tt>*nil*</tt>
followed by an error message is returned.

*This function is not binary safe.*

###  `driver:select(sql [, random_access]) → result_set`

Execute an SQL query that returns a result set. On success a result set
object is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned. To enable support for random access you can pass the optional
argument <tt>*random_access*</tt> as <tt>*true*</tt>.

*This function is not binary safe.*

###  `driver:transaction_start() → status`

Start a transaction. May be a no-op. On success <tt>*true*</tt> is returned, otherwise
a <tt>*nil*</tt> followed by an error message is returned.

Note that transaction modes, set by calling [driver:transaction\_mode()](#driver:transaction_mode),
will affect all query/select calls within a transaction. By default, any
error in query/select during a transaction will cause the transaction to
inherit the error code and any further query/select calls will fail
immediately. Put transaction in `'ignore-errors'` mode to avoid that. Use
`'rollback'` mode to do explicit rollback.

TODO Support for transaction objects that have query(), select(), prepare() methods?

###  `driver:transaction_end() → status`

End a transaction (commit on success, rollback on error). May be a no-op. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

###  `driver:transaction_mode([mode]) → mode`

Get or set the transaction mode, one of:

 - `'commit'`: commit the transaction
 - `'rollback'`: rollback the transaction
 - `'ignore-errors'`: ignore transaction errors

On success the new transaction mode is returned, otherwise a <tt>*nil*</tt> followed by
an error message is returned.

###  `driver:prepare(sql [, random_access]) → prepared_statement`

Prepare an SQL statement. On success a prepared statement object is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. The
string <tt>*sql*</tt> gives the query to prepare. If the optional argument
<tt>*random_access*</tt> is <tt>*true*</tt>, result sets created by the prepared statement will
support random access.

To specify parameters of the prepared query, use `%s`, `%d` etc. (see below
for full list) in place of database specific parameter syntax (e.g. for
PostgreSQL, this would be `$1`, `$2`, for SQLite3 this would be `?`, etc.).
For instance: `SELECT name FROM customers WHERE name = %s` would be a query
that this function understands. Here is the list of supported format
specifiers and what they map to in SQL (generally you'll only need the types
marked in bold text):

 - `%hhd`: TINY INT
 - `%hhu`: UNSIGNED TINY INT
 - `%hd`: SHORT
 - `%hu`: UNSIGNED SHORT
 - __`%d`: INT__
 - __`%u`: UNSIGNED INT__
 - `%ld`: LONG
 - `%lu`: UNSIGNED LONG
 - `%lld`: LONG LONG
 - `%llu`: UNSIGNED LONG LONG
 - __`%f`: FLOAT, REAL__
 - __`%lf`: DOUBLE PRECISION__
 - __`%s`: VARCHAR__
 - __`%pDt`: TEXT__
 - `%pDi`: TIME
 - `%pDd`: DATE
 - `%pDa`: DATETIME
 - `%pDs`: TIMESTAMP
 - `%pDz`: TIMESTAMP WITH TIME ZONE
 - `%pDn`: NULL

*This function is not binary safe.*

###  `prepared_statement:query(...) → status`

Using a prepared statement, execute an SQL query that doesn't return a
result set. On success <tt>*true*</tt> followed by the number of affected rows is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

If you pass a list then the values in the list become query parameters,
otherwise all function arguments become query parameters.

*This function is not binary safe.*

###  `prepared_statement:select(...) → result_set`

Using a prepared statement, execute an SQL query that returns a result set.
On success a result set object is returned, otherwise a <tt>*nil*</tt> followed by an
error message is returned. To enable support for random access pass
<tt>*random_access*</tt> as <tt>*true*</tt>, otherwise pass it as <tt>*false*</tt>.

If you pass a list then the values in the list become query parameters,
otherwise all function arguments after <tt>*random_access*</tt> become query
parameters.

*This function is not binary safe.*

###  `result_set:columns([num]) → name [, ...]`

If no arguments are given return the names of all columns in the result set,
otherwise return the name of the column with index <tt>*num*</tt> (counting from one).
For example:

    > driver = assert(apr.dbd 'sqlite3')
    > assert(driver:open ':memory:')
    > results = assert(driver:select [[ SELECT 1 AS col1, 2 AS col2 ]])
    > = assert(results:columns())
    { 'col1', 'col2' }

*This function is not binary safe.*

###  `result_set:row(num) → row`

Return a table with named fields for the next row in the result set or the
row with index <tt>*rownum*</tt> if given. When there are no more rows nothing is
returned, in case of an error a <tt>*nil*</tt> followed by an error message is
returned.

*This function is not binary safe.*

###  `result_set:rows() → iterator`

Return an iterator that produces a table with named fields for each
(remaining) row in the result set.

In Lua 5.2 you can also use `pairs(result_set)`.

*This function is not binary safe.*

###  `result_set:tuple([rownum]) → value [, ...]`

Return a tuple for the next row in the result set or the row with index
<tt>*rownum*</tt> if given. If more than one value is returned, the return values will
be in the same order as the column list in the SQL query. When there are no
more rows nothing is returned, in case of an error a <tt>*nil*</tt> followed by an
error message is returned.

*This function is not binary safe.*

###  `result_set:tuples() → iterator`

Return an iterator that produces a tuple for each (remaining) row in the
result set. The tuples produced by the iterator are in the same order as the
column list in the SQL query, for example:

    > driver = assert(apr.dbd 'sqlite3')
    > assert(driver:open 'quotes.sqlite3')
    > results = assert(driver:select [[ SELECT author, quote FROM quotes ]])
    > for author, quote in results:tuples() do
    >>  print(author, 'wrote:')
    >>  print(quote)
    >>  print()
    >> end

*This function is not binary safe.*

###  `result_set:pairs() → iterator`

Return an iterator that produces a row number and a table with named fields
for each (remaining) row in the result set.

In Lua 5.2 you can also use `ipairs(result_set)`.

*This function is not binary safe.*

###  `#result_set → num_tuples`

Get the number of rows in a result set of a synchronous select. If the
results are asynchronous -1 is returned.

###  `driver:close() → status`

Close a connection to a backend.

## DBM routines

This module enables the creation and manipulation of [dbm] [dbm] databases.
If you've never heard of dbm before you can think of it as a Lua table that
only supports string keys and values but is backed by a file, so that you
can stop and restart your application and find the exact same contents.
This module supports the following libraries/implementations:

 - `'db'` for [Berkeley DB] [bdb] files
 - `'gdbm'` for GDBM files
 - `'ndbm'` for NDBM files
 - `'sdbm'` for SDBM files (the default)

The SDBM format is the default database format for Lua/APR because APR has
built-in support for SDBM while the other libraries need to be separately
installed. This is why not all types may be available at run time.

[dbm]: http://en.wikipedia.org/wiki/dbm
[bdb]: http://en.wikipedia.org/wiki/Berkeley_DB

###  `apr.dbm_open(path [, mode [, permissions [, type ]]]) → dbm object`

Open a [dbm] [dbm] file by <tt>*path*</tt>. On success a database object is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned. The following
<tt>*mode*</tt> strings are supported:

 - `'r'` to open an existing database for reading only (this is the default)
 - `'w'` to open an existing database for reading and writing
 - `'c'` to open a database for reading and writing, creating it if it
   doesn't exist
 - `'n'` to open a database for reading and writing, truncating it if it
   already exists

The [permissions](#file_system_permissions) string is documented elsewhere. Valid values for <tt>*type*</tt> are
listed in the introductory text for this module. Also note that the <tt>*path*</tt>
string may not be a real file name, as many [dbm] [dbm] packages append
suffixes for separate data and index files (see also
[apr.dbm\_getnames()](#apr.dbm_getnames)).

*This function is not binary safe.*

###  `apr.dbm_getnames(path [, type]) → used1 [, used2]`

If the specified <tt>*path*</tt> were passed to [apr.dbm\_open()](#apr.dbm_open), return the actual
pathnames which would be (created and) used. At most, two files may be used;
<tt>*used2*</tt> is <tt>*nil*</tt> if only one file is used. The [dbm] [dbm] file(s) don't need
to exist because this function only manipulates the pathnames. Valid values
for <tt>*type*</tt> are listed in the introductory text for this module.

*This function is not binary safe.*

###  `dbm:exists(key) → status`

Check whether the [dbm] [dbm] record with the given string <tt>*key*</tt> exists.

*This function is binary safe.*

###  `dbm:fetch(key) → value`

Fetch the [dbm] [dbm] record with the given string <tt>*key*</tt>. On success the
fetched value is returned as a string, if the key doesn't exist nothing is
returned and on error a <tt>*nil*</tt> followed by an error message is returned.

*This function is binary safe.*

###  `dbm:store(key, value) → status`

Store the [dbm] [dbm] record <tt>*value*</tt> (a string) by the given string <tt>*key*</tt>. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

*This function is binary safe.*

###  `dbm:delete(key) → status`

Delete the [dbm] [dbm] record with the given string <tt>*key*</tt>. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is binary safe.*

###  `dbm:firstkey() → key`

Retrieve the first record key from a [dbm] [dbm]. On success the first key
is returned as a string, when there are no keys nothing is returned. In case
of error a <tt>*nil*</tt> followed by an error message is returned.

*This function is binary safe.*

###  `dbm:nextkey(key1) → key2`

Retrieve the next record key from a [dbm] [dbm]. This function works just
like Lua's [next()](http://www.lua.org/manual/5.1/manual.html#pdf-next) function: On success the next key is returned as a
string, when there are no more keys nothing is returned. In case of error a
<tt>*nil*</tt> followed by an error message is returned.

*This function is binary safe.*

###  `dbm:close() → status`

Close a [dbm] [dbm] database handle and return <tt>*true*</tt> (this can't fail).

## Environment manipulation

Operating systems organize tasks into processes. One of the simplest means
of communication between processes is the use of environment variables. If
you're not familiar with environment variables, picture every process on
your computer having an associated Lua table with string key/value pairs.
When a process creates or overwrites a key/value pair only the table of that
process changes. When the process spawns a child process the child gets a
copy of the table which from that point onwards is no longer associated with
the parent process.

###  `apr.env_get(name) → value`

Get the value of the environment variable <tt>*name*</tt>. On success the string value
is returned. If the variable does not exist nothing is returned. Otherwise a
<tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

###  `apr.env_set(name, value) → status`

Set the value of the environment variable <tt>*name*</tt> to the string <tt>*value*</tt>. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

*This function is not binary safe.*

###  `apr.env_delete(name) → status`

Delete the environment variable <tt>*name*</tt>. On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

## File path manipulation

###  `apr.filepath_root(path [, option, ...]) → root, path`

Extract the root from the file path <tt>*path*</tt>. On success the extracted root and
the relative path following the root are returned, otherwise a <tt>*nil*</tt> followed
by an error message is returned. Either or both of the following options may
be given after <tt>*path*</tt>:

 - `'true-name'` verifies that the root exists and resolves its <tt>*true*</tt> case.
   If the root does not exist, a <tt>*nil*</tt> followed by an error message is
   returned
 - `'native'` uses the file system's native path format (e.g. path delimiters
   of `:` on MacOS9, \\ on Win32, etc.) in the resulting root

These options only influence the resulting root. The path after the root is
returned as is. If you want to convert a whole file path to its <tt>*true*</tt> case
and/or native format use [apr.filepath\_merge()](#apr.filepath_merge) instead.

*This function is not binary safe.*

###  `apr.filepath_parent(path [, option, ...]) → parent, filename`

Split the file path <tt>*path*</tt> into its parent path and filename. This function
supports the same options as [apr.filepath\_root()](#apr.filepath_root). If any options are given
they're applied to <tt>*path*</tt> before it is split, so the options influence both
of the resulting values. If <tt>*path*</tt> is a filename and the `'true-name'` option
isn't given then the returned parent path will be an empty string.

*This function is not binary safe.*

###  `apr.filepath_name(path [, split]) → filename [, extension]`

Extract the filename (the final element) from the file path <tt>*path*</tt>. If <tt>*split*</tt>
evaluates <tt>*true*</tt> then the extension will be split from the filename and
returned separately. Some examples of what is considered a filename or an
extension:

    > -- regular file path
    > = apr.filepath_name('/usr/bin/lua', true)
    'lua', ''

    > -- hidden file on UNIX
    > = apr.filepath_name('/home/xolox/.vimrc', true)
    '.vimrc', ''

    > -- multiple extensions
    > = apr.filepath_name('index.html.en', true)
    'index.html', '.en'

*This function is not binary safe.*

###  `apr.filepath_merge(root, path [, option, ...]) → merged`

Merge the file paths <tt>*root*</tt> and <tt>*path*</tt>. On success the merged file path is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. Any
combination of one or more of the following options may be given:

 - `'true-name'` resolves the <tt>*true*</tt> case of existing elements in <tt>*path*</tt>,
   resolving any aliases on Windows, and appends a trailing slash if the
   final element is a directory
 - `'native'` uses the file system's native path format (e.g. path delimiters
   of `:` on MacOS9, \\ on Win32, etc.)
 - `'not-above-root'` fails if <tt>*path*</tt> is above <tt>*root*</tt>, e.g. if <tt>*root*</tt> is
   `/foo/bar` and <tt>*path*</tt> is `../baz`
 - `'not-absolute'` fails if the merged path is absolute
 - `'not-relative'` fails if the merged path is relative
 - `'secure-root'` fails if <tt>*path*</tt> is above <tt>*root*</tt>, even given the <tt>*root*</tt>
   `/foo/bar` and the <tt>*path*</tt> `../bar/bash`

This function can be used to generate absolute file paths as follows:

    apr.filepath_merge('.', 'filepath.c', 'not-relative')
    -- the above is equivalent to the below:
    apr.filepath_merge(apr.filepath_get(), 'filepath.c', 'not-relative')

*This function is not binary safe.*

###  `apr.filepath_list_split(searchpath) → components`

Split a search path string into a table of separate components. On success
the table of components is returned, otherwise a <tt>*nil*</tt> followed by an error
message is returned. Empty elements do not become part of the returned
table.

An example of a search path is the [$PATH] [path_var] environment variable
available in UNIX and Windows operating systems which controls the way
program names are resolved to absolute pathnames (see
[apr.filepath\_which()](#apr.filepath_which)).

[path_var]: http://en.wikipedia.org/wiki/PATH_(variable)

*This function is not binary safe.*

###  `apr.filepath_list_merge(components) → searchpath`

Merge a table of search path components into a single search path string. On
success the table of components is returned, otherwise a <tt>*nil*</tt> followed by an
error message is returned.

*This function is not binary safe.*

###  `apr.filepath_get([native]) → path`

Get the default filepath for relative filenames. If <tt>*native*</tt> evaluates <tt>*true*</tt>
the file system's native path format is used. On success the filepath is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

On at least Windows and UNIX the default file path for relative file names
is the current working directory. Because some operating systems supported
by APR don't use this convention Lua/APR uses the term 'default filepath'
instead.

*This function is not binary safe.*

###  `apr.filepath_set(path) → status`

Set the default file path for relative file names to the string <tt>*path*</tt>. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned. Also see the notes for [apr.filepath\_get()](#apr.filepath_get).

*This function is not binary safe.*

###  `apr.filepath_which(program [, find_all]) → pathname`

Find the full pathname of <tt>*program*</tt> by searching the directories in the
[$PATH] [path_var] environment variable and return the pathname of the
first program that's found. If <tt>*find_all*</tt> is <tt>*true*</tt> then a list with the
pathnames of all matching programs is returned instead.

[path_var]: http://en.wikipedia.org/wiki/PATH_%28variable%29

###  `apr.filepath_executable(path) → is_executable`

Check whether the file pointed to by <tt>*path*</tt> is executable.
Returns <tt>*true*</tt> when the file is executable, <tt>*false*</tt> otherwise.

## Filename matching

###  `apr.fnmatch(pattern, input [, ignorecase]) → status`

Try to match a string against a filename pattern. When the string matches
the pattern <tt>*true*</tt> is returned, otherwise <tt>*false*</tt>. The supported pattern items
are the following subset of shell wild cards:

 - `?` matches one character (any character)
 - `*` matches zero or more characters (any character)
 - `\x` escapes the special meaning of the character `x`
 - `[set]` matches one character within set. A range of characters can be
   specified by separating the characters of the range with a
   - character
 - `[^set]` matches the complement of set, where set is defined as above

If the optional argument <tt>*ignorecase*</tt> is <tt>*true*</tt>, characters are compared
case-insensitively.

*This function is not binary safe.*

###  `apr.fnmatch_test(pattern) → status`

Determine if a file path <tt>*pattern*</tt> contains one or more of the wild cards
that are supported by [apr.fnmatch()](#apr.fnmatch). On success <tt>*true*</tt> is returned,
otherwise <tt>*false*</tt>.

*This function is not binary safe.*

###  `apr.glob(pattern [, ignorecase]) → iterator`

Split <tt>*pattern*</tt> into a directory path and a filename pattern and return an
iterator which returns all filenames in the directory that match the
extracted filename pattern. The [apr.fnmatch()](#apr.fnmatch) function is used for
filename matching so the documentation there applies.

*This function is not binary safe.*

## Directory manipulation

###  `apr.temp_dir_get() → path`

Find an existing directory suitable as a temporary storage location. On
success the directory file path is returned, otherwise a <tt>*nil*</tt> followed by an
error message is returned.

*This function is not binary safe.*

###  `apr.dir_make(path [, permissions]) → status`

Create the directory <tt>*path*</tt> on the file system. On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned. See the
documentation on [permissions](#file_system_permissions) for the optional second argument.

*This function is not binary safe.*

###  `apr.dir_make_recursive(path [, permissions]) → status`

Create the directory <tt>*path*</tt> on the file system, creating intermediate
directories as required. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt>
followed by an error message is returned. See the documentation on
[permissions](#file_system_permissions) for the optional second argument.

*This function is not binary safe.*

###  `apr.dir_remove(path) → status`

Remove the *empty* directory <tt>*path*</tt> from the file system. On success <tt>*true*</tt>
is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

###  `apr.dir_remove_recursive(path) → status`

Remove the directory <tt>*path*</tt> *and all its contents* from the file system.
On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

Note: This function isn't part of the Apache Portable Runtime but has been
implemented on top of it by the author of the Lua/APR binding. *It also
hasn't been properly tested yet*.

*This function is not binary safe.*

###  `apr.dir_open(path) → directory handle`

Open the directory <tt>*path*</tt> for reading. On success a directory object is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

###  `directory:read([property, ...]) → value, ...`

Return the requested properties for the next directory entry. On success the
requested properties are returned, otherwise a <tt>*nil*</tt> followed by an error
message is returned. This function implements the same interface as
[apr.stat()](#apr.stat).

###  `directory:rewind() → status`

Rewind the directory handle to start from the first entry. On success <tt>*true*</tt>
is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

###  `directory:entries([property, ...]) → iterator, directory handle`

Return a function that iterates over the (remaining) directory entries and
returns the requested properties for each entry. If you don't request any
properties, a table with the available properties will be returned for each
directory entry:

    > directory = apr.dir_open 'examples'
    > for info in directory:entries() do print(info) end
    {
      type = 'file', name = 'webserver.lua',
      user = 'peter', group = 'peter', protection = 'rw-r--r--',
      size = 2789, csize = 4096, inode = 12455648, dev = 64514, nlink = 1,
      path = '/home/peter/Development/Lua/APR/examples/webserver.lua',
      mtime =<PHONE_NUMBER>.3382, atime =<PHONE_NUMBER>.3855, ctime =<PHONE_NUMBER>.3382,
    }
    {
     type = 'file', name = 'download.lua',
     user = 'peter' group = 'peter', protection = 'rw-r--r--',
     size = 2580, csize = 4096, inode = 12455598, dev = 64514, nlink = 1,
     path = '/home/peter/Development/Lua/APR/examples/download.lua',
     mtime =<PHONE_NUMBER>.3382, atime =<PHONE_NUMBER>.3855, ctime =<PHONE_NUMBER>.3382,
    }

This function implements the same interface as [apr.stat()](#apr.stat) with one
exception: If you pass property names to [directory:entries()](#directory:entries) that are not
available they will be returned as <tt>*false*</tt> instead of <tt>*nil*</tt> because of a
technical limitation in the [Lua iterator protocol] [iterators]:

> "On each iteration, the iterator function is called to
> produce a new value, stopping when this new value is <tt>*nil*</tt>."

[iterators]: http://www.lua.org/manual/5.1/manual.html#2.4.5

###  `directory:close() → status`

Close the directory handle. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt>
followed by an error message is returned.

## File I/O handling

###  `apr.file_link(source, target) → status`

Create a [hard link] [hard_link] to the specified file. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. Both
files must reside on the same device.

Please note that this function will only be available when the Lua/APR
binding is compiled against APR 1.4 or newer because the [apr\_file\_link()]
[apr_file_link] function wasn't available in earlier releases.

[hard_link]: http://en.wikipedia.org/wiki/Hard_link
[apr_file_link]: http://apr.apache.org/docs/apr/trunk/group__apr__file__io.html#ga7911275c0e97edc064b8167be658f9e

*This function is not binary safe.*

###  `apr.file_copy(source, target [, permissions]) → status`

Copy the file <tt>*source*</tt> to <tt>*target*</tt>. On success <tt>*true*</tt> is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned. The [permissions](#file_system_permissions) argument is
documented elsewhere. The new file does not need to exist, it will be
created if required. If the new file already exists, its contents will be
overwritten.

*This function is not binary safe.*

###  `apr.file_append(source, target [, permissions]) → status`

Append the file <tt>*source*</tt> to <tt>*target*</tt>. On success <tt>*true*</tt> is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned. The [permissions](#file_system_permissions) argument is
documented elsewhere. The new file does not need to exist, it will be
created if required.

*This function is not binary safe.*

###  `apr.file_rename(source, target) → status`

Rename the file <tt>*source*</tt> to <tt>*target*</tt>. On success <tt>*true*</tt> is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned. If a file exists at the new
location, then it will be overwritten. Moving files or directories across
devices may not be possible.

*This function is not binary safe.*

###  `apr.file_remove(path) → status`

Delete the file pointed to by <tt>*path*</tt>. On success <tt>*true*</tt> is returned, otherwise
a <tt>*nil*</tt> followed by an error message is returned. If the file is open, it
won't be removed until all instances of the file are closed.

*This function is not binary safe.*

###  `apr.file_truncate(path [, offset]) → status`

Truncate the file's length to the specified <tt>*offset*</tt> (defaults to 0). On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

###  `apr.file_mtime_set(path, mtime) → status`

Set the last modified time of the file pointed to by <tt>*path*</tt> to <tt>*mtime*</tt>. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

*This function is not binary safe.*

###  `apr.file_attrs_set(path, attributes) → status`

Set the attributes of the file pointed to by <tt>*path*</tt>. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

The table <tt>*attributes*</tt> should consist of string keys and boolean values. The
supported attributes are `readonly`, `hidden` and `executable`.

This function should be used in preference to explicit manipulation of the
file permissions, because the operations to provide these attributes are
platform specific and may involve more than simply setting permission bits.

*This function is not binary safe.*

###  `apr.file_perms_set(path, permissions) → status`

Set the permissions of the file specified by <tt>*path*</tt>. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

Warning: Some platforms may not be able to apply all of the available
permission bits, in this case a third value `'INCOMPLETE'` is returned (see
[error handling](#error_handling)).

*This function is not binary safe.*

###  `apr.stat(path [, property, ...]) → value, ...`

Get the status of the file pointed to by <tt>*path*</tt>. On success, if no properties
are given a table of property name/value pairs is returned, otherwise the
named properties are returned in the same order as the arguments. On failure
a <tt>*nil*</tt> followed by an error message is returned.

The following fields are supported:

 - `name` is a string containing the name of the file in proper case
 - `path` is a string containing the absolute pathname of the file
 - `type` is one of the strings `'directory'`, `'file'`, `'link'`, `'pipe'`,
   `'socket'`, `'block device'`, `'character device'` or `'unknown'`
 - `user` is a string containing the name of user that owns the file
 - `group` is a string containing the name of the group that owns the file
 - `size` is a number containing the size of the file in bytes
 - `csize` is a number containing the storage size consumed by the file
 - `ctime` is the time the file was created, or the inode was last changed
 - `atime` is the time the file was last accessed
 - `mtime` is the time the file was last modified
 - `nlink` is the number of hard links to the file
 - `inode` is a unique number within the file system on which the file
   resides
 - `dev` is a number identifying the device on which the file is stored
 - `protection` is a 9 character string with the file system [permissions](#file_system_permissions)
 - `link` *is a special flag that does not return a field*, instead it is
   used to signal that symbolic links should not be followed, i.e. the
   status of the link itself should be returned

Here are some examples:

    > -- Here's an example of a table with all properties:
    > = apr.stat('lua-5.1.4.tar.gz')
    {
     name = 'lua-5.1.4.tar.gz',
     path = 'lua-5.1.4.tar.gz',
     type = 'file',
     user = 'peter',
     group = 'peter',
     size = 216679,
     csize = 217088,
     ctime =<PHONE_NUMBER>.7264,
     atime =<PHONE_NUMBER>.6019,
     mtime =<PHONE_NUMBER>.194,
     nlink = 1,
     inode = 1838576,
     dev  = 64514,
     protection = 'rw-r--r--',
    }
    > -- To check whether a directory exists:
    > function isdir(p) return apr.stat(p, 'type') == 'directory' end
    > = isdir('.')
    true
    > -- To get a file's size in bytes:
    > function filesize(p) return apr.stat(p, 'size') end
    > = filesize('lua-5.1.4.tar.gz')
    216679

*This function is not binary safe.*

###  `apr.file_open(path [, mode [, permissions]]) → file`

This function imitates Lua's [io.open()](http://www.lua.org/manual/5.1/manual.html#pdf-io.open) function with one exception: On
UNIX you can pass a file descriptor (number) instead of a path string (see
also [file:fd\_get()](#file:fd_get)). Now follows the documentation for [io.open()](http://www.lua.org/manual/5.1/manual.html#pdf-io.open):

This function opens a file, in the mode specified in the string <tt>*mode*</tt>. It
returns a new file handle, or, in case of errors, <tt>*nil*</tt> plus an error
message. The <tt>*mode*</tt> string can be any of the following:

 - `'r'`: read mode (the default)
 - `'w'`: write mode
 - `'a'`: append mode
 - `'r+'`: update mode, all previous data is preserved
 - `'w+'`: update mode, all previous data is erased
 - `'a+'`: append update mode, previous data is preserved, writing is only
   allowed at the end of file

The <tt>*mode*</tt> string may also have a `b` at the end, which is needed in some
systems to open the file in binary mode. This string is exactly what is used
in the standard C function [fopen()] [fopen]. The [permissions](#file_system_permissions) argument is
documented elsewhere.

[fopen]: http://linux.die.net/man/3/fopen

*This function is not binary safe.*

###  `file:stat([field, ...]) → value, ...`

This method works like [apr.stat()](#apr.stat) except that it uses a file handle
instead of a filepath to access the file.

###  `file:lines() → iterator`

_This function implements the interface of the [file:lines()] [flines] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Return an iterator function that, each time it is called, returns a new line read from the file. Therefore, the construction

    for line in file:lines() do body end

will iterate over all lines. This function does not close the file when the loop ends.

[flines]: http://www.lua.org/manual/5.1/manual.html#pdf-file:lines

###  `file:truncate([offset]) → status`

Truncate the file's length to the specified <tt>*offset*</tt> (defaults to 0). On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned. Note that the read/write file offset is repositioned to the
selected offset.

###  `file:read([format, ...]) → mixed value, ...`

_This function implements the interface of the [file:read()] [fread] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Read from file, according to the given formats, which specify what to read. For each format, the function returns a string (or a number) with the characters read, or <tt>*nil*</tt> if it cannot read data with the specified format. When called without formats, it uses a default format that reads the entire next line (see below).

The available formats are:

 - `'*n'`: reads a number; this is the only format that returns a number instead of a string
 - `'*a'`: reads all data from the file, starting at the current position. On end of input, it returns the empty string
 - `'*l'`: reads the next line (skipping the end of line), returning <tt>*nil*</tt> on end of input (this is the default format)
 - `number`: reads a string with up to this number of characters, returning <tt>*nil*</tt> on end of input. If number is zero, it reads nothing and returns an empty string, or <tt>*nil*</tt> on end of input

[fread]: http://www.lua.org/manual/5.1/manual.html#pdf-file:read

###  `file:write(value [, ...]) → status`

_This function implements the interface of the [file:write()] [fwrite] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Write the value of each argument to file. The arguments must be strings or numbers. To write other values, use [tostring()](http://www.lua.org/manual/5.1/manual.html#pdf-tostring) or [string.format()](http://www.lua.org/manual/5.1/manual.html#pdf-string.format) before this function.

[fwrite]: http://www.lua.org/manual/5.1/manual.html#pdf-file:write

###  `file:seek([whence [, offset]]) → offset`

_This function implements the interface of the [file:seek()] [fseek] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Sets and gets the file position, measured from the beginning of the file, to
the position given by <tt>*offset*</tt> plus a base specified by the string <tt>*whence*</tt>, as
follows:

 - `'set'`:  base is position 0 (beginning of the file)
 - `'cur'`:  base is current position
 - `'end'`:  base is end of file

In case of success, function `seek` returns the final file position, measured
in bytes from the beginning of the file. If this function fails, it returns
<tt>*nil*</tt>, plus a string describing the error.

The default value for <tt>*whence*</tt> is `'cur'`, and for offset is 0. Therefore, the
call [file:seek()](#file:seek) returns the current file position, without changing it; the
call `file:seek('set')` sets the position to the beginning of the file (and
returns 0); and the call `file:seek('end')` sets the position to the end of the
file, and returns its size.

[fseek]: http://www.lua.org/manual/5.1/manual.html#pdf-file:seek

###  `file:flush() → status`

Saves any written data to <tt>*file*</tt>. On success <tt>*true*</tt> is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned.

###  `file:lock(type [, nonblocking ]) → status`

Establish a lock on the open file <tt>*file*</tt>. On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned. The <tt>*type*</tt> must be
one of:

 - `'shared'`: Shared lock. More than one process or thread can hold a
   shared lock at any given time. Essentially, this is a "read lock",
   preventing writers from establishing an exclusive lock
 - `'exclusive'`: Exclusive lock. Only one process may hold an exclusive
   lock at any given time. This is analogous to a "write lock"

If <tt>*nonblocking*</tt> is <tt>*true*</tt> the call will not block while acquiring the file
lock.

The lock may be advisory or mandatory, at the discretion of the platform.
The lock applies to the file as a whole, rather than a specific range. Locks
are established on a per-thread/process basis; a second lock by the same
thread will not block.

###  `file:unlock() → status`

Remove any outstanding locks on the file. On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

###  `pipe:timeout_get() → timeout`

Get the timeout value or blocking state of <tt>*pipe*</tt>. On success the timeout
value is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

The <tt>*timeout*</tt> <tt>*true*</tt> means wait forever, <tt>*false*</tt> means don't wait at all and a
number is the microseconds to wait.

###  `pipe:timeout_set(timeout) → status`

Set the timeout value or blocking state of <tt>*pipe*</tt>. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

The <tt>*timeout*</tt> <tt>*true*</tt> means wait forever, <tt>*false*</tt> means don't wait at all and a
number is the microseconds to wait. For example:

    -- Configure read end of pipe to block for a maximum of 5 seconds.
    pipe:timeout_set(1000000 * 5)
    for line in pipe:lines() do
      print(line)
    end

###  `file:fd_get() → fd`

Get the underlying [file descriptor] [fildes] for this file. On success a
number is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

To convert a file descriptor into a Lua/APR file object you can pass the
file descriptor (number) to [apr.file\_open()](#apr.file_open) instead of the pathname.

Note that this function is only available on platforms where file
descriptors are numbers (this includes UNIX and excludes Windows).

###  `file:inherit_set() → status`

Set a file to be inherited by child processes. By default, file descriptors
will not be inherited by child processes created by [apr.proc\_create()](#apr.proc_create).

At the time of writing this [seems to only apply to UNIX] [inherit] where
APR will close all open file handles after performing a [fork()] [fork]
unless you explicitly set your files to be inheritable.

[inherit]: http://marc.info/?l=apache-httpd-dev&m=104361635329125&w=2

###  `file:inherit_unset() → status`

Unset a file from being inherited by child processes.

###  `file:close() → status`

Close <tt>*file*</tt>. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an
error message is returned.

## Network I/O handling

To get started with network programming using the Lua/APR binding, have a
look at any of the following examples:

 - [HTTP client](#example_http_client)
 - [Single threaded webserver](#example_single_threaded_webserver)
 - [Multi threaded webserver](#example_multi_threaded_webserver)
 - [Asynchronous webserver](#example_asynchronous_webserver)

###  `apr.socket_create([protocol [, family]]) → socket`

Create a network socket. On success the new socket object is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned. Valid values for
the <tt>*protocol*</tt> argument are:

 - `'tcp'` to create a [TCP] [tcp] socket (this is the default)
 - `'udp'` to create a [UDP] [udp] socket

These are the valid values for the <tt>*family*</tt> argument:

 - `'inet'` to create a socket using the [IPv4] [ipv4] address family (this
   is the default)
 - `'inet6'` to create a socket using the [IPv6] [ipv6] address family
 - `'unspec'` to pick the system default type

Note that `'inet6'` is only supported when `apr.socket_supports_ipv6` is
<tt>*true*</tt>.

[tcp]: http://en.wikipedia.org/wiki/Transmission_Control_Protocol
[udp]: http://en.wikipedia.org/wiki/User_Datagram_Protocol
[ipv4]: http://en.wikipedia.org/wiki/IPv4
[ipv6]: http://en.wikipedia.org/wiki/IPv6

###  `apr.hostname_get() → name`

Get the name of the current machine. On success the host name string is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

###  `apr.host_to_addr(hostname [, family]) → ip_address, ...`

Resolve a host name to one or more IP addresses. On success one or more IP
addresses are returned as strings, otherwise a <tt>*nil*</tt> followed by an error
message is returned. The optional <tt>*family*</tt> argument is documented under
[apr.socket\_create()](#apr.socket_create).

    > = apr.host_to_addr 'www.lua.org'
    '<IP_ADDRESS>'
    > = apr.host_to_addr 'google.com'
    '<IP_ADDRESS>' '<IP_ADDRESS>' '<IP_ADDRESS>' '<IP_ADDRESS>' '<IP_ADDRESS>' '<IP_ADDRESS>'
    > = apr.host_to_addr('ipv6.google.com', 'inet6')
    '2a00:1450:8005::67'

*This function is not binary safe.*

###  `apr.addr_to_host(ip_address [, family]) → hostname`

Look up the host name from an IP-address (also known as a reverse [DNS]
[dns] lookup). On success the host name is returned as a string, otherwise a
<tt>*nil*</tt> followed by an error message is returned. The optional <tt>*family*</tt> argument
is documented under [apr.socket\_create()](#apr.socket_create).

    > = apr.addr_to_host '<IP_ADDRESS>'
    'flounder.pepperfish.net'

[dns]: http://en.wikipedia.org/wiki/Domain_Name_System

*This function is not binary safe.*

###  `socket:connect(host, port) → status`

Issue a connection request to a socket either on the same machine or a
different one, as indicated by the <tt>*host*</tt> string and <tt>*port*</tt> number. On success
<tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

*This function is not binary safe.*

###  `socket:bind(host, port) → status`

Bind the socket to the given <tt>*host*</tt> string and <tt>*port*</tt> number. On success <tt>*true*</tt>
is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. The
special <tt>*host*</tt> value `'*'` can be used to select the default 'any' address.
For example if you want to create a web server you can start with the
following:

    -- Basic single threaded server
    server = assert(apr.socket_create())
    assert(server:bind('*', 80))
    assert(server:listen(10))
    while true do
      local client = assert(server:accept())
      -- Here you can receive data from the client by calling client:read()
      -- and send data to the client by calling client:write()
    end

This function can fail if you try to bind a port below 1000 without
superuser privileges or if another process is already bound to the given
port number.

*This function is not binary safe.*

###  `socket:listen(backlog) → status`

To listen for incoming network connections three steps must be performed:

1. First a socket is created with [apr.socket\_create()](#apr.socket_create)
2. Next a willingness to accept incoming connections and a queue limit for
   incoming connections are specified with [socket:listen()](#socket:listen) (this call
   doesn't block)
3. Finally [socket:accept()](#socket:accept) is called to wait for incoming connections

On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned. The <tt>*backlog*</tt> argument indicates the number of outstanding
connections allowed in the socket's listen queue. If this value is less than
zero, the listen queue size is set to zero. As a special case, if you pass
the string `'max'` as <tt>*backlog*</tt> then a platform specific maximum value is
chosen based on the compile time constant [SOMAXCONN] [SOMAXCONN].

[SOMAXCONN]: http://www.google.com/search?q=SOMAXCONN

###  `socket:recvfrom([bufsize]) → address, data`

Read data from an [UDP] [udp] socket that has been bound to an interface
and/or port. On success two values are returned: A table with the address of
the peer from which the data was sent and a string with the received data.
If the call fails it returns <tt>*nil*</tt> followed by an error message.

By default <tt>*bufsize*</tt> is 1024, this means the resulting <tt>*data*</tt> string will be
truncated to a maximum of 1024 bytes. If you want to receive larger
messages, pass a larger <tt>*bufsize*</tt>.

The returned <tt>*address*</tt> table contains the following fields:

 - `address` is the IP address (a string)
 - `port` is the port number
 - `family` is one of the strings `'inet'`, `'inet6'` or `'unspec'`

*This function is binary safe.*

[udp]: http://en.wikipedia.org/wiki/User_Datagram_Protocol

###  `socket:accept() → client_socket`

Accept a connection request on a server socket. On success a socket is
returned which forms the connection to the client, otherwise a <tt>*nil*</tt> followed
by an error message is returned. This function blocks until a client
connects.

###  `socket:read([format, ...]) → mixed value, ...`

_This function implements the interface of the [file:read()] [fread] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Read from socket, according to the given formats, which specify what to read. For each format, the function returns a string (or a number) with the characters read, or <tt>*nil*</tt> if it cannot read data with the specified format. When called without formats, it uses a default format that reads the entire next line (see below).

The available formats are:

 - `'*n'`: reads a number; this is the only format that returns a number instead of a string
 - `'*a'`: reads all data from the socket, starting at the current position. On end of input, it returns the empty string
 - `'*l'`: reads the next line (skipping the end of line), returning <tt>*nil*</tt> on end of input (this is the default format)
 - `number`: reads a string with up to this number of characters, returning <tt>*nil*</tt> on end of input. If number is zero, it reads nothing and returns an empty string, or <tt>*nil*</tt> on end of input

[fread]: http://www.lua.org/manual/5.1/manual.html#pdf-file:read

###  `socket:write(value [, ...]) → status`

_This function implements the interface of the [file:write()] [fwrite] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Write the value of each argument to socket. The arguments must be strings or numbers. To write other values, use [tostring()](http://www.lua.org/manual/5.1/manual.html#pdf-tostring) or [string.format()](http://www.lua.org/manual/5.1/manual.html#pdf-string.format) before this function.

[fwrite]: http://www.lua.org/manual/5.1/manual.html#pdf-file:write

###  `socket:lines() → iterator`

_This function implements the interface of the [file:lines()] [flines] function described in the Lua 5.1 reference manual. Here is the description from the reference manual:_

Return an iterator function that, each time it is called, returns a new line read from the socket. Therefore, the construction

    for line in socket:lines() do body end

will iterate over all lines. This function does not close the socket when the loop ends.

[flines]: http://www.lua.org/manual/5.1/manual.html#pdf-file:lines

###  `socket:timeout_get() → timeout`

Get the timeout value or blocking state of <tt>*socket*</tt>. On success the timeout
value is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

The <tt>*timeout*</tt> <tt>*true*</tt> means wait forever, <tt>*false*</tt> means don't wait at all and a
number is the microseconds to wait.

###  `socket:timeout_set(timeout) → status`

Set the timeout value or blocking state of <tt>*socket*</tt>. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

The <tt>*timeout*</tt> <tt>*true*</tt> means wait forever, <tt>*false*</tt> means don't wait at all and a
number is the microseconds to wait.

###  `socket:opt_get(name) → value`

Query socket options for the specified socket. Valid values for <tt>*name*</tt> are:

 - `'debug'`: turn on debugging information
 - `'keep-alive'`: keep connections active
 - `'linger'`: lingers on close if data is present
 - `'non-block'`: turns blocking on/off for socket
 - `'reuse-addr'`: the rules used in validating addresses supplied to bind
   should allow reuse of local addresses
 - `'sndbuf'`: set the send buffer size
 - `'rcvbuf'`: set the receive buffer size
 - `'disconnected'`: query the disconnected state of the socket (currently only used on Windows)

The `'sndbuf'` and `'rcvbuf'` options have integer values, all other options
have a boolean value.

###  `socket:opt_set(name, value) → status`

Setup socket options for the specified socket. Valid values for <tt>*name*</tt> are
documented under [socket:opt\_get()](#socket:opt_get), <tt>*value*</tt> should be a boolean or integer
value. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error
message is returned.

###  `socket:addr_get([type]) → ip_address, port [, hostname]`

Get one of the IP-address / port pairs associated with <tt>*socket*</tt>, according to
<tt>*type*</tt>:

 - `'local'` to get the address/port to which the socket is bound locally
 - `'remote'` to get the address/port of the peer to which the socket is
   connected (this is the default)

On success the local or remote IP-address (a string) and the port (a number)
are returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. If a
host name is available that will be returned as the third value.

*This function is not binary safe.*

###  `socket:fd_get() → fd`

Get the underlying [file descriptor] [fildes] for this socket. On success a
number is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

[fildes]: http://en.wikipedia.org/wiki/File_descriptor

###  `socket:fd_set(fd) → status`

Set the underlying file descriptor (a number) of an existing socket. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

###  `socket:shutdown(mode) → status`

Shutdown either reading, writing, or both sides of a socket. On success <tt>*true*</tt>
is returned, otherwise a <tt>*nil*</tt> followed by an error message is returned. Valid
values for <tt>*mode*</tt> are:

 - `'read'`: no longer allow read requests
 - `'write'`: no longer allow write requests
 - `'both'`: no longer allow read or write requests

This does not actually close the socket descriptor, it just controls which
calls are still valid on the socket. To close sockets see [socket:close()](#socket:close).

###  `socket:close() → status`

Close <tt>*socket*</tt>. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an
error message is returned.

## Pipe I/O handling

Lua/APR represents [pipes] [pipeline] as files just like Lua's standard
library function [io.popen()](http://www.lua.org/manual/5.1/manual.html#pdf-io.popen) does because it works fairly well, however
there are some differences between files and pipes which impact the API:

 - File objects implement [pipe:timeout\_get()](#pipe:timeout_get) and [pipe:timeout\_set()](#pipe:timeout_set) even
 though these methods only make sense for pipe objects

 - Pipe objects implement [file:seek()](#file:seek) but don't support it

One of the reasons that file/pipe support is so interwoven in APR and thus
Lua/APR is that you can create a named pipe with [apr.namedpipe\_create()](#apr.namedpipe_create)
and access it using [apr.file\_open()](#apr.file_open) and APR won't know or even care that
you're reading/writing a pipe instead of a file.

[pipeline]: http://en.wikipedia.org/wiki/Pipeline_(Unix)

###  `apr.pipe_open_stdin() → pipe`

Open standard input as a pipe. On success the pipe is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned.

###  `apr.pipe_open_stdout() → pipe`

Open standard output as a pipe. On success the pipe is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned.

###  `apr.pipe_open_stderr() → pipe`

Open standard error as a pipe. On success the pipe is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned.

###  `apr.namedpipe_create(name [, permissions]) → status`

Create a [named pipe] [named_pipe]. On success <tt>*true*</tt> is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned. The [permissions](#file_system_permissions) argument is
documented elsewhere.

Named pipes can be used for interprocess communication:

1. Check if the named pipe already exists, if it doesn't then create it
2. Have each process access the named pipe using [apr.file\_open()](#apr.file_open)
3. Communicate between the two processes over the read/write ends of the
   named pipe and close it when the communication is finished.

Note that APR supports named pipes on UNIX but not on Windows. If you try
anyhow the error message "This function has not been implemented on this
platform" is returned.

[named_pipe]: http://en.wikipedia.org/wiki/Named_pipe

*This function is not binary safe.*

###  `apr.pipe_create() → input, output`

Create an [anonymous pipe] [anon_pipe]. On success the write and read ends
of the pipe are returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned. There's an example use of this function in the documentation for
[process:in\_set()](#process:in_set).

[anon_pipe]: http://en.wikipedia.org/wiki/Anonymous_pipe

## LDAP connection handling

The Lightweight Directory Access Protocol ([LDAP] [ldap]) enables querying
and modifying data hosted on [directory servers] [dirs]. LDAP databases are
similar to [relational databases] [reldbs] in the sense that both types of
databases store records with attributes and allow clients to search records
based on those attributes. Notable differences between LDAP and relational
databases are that LDAP stores all records in a [hierarchy] [hierarchy] and
records can have an arbitrary number of attributes. LDAP is frequently used
by (large) organizations to provide a centralized address book for all
employees and to store system account information like user names and
passwords in a central place (one piece of the puzzle towards [roaming
profiles] [roaming]).

This module is based on [LuaLDAP] [lualdap] by Roberto Ierusalimschy, André
Carregal and Tomás Guisasola.

[ldap]: http://en.wikipedia.org/wiki/LDAP
[dirs]: http://en.wikipedia.org/wiki/Directory_(databases)
[reldbs]: http://en.wikipedia.org/wiki/Relational_database
[hierarchy]: http://en.wikipedia.org/wiki/Hierarchical_database_model
[roaming]: http://en.wikipedia.org/wiki/Roaming_user_profile
[lualdap]: http://www.keplerproject.org/lualdap/

###  `apr.ldap([url [, secure ]]) → ldap_conn`

Create an LDAP connection. The <tt>*url*</tt> argument is a URL string with the
following components:

 - One of the URL schemes `ldap://` (the default) or `ldaps://` (for secure
   connections)
 - The host name or IP-address of the LDAP server (defaults to <IP_ADDRESS>)
 - An optional port number (defaults to 389)

If <tt>*secure*</tt> is <tt>*true*</tt> the connection will use [STARTTLS] [starttls] even if the
URL scheme is `ldap://`. On success an LDAP connection object is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

[starttls]: http://en.wikipedia.org/wiki/STARTTLS

###  `apr.ldap_info() → string`

This function returns a string describing the LDAP [SDK] [sdk] (library)
currently in use. On success a string is returned, otherwise a <tt>*nil*</tt> followed
by an error message is returned. The resulting string is intended to be
displayed to the user, it's not meant to be parsed (although you can of
course decide to do this :-). According to [apr_ldap.h] [ldap_docs] the
following LDAP SDKs can be used:

 - Netscape (I assume this been superseded by the Mozilla SDK below)
 - Solaris
 - [Novell](http://www.novell.com/developer/ndk/ldap_libraries_for_c.html)
 - [Mozilla](https://wiki.mozilla.org/Directory)
 - [OpenLDAP](http://www.openldap.org/software/man.cgi?query=ldap)
 - [Microsoft] [ms_ldap_sdk]
 - [Tivoli](http://en.wikipedia.org/wiki/IBM_Tivoli_Directory_Server)
 - [zOS](http://www.lsu.edu/departments/ocs/tsc/ldap/ldappref.html)
 - 'Others' (implying there is support for other SDKs?)

[sdk]: http://en.wikipedia.org/wiki/Software_development_kit
[ms_ldap_sdk]: http://msdn.microsoft.com/en-us/library/aa367008(v=vs.85).aspx
[ldap_docs]: http://apr.apache.org/docs/apr/trunk/group___a_p_r___util___l_d_a_p.html

###  `apr.ldap_url_parse(string) → table`

Parse an [LDAP URL] [ldap_urls] into a table of URL components. On success a
table is returned, otherwise a <tt>*nil*</tt> followed by an error message and one of
the following strings is returned:

 - **MEM**: can't allocate memory space
 - **PARAM**: parameter is bad
 - **BADSCHEME**: URL doesn't begin with `ldap://`, `ldapi://` or `ldaps://`
 - **BADENCLOSURE**: URL is missing trailing `>`
 - **BADURL**: URL is bad
 - **BADHOST**: host port is bad
 - **BADATTRS**: bad (or missing) attributes
 - **BADSCOPE**: scope string is invalid (or missing)
 - **BADFILTER**: bad or missing filter
 - **BADEXTS**: bad or missing extensions

LDAP URLs look like this:

    ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]

Where:

 - <tt>*attributes*</tt> is a comma separated list
 - <tt>*scope*</tt> is one of the three strings **base**, **one** or **sub** (the default is **base**)
 - <tt>*filter*</tt> is an string-represented filter as in RFC 2254

For example:

    > = apr.ldap_url_parse 'ldap://root.openldap.org/dc=openldap,dc=org'
    {
      scheme = 'ldap',
      host = 'root.openldap.org',
      port = 389,
      scope = 'sub',
      dn = 'dc=openldap,dc=org',
      crit_exts = 0,
    }

[ldap_urls]: http://en.wikipedia.org/wiki/LDAP#LDAP_URLs

###  `apr.ldap_url_check(url) → type`

Checks whether the given URL is an LDAP URL. On success one of the strings
below is returned, otherwise <tt>*nil*</tt> is returned:

 - **ldap** for regular LDAP URLs (`ldap://`)
 - **ldapi** for socket LDAP URLs (`ldapi://`)
 - **ldaps** for SSL LDAP URLs (`ldaps://`)

###  `ldap_conn:bind([who [, passwd]]) → status`

Bind to the LDAP directory. If no arguments are given an anonymous bind is
attempted, otherwise <tt>*who*</tt> should be a string with the relative distinguished
name (RDN) of the user in the form `'cn=admin,dc=example,dc=com'`. On
success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

###  `ldap_conn:unbind() → status`

Unbind from the directory. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt>
followed by an error message is returned.

###  `ldap_conn:option_get(name) → value`

Get an LDAP option by its <tt>*name*</tt> (one of the strings documented below). On
success the option value is returned, otherwise a <tt>*nil*</tt> followed by an error
message is returned. These are the supported LDAP options:

 - **defbase** (string)
 - **deref** (integer)
 - **network-timeout** (fractional number of seconds)
 - **protocol-version** (integer)
 - **refhop-limit** (integer)
 - **referral-urls** (list of strings)
 - **referrals** (boolean)
 - **restart** (boolean)
 - **size-limit** (integer)
 - **time-limit** (integer)
 - **timeout** (fractional number of seconds)
 - **uri** (string with space separated URIs)

###  `ldap_conn:option_set(name, value) → status`

Set the LDAP option <tt>*name*</tt> (one of the strings documented for
[ldap\_conn:option\_get()](#ldap_conn:option_get)) to <tt>*value*</tt>. On success <tt>*true*</tt> is returned, otherwise
a <tt>*nil*</tt> followed by an error message is returned.

###  `ldap_conn:rebind_add([who [, password]]) → status`

LDAP servers can return referrals to other servers for requests the server
itself will not/can not serve. This function creates a cross reference entry
for the specified LDAP connection. The rebind callback function will look up
this LDAP connection so it can retrieve the <tt>*who*</tt> and <tt>*password*</tt> fields for
use in any binds while referrals are being chased.

On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

When the LDAP connection is garbage collected the cross reference entry is
automatically removed, alternatively [ldap\_conn:rebind\_remove()](#ldap_conn:rebind_remove) can be
called to explicitly remove the entry.

###  `ldap_conn:rebind_remove() → status`

Explicitly remove an LDAP cross reference entry (also done automatically
when the LDAP connection is garbage collected). On success <tt>*true*</tt> is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

###  `ldap_conn:search(parameters) → iterator`

_The implementation of this method is based on LuaLDAP and the following
documentation was based on the [LuaLDAP manual] [lualdap]:_

Performs a search operation on the directory. The parameters are described
below. The search method will return a search iterator which is a function
that requires no arguments. The search iterator is used to get the search
result and will return a string representing the distinguished name and a
table of attributes as returned by the search request.

Supported parameters:

 - **attrs**: a string or a list of attribute names to be retrieved (default
   is to retrieve all attributes)

 - **attrsonly**: a boolean value that must be either <tt>*false*</tt> (default) if
   both attribute names and values are to be retrieved, or <tt>*true*</tt> if only
   names are wanted

 - **base**: The [distinguished name] [distinguished_name] of the entry at
   which to start the search

 - **filter**: A string representing the search filter as described in [The
   String Representation of LDAP Search Filters] [rfc2254] (RFC 2254)

 - **scope**: A string indicating the scope of the search. The valid strings
   are: _base_, _one_ and _sub_. The empty string and <tt>*nil*</tt> will be treated as
   the default scope

 - **sizelimit**: The maximum number of entries to return (default is no
   limit)

 - **timeout**: The timeout in seconds (default is no timeout). The
   precision is microseconds

[distinguished_name]: http://www.keplerproject.org/lualdap/manual.html#dn
[rfc2254]: http://www.ietf.org/rfc/rfc2254.txt
[lualdap]: http://www.keplerproject.org/lualdap/manual.html#connection

###  `ldap_conn:add(dn, attrs) → future`

Add a new entry to the directory. The string <tt>*dn*</tt> is the distinguished name
of the new entry. The table <tt>*attrs*</tt> contains the attributes and values.
Returns a function to process the LDAP result.

*This function is not binary safe.*

###  `ldap_conn:compare(dn, attr, value) → future`

Compare a value against an entry. The string <tt>*dn*</tt> contains the distinguished
name of the entry, the string <tt>*attr*</tt> is the name of the attribute to compare
and the string <tt>*value*</tt> is the value to compare against. Returns a function to
process the LDAP result.

*This function is not binary safe.*

###  `ldap_conn:delete(dn) → future`

Delete an entry. The string <tt>*dn*</tt> is the distinguished name of the entry to
delete. Returns a function to process the LDAP result.

*This function is not binary safe.*

###  `ldap_conn:modify(dn, mods [, ...]) → future`

Modify an entry. The string <tt>*dn*</tt> is the distinguished name of the entry to
modify. The table <tt>*mods*</tt> contains modifications to apply. You can pass any
number of additional tables with modifications to apply. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

*This function is not binary safe.*

###  `ldap_conn:rename(dn, new_rdn [, new_parent [, delete]]) → future`

Change the distinguished name of an entry. The string <tt>*dn*</tt> is the
distinguished name of the entry to rename. The string <tt>*new_rdn*</tt> gives the new
root distinguished name. The optional string <tt>*new_parent*</tt> gives the
distinguished name of the new parent for the entry. If the optional argument
<tt>*delete*</tt> is <tt>*true*</tt> the entry is removed from it's old parent. Returns a
function to process the LDAP result.

*This function is not binary safe.*

## Memcached client

[Memcached] [memcached] is a "distributed memory object caching system".
It's designed as an in-memory key-value store for small chunks of arbitrary
data (strings, objects) from results of database calls, API calls, or page
rendering. The memcached client module makes it possible to read from and
write to one or more memcached servers over a network socket in Lua.

To-do: Find out if "flags" can be any 32 bits value and how useful it is
to Lua.

[memcached]: http://memcached.org/

###  `apr.memcache([max_servers]) → mc_client`

Create a memcached client. The optional argument <tt>*max_servers*</tt> determines the
maximum number of memcached servers supported by the client (defaults to
10). On success the client object is returned, otherwise <tt>*nil*</tt> followed by an
error message is returned.

###  `mc_client:hash(str) → hash`

Create a [CRC32] [crc] hash used to split keys between servers.
The hash is not compatible with old memcached clients.

[crc]: http://en.wikipedia.org/wiki/Cyclic_redundancy_check

*This function is binary safe.*

###  `mc_client:find_server_hash(hash) → mc_server`

Picks a server based on a hash. Returns the info of the server that controls
the specified hash.

###  `mc_client:add_server(host, port [, min [, smax [, max [, ttl]]]]) → mc_server`

Create a new server object and add it to the client object. On success the
server object is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned. The parameters have the following meaning:

 - <tt>*host*</tt>: hostname of server
 - <tt>*port*</tt>: port of server (usually 11211)
 - <tt>*min*</tt>:  minimum number of client sockets to open (defaults to 0)
 - <tt>*smax*</tt>: soft maximum number of client connections to open (defaults to 1)
 - <tt>*max*</tt>:  hard maximum number of client connections (defaults to 1)
 - <tt>*ttl*</tt>:  time to live in microseconds of a client connection (defaults to 60000)

Note that <tt>*min*</tt>, <tt>*smax*</tt> and <tt>*max*</tt> are only used when APR was compiled with
threads. Also a word of caution: Changing servers after startup may cause
keys to go to different servers.

###  `mc_client:find_server(host, port) → mc_server`

Finds a server object based on a (hostname, port) pair. On success the
server with matching host name and port is returned, otherwise nothing is
returned.

###  `mc_client:enable_server(mc_server) → status`

Enable a server for use again after disabling the server with
[mc\_client:disable\_server()](#mc_client:disable_server). On success <tt>*true*</tt> is returned,
otherwise <tt>*nil*</tt> followed by an error message is returned.

###  `mc_client:disable_server(mc_server) → status`

Disable a server. On success <tt>*true*</tt> is returned, otherwise <tt>*nil*</tt> followed by an
error message is returned.

###  `mc_client:get(key [, ...]) → status, value [, ...]`

Get one or more values from the server. On success <tt>*true*</tt> is returned followed
by the retrieved value(s), otherwise <tt>*nil*</tt> followed by an error message is
returned. The keys are null terminated strings and the return values are
binary safe strings. Keys that don't have an associated value result in <tt>*nil*</tt>.

###  `mc_client:set(key, value [, timeout]) → status`

Sets a value by key on the server. If the key already exists the old value
will be overwritten. The <tt>*key*</tt> is a null terminated string, the <tt>*value*</tt> is a
binary safe string and <tt>*timeout*</tt> is the time in seconds for the data to live
on the server (a number, defaults to 60 seconds). On success <tt>*true*</tt> is
returned, otherwise <tt>*nil*</tt> followed by an error message is returned.

###  `mc_client:add(key, value [, timeout]) → status`

Adds a value by key on the server. If the key already exists this call will
fail and the old value will be preserved. The arguments and return values
are documented under [mc\_client:set()](#mc_client:set).

###  `mc_client:replace(key, value [, timeout]) → status`

Replace a value by key on the server. If the key doesn't exist no value will
be set. The arguments and return values are documented under
[mc\_client:set()](#mc_client:set).

###  `mc_client:delete(key [, timeout]) → status`

Delete a key from the server. The <tt>*key*</tt> is a null terminated string and
<tt>*timeout*</tt> is the time in seconds for the delete to stop other clients from
adding (a number, defaults to 10 seconds). On success <tt>*true*</tt> is returned,
otherwise <tt>*nil*</tt> followed by an error message is returned.

###  `mc_client:incr(key [, number]) → value`

Increment a value. The <tt>*key*</tt> is a null terminated string and the optional
argument <tt>*number*</tt> is the number to increment by (defaults to 1). On success
the new value after incrementing is returned, otherwise <tt>*nil*</tt> followed by an
error message is returned.

###  `mc_client:decr(key [, number]) → value`

Decrement a value. The <tt>*key*</tt> is a null terminated string and the optional
argument <tt>*number*</tt> is the number to decrement by (defaults to 1). On success
the new value after decrementing is returned, otherwise <tt>*nil*</tt> followed by an
error message is returned.

###  `mc_client:version(mc_server) → version`

Query a server's version. On success the version string is returned,
otherwise <tt>*nil*</tt> followed by an error message is returned.

###  `mc_client:stats() → statistics`

Query a server for statistics. On success a table with information is
returned, otherwise <tt>*nil*</tt> followed by an error message is returned. The
following fields are supported:

 - <tt>*version*</tt>: version string of the server
 - <tt>*pid*</tt>: process ID of the server process
 - <tt>*uptime*</tt>: number of seconds this server has been running
 - <tt>*time*</tt>: current UNIX time according to the server
 - <tt>*rusage_user*</tt>: accumulated user time for this process
 - <tt>*rusage_system*</tt>: accumulated system time for this process
 - <tt>*curr_items*</tt>: current number of items stored by the server
 - <tt>*total_items*</tt>: total number of items stored by this server
 - <tt>*bytes*</tt>: current number of bytes used by this server to store items
 - <tt>*curr_connections*</tt>: number of open connections
 - <tt>*total_connections*</tt>: total number of connections opened since the server started running
 - <tt>*connection_structures*</tt>: number of connection structures allocated by the server
 - <tt>*cmd_get*</tt>: cumulative number of retrieval requests
 - <tt>*cmd_set*</tt>: Cumulative number of storage requests
 - <tt>*get_hits*</tt>: number of keys that have been requested and found present
 - <tt>*get_misses*</tt>: number of items that have been requested and not found
 - <tt>*evictions*</tt>: number of items removed from cache because they passed their expiration time
 - <tt>*bytes_read*</tt>: total number of bytes read by this server
 - <tt>*bytes_written*</tt>: total number of bytes sent by this server
 - <tt>*limit_maxbytes*</tt>: number of bytes this server is allowed to use for storage
 - <tt>*threads*</tt>: number of threads the server is running (if built with threading)

## Command argument parsing

###  `apr.getopt(usage [, config ]) → options, arguments`

Parse the [command line arguments] [cmdargs] according to the option letters
and/or long options defined in the string <tt>*usage*</tt> (see the example below) and
return a table with the matched options and a table with any remaining
positional arguments. When an option is matched multiple times, the
resulting value in <tt>*options*</tt> depends on the following context:

 * If the option doesn't take an argument, the value will be a number
   indicating the number of times that the option was matched

 * If the option takes an argument and only one option/argument pair is
   matched, the value will be the argument (a string). When more than one
   pair is matched for the same option letter/name, the values will be
   collected in a table

The optional <tt>*config*</tt> table can be used to change the following defaults:

 * When <tt>*usage*</tt> mentions `-h` or `--help` and either of these options is
   matched in the arguments, [apr.getopt()](#apr.getopt) will print the usage message
   and call [os.exit()](http://www.lua.org/manual/5.1/manual.html#pdf-os.exit). To avoid this set `config.show_usage` to <tt>*false*</tt>
   (not <tt>*nil*</tt>!)

 * When an error is encountered during argument parsing, [apr.getopt()](#apr.getopt) will
   print a warning about the invalid argument and call [os.exit()](http://www.lua.org/manual/5.1/manual.html#pdf-os.exit). To avoid
   this set `config.handle_errors` to <tt>*false*</tt> (not <tt>*nil*</tt>!)

 * By default the arguments in the global variable [arg] [arg-global] will
   be used, but you can set `config.args` to a table of arguments to be
   used instead

Here is a short example of a valid Lua script that doesn't really do
anything useful but demonstrates the use of [apr.getopt()](#apr.getopt):

    apr = require 'apr'
    opts, args = apr.getopt [[
    Usage: echo.lua [OPTIONS] ARG...
      -h, --help     show this message and exit
      -v, --verbose  make more noise
          --version  print version and exit
    ]]
    if opts.version then
      print "This is version 0.1"
    else
      if opts.verbose then
        print("Got", #args, "arguments")
      end
      if opts.verbose >= 2 then
        print "Here they are:"
      end
      for i = 1, #args do print(args[i]) end
    end

The [apr.getopt()](#apr.getopt) function is very similar to [Lapp] [lapp] by Steve
Donovan although Lapp is more full featured, for example it validates and
converts argument types.

[cmdargs]: http://en.wikipedia.org/wiki/Command-line_argument
[arg-global]: http://www.lua.org/manual/5.1/manual.html#6
[lapp]: http://lua-users.org/wiki/LappFramework

## HTTP request parsing

This module is an experimental binding to the [apreq2] [apreq2] library
which enables [HTTP] [http] request parsing of [query strings] [qstrings],
[headers] [headers] and [multipart messages] [multipart]. Some general notes
about the functions in this module:

 - None of the extracted strings (except maybe for request bodies) are
   binary safe because (AFAIK) HTTP headers are not binary safe

 - Parsed name/value pairs are converted to a Lua table using two rules:
   names without a value get the value <tt>*true*</tt> and duplicate names result in a
   table that collects all values for the given name

 - When a parse error is encountered after successfully parsing part of the
   input, the results of the function are followed by an error message and
   error code (see below)

The functions in this module return three values on error: a <tt>*nil*</tt> followed by
an error message and an error code. This module defines the following error
codes (in addition to the [generic Lua/APR error codes](#error_handling)):

 - `'EBADARG'`: bad arguments
 - `'GENERAL'`: internal apreq2 error
 - `'TAINTED'`: attempted to perform unsafe action with tainted data
 - `'INTERRUPT'`: parsing interrupted
 - `'BADDATA'`: invalid input data
 - `'BADCHAR'`: invalid character
 - `'BADSEQ'`: invalid byte sequence
 - `'BADATTR'`: invalid attribute
 - `'BADHEADER'`: invalid header
 - `'BADUTF8'`: invalid UTF-8 encoding
 - `'NODATA'`: missing input data
 - `'NOTOKEN'`: missing required token
 - `'NOATTR'`: missing attribute
 - `'NOHEADER'`: missing header
 - `'NOPARSER'`: missing parser
 - `'MISMATCH'`: conflicting information
 - `'OVERLIMIT'`: exceeds configured maximum limit
 - `'UNDERLIMIT'`: below configured minimum limit
 - `'NOTEMPTY'`: setting already configured

[apreq2]: http://httpd.apache.org/apreq/
[http]: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
[qstrings]: http://en.wikipedia.org/wiki/Query_string
[headers]: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
[multipart]: http://en.wikipedia.org/wiki/MIME#Multipart_messages

###  `apr.parse_headers(request) → headers, body`

Parse the [headers] [headers] in a [HTTP] [http] request string according to
[RFC 822] [rfc822]. On success a table of header name/value pairs and the
request body string are returned, otherwise <tt>*nil*</tt> followed by an error message
is returned.

There are some gotchas in using this function:

 - It will fail if anything comes before the headers, so be sure to strip
   the status line from the request string before calling this function

 - If the request string doesn't contain an empty line to separate the
   headers from the body, the last header might be silently discarded

[rfc822]: http://tools.ietf.org/html/rfc822

###  `apr.parse_multipart(request, enctype [, limit [, tempdir]]) → parts`

Parse a [multipart/form-data] [mp_formdata] or [multipart/related]
[mp_related] HTTP request body according to [RFC 2388] [rfc2388] and the
boundary string in <tt>*enctype*</tt>. On success the table with parameter name/value
pairs is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

The optional number <tt>*limit*</tt> gives the maximum in-memory bytes that the data
structure used to parse the request may use (it defaults to 1024 KB), but be
aware that because of internal copying [apr.parse\_multipart()](#apr.parse_multipart) can use more
than double this amount of memory while parsing a request.

The optional string <tt>*tempdir*</tt> is the directory used for temporary storage of
large uploads.

[mp_formdata]: http://en.wikipedia.org/wiki/MIME#Form_Data
[mp_related]: http://en.wikipedia.org/wiki/MIME#Related
[rfc2388]: http://tools.ietf.org/html/rfc2388

###  `apr.parse_cookie_header(header) → cookies`

Parse a cookie header and store the cookies in a Lua table. On success the
table with cookie name/value pairs is returned, otherwise <tt>*nil*</tt> followed by an
error message and error code is returned.

###  `apr.parse_query_string(query_string) → parameters`

Parse a URL encoded string into a Lua table. On success the table with
parameter name/value pairs is returned, otherwise <tt>*nil*</tt> followed by an error
message and error code is returned.

This function uses `&` and `;` as the set of tokens to delineate words, and
will treat a word without `=` as a name/value pair with the value <tt>*true*</tt>.

###  `apr.header_attribute(header, name) → value`

Search a header string for the value of a particular named attribute. On
success the matched value is returned, otherwise <tt>*nil*</tt> followed by an error
message is returned.

*This function is not binary safe.*

###  `apr.uri_encode(string) → encoded`

Encode unsafe bytes in <tt>*string*</tt> using [percent-encoding] [percenc] so that
the string can be embedded in a [URI] [uri] query string.

[percenc]: http://en.wikipedia.org/wiki/Percent-encoding

*This function is not binary safe.*

###  `apr.uri_decode(encoded) → string`

Decode all [percent-encoded] [percenc] bytes in the string <tt>*encoded*</tt>.

*This function is binary safe.*

## Pollset

The pollset module enables [asynchronous I/O] [wp_async_io] which can
improve throughput, latency and/or responsiveness. It works as follows:

 1. Create a pollset object by calling [apr.pollset()](#apr.pollset)
 2. Add one or more sockets to the pollset (e.g. a server socket listening
    for connections or a bunch of sockets receiving data)
 3. Call [pollset:poll()](#pollset:poll) in a loop to process readable/writable sockets

You can keep adding and removing sockets from the pollset at runtime, just
keep in mind that the size given to [apr.pollset()](#apr.pollset) is a hard limit. There
is an example of a [simple asynchronous webserver] [async_server] that uses
a pollset.

[wp_async_io]: http://en.wikipedia.org/wiki/Asynchronous_I/O
[async_server]: #example_asynchronous_webserver

###  `apr.pollset(size) → pollset`

Create a pollset object. The number <tt>*size*</tt> is the maximum number of sockets
that the pollset can hold. On success a pollset object is returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned.

###  `pollset:add(socket, flag [, ...]) → status`

Add a network socket to the pollset. On success <tt>*true*</tt> is returned, otherwise
a <tt>*nil*</tt> followed by an error message is returned. One or two of the following
flags should be provided:

 - `'input'` indicates that the socket can be read without blocking
 - `'output'` indicates that the socket can be written without blocking

If the socket is already in the pollset the flags of the existing entry in
the pollset will be combined with the new flags. If you want to *change* a
socket from readable to writable or the other way around, you have to first
remove the socket from the pollset and then add it back with the new flag.

###  `pollset:remove(socket) → status`

Remove a <tt>*socket*</tt> from the pollset. On success <tt>*true*</tt> is returned, otherwise a
<tt>*nil*</tt> followed by an error message is returned. It is not an error if the
socket is not contained in the pollset.

###  `pollset:poll(timeout) → readable, writable`

Block for activity on the descriptor(s) in a pollset. The <tt>*timeout*</tt> argument
gives the amount of time in microseconds to wait. This is a maximum, not a
minimum.  If a descriptor is signaled, we will wake up before this time. A
negative number means wait until a descriptor is signaled. On success a
table with sockets waiting to be read followed by a table with sockets
waiting to be written is returned, otherwise a <tt>*nil*</tt> followed by an error
message is returned.

###  `pollset:destroy() → status`

Destroy a pollset. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by
an error message is returned. Note that pollset objects are automatically
destroyed when they are garbage collected.

## Process handling

###  `apr.proc_create(program) → process`

Create a child process that will execute the given <tt>*program*</tt> when started.
Once you've called this function you still need to execute the process using
the [process:exec()](#process:exec) function. Here's a simple example that emulates Lua's
[os.execute()](http://www.lua.org/manual/5.1/manual.html#pdf-os.execute) function:

    function execute(command)
      local arguments = apr.tokenize_to_argv(command)
      local progname = table.remove(arguments, 1)
      local process = apr.proc_create(progname)
      process:cmdtype_set('shellcmd/env')
      process:exec(arguments)
      local done, code, why = process:wait(true)
      return code
    end

    execute 'echo This can be any process...'

*This function is not binary safe.*

###  `apr.proc_detach(daemonize) → status`

Detach the current process from the controlling terminal. If <tt>*daemonize*</tt>
evaluates to <tt>*true*</tt> the process will [daemonize] [daemons] and become a
background process, otherwise it will stay in the foreground. On success
<tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed by an error message is
returned.

[daemons]: http://en.wikipedia.org/wiki/Daemon_(computer_software)

###  `apr.proc_fork() → process, context`

This is currently the only non-portable function in APR and by extension
Lua/APR. It performs a [standard UNIX fork][fork]. If the fork succeeds a
<tt>*process*</tt> object and <tt>*context*</tt> string (`'parent'` or `'child'`) are returned,
otherwise a <tt>*nil*</tt> followed by an error message is returned. The parent process
can use the returned <tt>*process*</tt> object to wait for the child process to die:

    if apr.proc_fork then -- forking supported?
      process, context = assert(apr.proc_fork())
      if context == 'parent' then
        print "Parent waiting for child.."
        process:wait(true)
        print "Parent is done!"
      else -- context == 'child'
        print "Child simulating activity.."
        apr.sleep(10)
        print "Child is done!"
      end
    end

As the above example implies the [apr.proc\_fork()](#apr.proc_fork) function will only be
defined when forking is supported on the current platform.

[fork]: http://en.wikipedia.org/wiki/Fork_(operating_system)

###  `process:addrspace_set(separate) → status`

If <tt>*separate*</tt> evaluates to <tt>*true*</tt> the child process will start in its own
address space, otherwise the child process executes in the current address
space from its parent. On success <tt>*true*</tt> is returned, otherwise a <tt>*nil*</tt> followed
by an error message is returned. The default is no on NetWare and yes on
other platforms.

###  `process:user_set(username [, password]) → status`

Set the user under which the child process will run. On success <tt>*true*</tt> is
returned, otherwise a <tt>*nil*</tt> followed by an error message is returned.

On Windows and other platforms where `apr.user_set_requires_password` is
<tt>*true*</tt>

repository: LuaDist/lua-apr

gha_language: C

repo_name: LuaDist/lua-apr