/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : shmtest.cc                                                    */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>

char memfile[] = "hello, world";
const char msg[] = "hello, world - how are you doing???\n";

int map(const char *name, size_t size, int access);


int main(int argc, char **argv)
{
  if (argc != 3) {
    fprintf(stderr, "usage: %s memname r|rw\n", argv[0]);
    return -1;
  }

  char *memName = argv[1];
  int access;

  if (!strcmp(argv[2], "r"))
    access = O_RDONLY;
  else if (!strcmp(argv[2], "rw"))
    access = O_RDWR;
  else {
    fprintf(stderr, "access must be \"r\" or \"rw\"\n");
    return EXIT_FAILURE;
  }


  map(memName, 27, access);

  return 0;
}


int map(const char *name, size_t size, int access)
{
  int fd;

  int shmFlags = O_CREAT | access;
  fprintf(stderr, "map() - access=%d\n", access);
  fprintf(stderr, "shm_open(): %s, flags=%d\n", name, shmFlags);

  if ((fd = shm_open(name, shmFlags, 0777)) == -1) {
    perror("shm_open() failed");
    return EXIT_FAILURE;
  }

  fprintf(stderr, "ltrunc(): fd=%d, size=%d\n", fd, size);
  if (ltrunc(fd, size, SEEK_SET) == -1) {

    /* If errno is EBUSY, it means someone else has already set the
       size, and that's fine. Otherwise, there's a serious problem. */
    if (errno != EBUSY) {
      perror("ltrunc() failed");
      return EXIT_FAILURE;
    }
    else {
      perror("ltrunc()");
    }
  }

  int mmapProtect;
  if (access & O_RDWR)
    mmapProtect = PROT_READ | PROT_WRITE;
  else
    mmapProtect = PROT_READ;

  fprintf(stderr, "mmap(): size=%d, mmapProtect=%d, fd=%d\n",
	  size, mmapProtect, fd);

  char *p;
  if ((p = (char *)mmap(0, size, mmapProtect, MAP_SHARED, fd, 0)) 
      == (char *)-1) {

    perror("mmap() failed");
    //    return EXIT_FAILURE;
  }
  else {
    fprintf(stderr, "Successfully mmap'ed \"%s\", size=%d\n",
	    name, size);

    // Infinite loop for now!
    while (1) {
      sleep(1);
    }

    munmap(p, strlen(msg)+1);
  }
  
  close(fd);

  fprintf(stderr, "shm_unlink()\n");
  if (shm_unlink(name) == -1) {
    perror("shm_unlink() failed");
    return EXIT_FAILURE;
  }

  return 0;
}


