Writing Portable C Code with APR






Garrett Rooney

CollabNet

Introduction

Getting APR

Building on Unix

$ export P=$HOME/apr
$ tar zxvf apr-1.2.7.tar.gz
$ cd apr-1.2.7
$ ./configure --prefix=$P
$ make && make install
$ tar zxvf apr-util-1.2.7.tar.gz
$ cd apr-util-1.2.7
$ ./configure --prefix=$P --with-apr=$P/bin/apr-1-config
$ make && make install

Building on Windows

Hello APR World

#include <apr.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    apr_pool_t *pool;
    apr_file_t *out;

    apr_initialize();
    atexit(apr_terminate());

    apr_pool_create(&pool, NULL);
    apr_file_open_stdout(&out, pool);
    apr_file_printf(out, "Hello World\n");
    apr_pool_destroy(pool);

    return EXIT_SUCCESS;
}

How To Compile It

# first, cflags (i.e. -g -O2 -pthread)
$ export CFLAGS=`apr-1-config --cflags`
# then, cppflags (i.e. -I/path/to/includes -D_REENTRANT)
$ export CPPFLAGS=`apr-1-config --cppflags`
# then link options (i.e. -L /path/to/libs -lapr-1)
$ export LINK_LD=`apr-1-config --link-ld`
$ cc $CFLAGS $CPPFLAGS $LINK_LD program.c -o program

Things to note

  1. Initialize APR and set up apr_terminate via atexit
  2. Create a global pool
  3. Do our thing
  4. Destroy the pool

What's With The Pool?

Proper Pool Usage

const char *find_interesting_string(apr_pool_t *pool) {
    const char *interesting = NULL, *temp;
    apr_pool_t *subpool;
    int i;

    apr_pool_create (&subpool, pool);

    for (i = 0; i < 100; ++i) {
        apr_pool_clear(subpool);

        function_that_uses_temp_memory(&temp, subpool);

        if (retval_is_interesting(temp)) {
            interesting = apr_pstrdup(pool, temp);
            break;
        }
    }

    apr_pool_destroy(subpool);

    return interesting;
}

Error Handling

Good Error Handling

apr_status_t some_function(apr_pool_t *pool) {
    apr_status_t err;
    apr_file_t *fp;

    err = apr_file_open(&fp, "the-file-name", APR_READ,
                        APR_OS_DEFAULT, pool);
    if (APR_STATUS_IS_SUCCESS(err)) {
        /* read from the file... */
    } else if (APR_STATUS_IS_ENOENT(err)) {
        /* ok, the file wasn't found.  do something useful
         * here. */
        return err;
    } else {
        return err;
    }

    return APR_SUCCESS;
}

Data Structues

APR-Util

Examples

File I/O

cat/cat.c

Network I/O

XXX network client

Echo Server

echoserver/echoserver.c

Poll

XXX polling network server

Process Management

XXX fork
XXX executing processes

Threads

XXX threaded network server

Shared Memory

XXX come up with an example

Contributing to the Project

http://apr.apache.org/

http://svn.apache.org/repos/asf/apr/

dev@apr.apache.org

commits@apr.apache.org

Thank You

That's all Folks.