#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <err.h>

#ifdef RCSID
RCSID("$Id: read-vs-mmap2.c,v 1.2 1998/12/05 22:45:51 assar Exp $");
#endif

static void
generate_random_file (const char *filename, size_t sz)
{
    int fd;
    char *buf;
    int i;

    buf = malloc (sz);
    if (buf == NULL)
	err (1, "malloc %u", sz);

    fd = open (filename, O_WRONLY | O_CREAT, 0666);
    if (fd < 0)
	err (1, "open %s", filename);

    for (i = 0; i < sz; ++i)
	buf[i] = rand();

    if (write (fd, buf, sz) != sz)
	err (1, "write");
    if (close (fd))
	err (1, "close");
    free (buf);
}

static char *
read_file (int fd, size_t sz)
{
    char *buf;

    buf = malloc (sz);
    if (buf == NULL)
	err (1, "malloc %u", sz);
    if (read (fd, buf, sz) != sz)
	err (1, "read");
    return buf;
}

#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
#endif

static void *
mmap_file (int fd, size_t sz)
{
    void *ret;

    ret = mmap (0, sz, PROT_READ, MAP_SHARED, fd, 0);
    if (ret == MAP_FAILED)
	err (1, "mmap");
    return ret;
}

int
main (int argc, char **argv)
{
    const char *file = "foo";
    const size_t sz  = 16384;

    char *malloc_buf;
    void *mmap_buf;
    int fd;

    srand (time(NULL));

    generate_random_file (file, sz);

    fd = open (file, O_RDONLY, 0);
    if (fd < 0)
	err (1, "open %s", file);

    malloc_buf = read_file (fd, sz);
    mmap_buf   = mmap_file (fd, sz);
    close (fd);
    unlink (file);
    if (memcmp (malloc_buf, mmap_buf, sz) != 0)
	return 1;
    return 0;
}
