/* file: memshare.c purpose: Demonstrate the use of mmap(). */ #define _POSIX_C_SOURCE 199506L #define __EXTENSIONS__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include pid_t mainpid; /* process id of the main program */ #define CHECK(CALL)\ if (((int)(CALL)) == -1) {\ perror (#CALL);\ kill (-mainpid, SIGKILL);\ exit (-1);\ } #define QUIT(MSG) {\ fprintf (stderr, "fatal error: %s\n", MSG);\ kill (-mainpid, SIGKILL);\ exit (-1);\ } int xprintf (FILE *stream, const char * format, ...) { /* behaves like fprintf except that the output is atomic with respect to other calls to xprintf */ va_list arg; int done; va_start(arg, format); done = vfprintf(stream, format, arg); va_end(arg); return done; } const char sharefilename[] = "/tmp/my_share"; /* name of file to be mapped */ int sharefd; /* file desc for mapped file */ #define MYSIZE 4096 typedef struct { char data[MYSIZE]; } sharedregion_t; sharedregion_t *shared; /* pointer to mapped memory */ int main() { int status; pid_t child; int result; sharedregion_t init; mainpid = getpid(); /* create a file to represent the shared memory region */ CHECK(sharefd = open (sharefilename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)); /* initialize the file contents */ memset (init.data, 0, sizeof (init.data)); result = write(sharefd, &init, sizeof(init)); if (result != sizeof(init)) QUIT ("write"); /* map the file into the address space of this process */ shared = (sharedregion_t *) mmap(0, /* suggested address */ sizeof (sharedregion_t), /* size of region to be mapped */ PROT_READ | PROT_WRITE, /* allow read and write access */ MAP_SHARED, /* share changes */ sharefd, /* file descriptor */ 0 /* offset in file */); if ((shared == MAP_FAILED)) QUIT ("mmmap"); printf ("mapped memory address = %09lx\n", (long) shared); /* create a child process to share this region */ child = fork(); if (child) { /* executed by the parent */ CHECK(waitpid (child, &status, 0)); strcat (shared->data, "parent."); write (1, shared->data, strlen (shared->data)); CHECK(munmap(shared, sizeof(sharedregion_t))); CHECK(close (sharefd)); CHECK(unlink (sharefilename)); } else { /* executed by the child */ strcat (shared->data, "child."); write (1, shared->data, strlen (shared->data)); } return 0; }