#include <aio.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

struct aiocb * cb[2];

//The signal number to use.
#define SIG_AIO SIGRTMIN+5

//Signal handler called when an AIO operation finishes
void aio_handler(int signal, siginfo_t *info, void*uap)
{
    int cbNumber = info->si_value.sival_int;
    printf("AIO operation %d completed returning %d\n",
        cbNumber,
        aio_return(cb[cbNumber]));
}

int main(void)
{
    struct sigaction action;
    //Create a buffer to store the read data
    char * foo = calloc(1,20);
    //Set up the signal handler
    action.sa_sigaction = aio_handler;
    action.sa_flags = SA_SIGINFO;
    sigemptyset(&action.sa_mask);
    sigaction(SIG_AIO, &action, NULL);
    FILE * file = fopen("bar", "r+");

    //Allocate space for the aio control blocks
    cb[0] = calloc(1,sizeof(struct aiocb));
    cb[1] = calloc(1,sizeof(struct aiocb));
    //Somewhere to store the result
    cb[0]->aio_buf = foo;
    cb[1]->aio_buf = foo + 10;
    //The file to read from
    cb[0]->aio_fildes = fileno(file);
    cb[1]->aio_fildes = fileno(file);
    //The number of bytes to read, and the offset
    cb[0]->aio_nbytes = 10;
    cb[1]->aio_nbytes = 10;
    cb[0]->aio_offset = 0;
    cb[1]->aio_offset = 10;
    //The signal to send, and the value of the signal
    cb[0]->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
    cb[0]->aio_sigevent.sigev_signo = SIG_AIO;
    cb[0]->aio_sigevent.sigev_value.sival_int = 0;
    cb[1]->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
    cb[1]->aio_sigevent.sigev_signo = SIG_AIO;
    cb[1]->aio_sigevent.sigev_value.sival_int = 1;

    aio_read(cb[0]);
    aio_read(cb[1]);
    while(1){sleep(1);}
    sleep(1);
}