/*
 * mm_test.c
 *
 * testing program for mmap() emulation
 */

/*---| includes |---*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "portable.h"
#include "mman.h"            /* replacement for "#include <sys/mman.h>" */

/*---| procedures |---*/
int main( void )
{
        char    *pszFileName    = "test.txt";
        char     szTest[40]     = "0123456789ABCDEFGHIJ";
        int      hFile          = 0;
        int      cb;

        caddr_t  pAddr1         = NULL;
        caddr_t  pAddr2         = NULL;
        caddr_t  pAddr3         = NULL;

        /*
        ** create dummy file
        */
        if( 0 > (hFile = open(pszFileName, O_WRONLY | O_CREAT, 0644)) )
        {
                fprintf( stderr, "can't create %s\n", pszFileName );
                return 1;
        }
        if( 0 > write(hFile, szTest, strlen(szTest)) )
        {
                close( hFile );
                fprintf( stderr, "failed to write to %s\n", pszFileName);
                return 1;
        }
        close( hFile );

        /*
        ** re-open test file
        */
        if( 0 > (hFile = open(pszFileName, O_RDWR)) )
        {
                fprintf( stderr, "can't open %s\n", pszFileName );
                return 1;
        }
        printf( "do some mapping\n" );

        /*
        ** mapping #1
        */
        if( (caddr_t) -1 == (pAddr1=mmap( NULL, 5, PROT_READ | PROT_WRITE,
                                          MAP_SHARED, hFile, 0 )) )
        {
                close( hFile );
                fprintf( stderr, "failed to map #1\n" );
                return 1;
        }
        printf( "  map #1: '" );
        for( cb = 0; cb < 5; cb++ )
                putchar( ((char *) pAddr1)[cb] );
        printf( "'\n" );

        /*
        ** mapping #2
        */
        if( (caddr_t) -1 == (pAddr2=mmap( NULL, 10, PROT_READ | PROT_WRITE,
                                          MAP_SHARED, hFile, 0 ) ) )
        {
                close( hFile );
                munmap( pAddr1, 5 );
                fprintf( stderr, "failed to map #2\n" );
                return 1;
        }
        printf( "  map #2: '" );
        for( cb = 0; cb < 10; cb++ )
                putchar( ((char *) pAddr2)[cb] );
        printf( "'\n" );

        /*
        ** map #3
        */
        if( (caddr_t) -1 == (pAddr3=mmap( NULL, 20, PROT_READ | PROT_WRITE,
                                          MAP_SHARED, hFile, 0 ) ) )
        {
                close( hFile );
                munmap( pAddr1,  5 );
                munmap( pAddr2, 10 );
                fprintf( stderr, "failed to map #2\n" );
                return 1;
        }
        printf( "  map #3: '" );
        for( cb = 0; cb < 20; cb++ )
                putchar( ((char *) pAddr3)[cb] );
        printf( "'\n" );

        /*
        ** do some changes (1)
        */
        memset( pAddr1, 'x', 5 );
        printf( "### change 1 ###\n  mmap #1: '" );
        for( cb = 0; cb <  5; cb++ )
                putchar( ((char *) pAddr1)[cb] );
        printf( "'\n  mmap #2: '" );
        for( cb = 0; cb < 10; cb++ )
                putchar( ((char *) pAddr2)[cb] );
        printf( "'\n  mmap #3: '" );
        for( cb = 0; cb < 20; cb++ )
                putchar( ((char *) pAddr3)[cb] );
        printf( "'\n" );

        /*
        ** do some changes (2)
        */
        memset( pAddr3 + 2, 'Y', 2 );
        printf( "### change 2 ###\n  mmap #1: '" );
        for( cb = 0; cb <  5; cb++ )
                putchar( ((char *) pAddr1)[cb] );
        printf( "'\n  mmap #2: '" );
        for( cb = 0; cb < 10; cb++ )
                putchar( ((char *) pAddr2)[cb] );
        printf( "'\n  mmap #3: '" );
        for( cb = 0; cb < 20; cb++ )
                putchar( ((char *) pAddr3)[cb] );
        printf( "'\n" );

        /*
        ** close mappings and file
        */
        munmap( pAddr1,  5 );
        munmap( pAddr2, 10 );
        munmap( pAddr3, 20 );
        close( hFile );

        /*
        ** read dummy file
        */
        if( 0 > (hFile = open(pszFileName, O_RDONLY)) )
        {
                fprintf( stderr, "can't open %s\n", pszFileName );
                return 1;
        }
        memset( szTest, '\0', sizeof(szTest) );
        if( 0 > read(hFile, szTest, sizeof(szTest) - 1) )
        {
                close( hFile );
                fprintf( stderr, "failed to read from %s\n", pszFileName);
                return 1;
        }
        close( hFile );
        printf( "new file contents: '%s'\n", szTest );

        /*
        ** remove file
        */
        if( 0 > unlink(pszFileName) )
        {
                fprintf( stderr, "can't remove %s\n", pszFileName );
                return 1;
        }

        /*
        ** done
        */
        printf( "done\n" );
        return 0;

} /* main() */

/*===| end of file |===*/
