#include /* for mmap */ #include /* for exit */ #include /* for fprintf */ #include /* for strerror */ #include /* for fork */ #include /* for errno */ #include /* for wait */ #include /* for wait */ #include "mem.h" #include "fileLock.h" #define NAME_MAX 64 #define PROC_MAX 100 /* this is what the shared memory will look like: */ typedef struct shared { int nprocs; pid_t pids[PROC_MAX]; } shared_t; int parse_args(int argc, char *argv[ ], int *np){ if((argc != 2) || ((*np = atoi (argv[1])) <= 0)){ fprintf(stderr, "Usage: %s \n", argv[0]); return(-1); } if(*np > PROC_MAX){ fprintf (stderr, "Usage: %s (with < %d thanks)!\n", argv[0], PROC_MAX); return(-1); } return(0); } int main(int argc, char *argv[]){ int fd, i, j, nprocs, lval, delay; pid_t child; void *start_addr; char self[NAME_MAX]; size_t size = sizeof(shared_t); shared_t *shared; fileLock_p lock = makeLock(); if(lock == NULL) exit(EXIT_FAILURE); /* OK lets start the ball rolling */ if(parse_args(argc, argv, &nprocs) < 0) exit(EXIT_FAILURE); /* does the file exist (and is the right size)? if not make it! */ if(init_shared_file(&fd, "sharedFile", size) != 0){ exit(EXIT_FAILURE); } /* map it to memory */ start_addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(start_addr == MAP_FAILED){ perror("mmap failed"); exit(EXIT_FAILURE); } /* zero it */ memset(start_addr, 0, size); shared = start_addr; /* lets get ready to FORK! */ for(i = 0; i < nprocs; i++){ child = fork(); if(child < 0){ fprintf(stderr, "%s: fork failed -- %s\n", argv[0], strerror(errno)); exit(EXIT_FAILURE); } if(child > 0) break; } /* make my name */ sprintf(self, "process %d", i); /* sleep for a random time from 1 to 10 seconds */ srand(getpid()); delay = 1 + (int)(10.0 * rand() / (RAND_MAX + 1.0)); sleep(delay); /* lets lock shared memory, and edit it */ lval = getLock(lock, fd); if(lval == -1){ fprintf(stderr, "%s: getLock failed -- %s", argv[0], strerror(errno)); exit(EXIT_FAILURE); } shared->nprocs++; shared->pids[i] = getpid(); /* show it to the world, unlock it and exit */ fprintf(stderr, "\n%s: count = %d (delay = %d) pids:\n", self, shared->nprocs, delay); for(j = 0; j <= nprocs; j++){ fprintf(stderr, "\tshared->pids[%d] = %ld\n", j, (long)shared->pids[j]); } unLock(lock, fd); freeLock(lock); /* wait for my children */ while(1){ pid_t waitreturn; int status; waitreturn = wait(&status); if ((waitreturn == -1) && (errno != EINTR)) break; } exit(EXIT_SUCCESS); }