Data Pile

Against Digital Amnesia

Programming With the APR

This article will give you an introduction of how to program with the Apache Portable Runtime (APR). It illustrates a simple command line program.

NOTE: The program supplied should actually use apr_app_initialize(&argc, &argv, NULL); since apr_initialize() is intended for library use only.

I was playing around with the Apache Portable Runtime (APR) recently and found out, probably the most difficult part was to find out how to compile the program you have just written. The probably most famous projects using APR are the Apache HTTPd and Subversion.

Overview

APR’s goal is to provide a platform independent API that provides a consistent interface to the platform specific implementation. The APR code itself is pretty good documented. But i wouldn’t say you’d find plenty of resources on the web. Especially a simple example on how to program with the APR was missing for me.

Example program

I put together an example program which shows how to use the APR. This includes instructions on how to get the program compiled after you have written it. This seems to be so self-evident to people, that no one seems to write that up. The heart of this process lies in the usage of the apr-config, or sometimes called apr-1-config utility.

Preconditions

Make sure you have the APR development files installed. Since i am mostly working with Debian based distributions, like Debian itself or Ubuntu, i install the libraries with my package management system. Of course make sure you install the “-dev” versions of APR. For me that have been the packages

  • libapr1
  • libapr1-dbg
  • libapr1-dev
  • libaprutil1
  • libaprutil1-dbg
  • libaprutil1-dev

You can get those packages by issuing the following command on the command line (this may of course vary if you are not using a Debian based distribution or if you install from source).

Install APR Development Libraries
1
$ sudo apt-get install libapr1 libapr1-dbg libapr1-dev libaprutil1 libaprutil1-dbg libaprutil1-dev

Program code

The program itself is obviously a pretty easy one, it basically allocates resources from a memory pool managed through APR onto a struct and later simply prints the allocated values. The programs code is as follows.

Simple APR Program (simple_apr.c) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <apr.h>
#include <apr_general.h>
#include <apr_pools.h>
#include <stdlib.h>
#include <stdio.h>
#include <apr_strings.h>
#include <apr_time.h>

/* Compile this beast with 
 * $> export APR_LIBS="`apr-1-config --cflags --cppflags --includes --ldflags --link-ld --libs`"
 * $> gcc simple_apr.c -o simple_apr $APR_LIBS
 */
typedef struct user
{
  apr_time_t *creationDate;
  char *username;
  char *password;
} user;

int main(int argc, char **argv)
{

  apr_pool_t *pool = NULL;
  user *user = NULL;
  char *time = NULL;

  /* Initialize APR at the program start */
  apr_initialize();

  /* atexit(apr_terminate()); gives 
   * error: invalid use of void expression 
   */
  atexit(apr_terminate);

  /* create a managed memory pool with APR */
  apr_pool_create(&pool, NULL);

  /* Init the struct */
  user = apr_palloc(pool, sizeof(struct user));

  /* Assign strings via the pool */
  user->username = apr_pstrdup(pool, "Jens Frey");
  user->password = apr_pstrdup(pool, "secret");

  /* Assign binary mem */
  apr_time_t now = apr_time_now();
  user->creationDate = apr_pmemdup(pool, &now, sizeof(apr_time_t));

  printf("Username: %s\n", user->username);
  printf("Password: %s\n", user->password);
  printf("Time: %" APR_TIME_T_FMT "\n", *user->creationDate);

  time = apr_palloc(pool, APR_RFC822_DATE_LEN);
  apr_rfc822_date(time, *user->creationDate);
  printf("Time readable: %s\n", time);

  apr_pool_destroy(pool);

  return 0;
}

Compile the program

Now there comes the next crucial step in getting your program to fly. To do so you probably best export a variable as suggested by the apr-1-config tool. Then you can go on an compile your program the “normal” way you’d do that. If you do not want debug symbols compiled into your code, you of course would remove the “-g” option in front of the APR_LIBS variable.

Simple APR Program Compilation
1
2
$> export APR_LIBS="`apr-1-config --cflags --cppflags --includes --ldflags --link-ld --libs`"
$> gcc -g simple_apr.c -o simple_apr $APR_LIBS

By executing the program your output should now look something like that:

Ouput
1
2
3
4
5
$ ./simple_apr
Username: Jens Frey
Password: secret
Time: 1231102877630911
Time readable: Sun, 04 Jan 2009 21:01:17 GMT

I hope you achieved similar results.

References