/* * Name: logd (server) * Author: Manuel Mausz, 0728348 * Description: Server reads log messages from shared memory (written from * client) and prints message to stdout * Created: 25.04.2009 * Exercise: 2e */ #include #include #include #include #include "global.h" /* global variables */ volatile static int shmid = -1; /* shared memory id */ volatile static int semid1 = -1; /* semaphore#1 id */ volatile static int semid2 = -1; /* semaphore#2 id */ volatile static shm_t *shmdata = (shm_t *) -1; /* data pointer to shm */ /* * NAME: sighandler * PURPOSE: * signal handler sets global error flag to 1 * * PARAMETERS: * int signum ... signal number * * RETURN VALUE: * void * * GLOBAL VARS: * error */ static void sighandler(int signum) { #ifdef DEBUG (void) printf("signal %d received\n", signum); #endif error = 1; } /* * NAME: usage * PURPOSE: * prints program usage to stderr and terminates with EXIT_FAILURE * * PARAMETERS: * void * * RETURN VALUE: * void * * GLOBAL VARS: * me */ static void usage(void) { (void) fprintf(stderr, "Usage: %s\n", me); (void) bailout(NULL); } /* * NAME: free_resources * PURPOSE: * frees allocated resources * * PARAMETERS: * void * * RETURN VALUE: * void */ void free_resources(void) { #ifdef DEBUG printf("freeing resources...\n"); #endif /* remove semaphore#1 */ if (semid1 != -1) { if (semrm(semid1) == -1) { semid1 = -1; bailout("Unable to remove semaphore#1"); } semid1 = -1; } /* remove semaphore#2 */ if (semid2 != -1) { if (semrm(semid2) == -1) { semid2 = -1; bailout("Unable to remove semaphore#2"); } semid2 = -1; } /* detach from memory segmnet */ if (shmdata != (shm_t *) -1) { if (shmdt((void *)shmdata) == -1) { shmdata = (shm_t *) -1; bailout("Unable to detach from shared memory segment"); } shmdata = (shm_t *) -1; } /* remove shared memory segment */ if (shmid != -1) { if (shmctl(shmid, IPC_RMID, NULL) == -1) { shmid = -1; bailout("Unable to remove shared memory segment"); } shmid = -1; } } /* * NAME: main * PURPOSE: * install signal handler, allocate resources * and read from shared memory segment * mutual exclusion is accomplished using 2 semaphores * * PARAMETERS: * standard parameters of main * * RETURN VALUE: * int ... 0 on success, 1 on error * * GLOBAL VARS: * me, error */ int main(int argc, char *argv[]) { struct sigaction new_action, old_action; /* save me */ me = argv[0]; /* install signal handler */ new_action.sa_handler = sighandler; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; /* to avoid restart of blocking syscalls */ INSTALL_SIGNAL(SIGINT, new_action, old_action) INSTALL_SIGNAL(SIGQUIT, new_action, old_action) INSTALL_SIGNAL(SIGTERM, new_action, old_action) /* check cmdline options */ if (argc > 1) (void) usage(); /* allocate resources */ #ifdef DEBUG (void) printf("allocating resources...\n"); #endif if (!error && (shmid = shmget(SHM_KEY, sizeof(shm_t), SHM_PERMS | IPC_CREAT | IPC_EXCL)) == -1) (void) bailout("Unable to allocate shared memory segment"); if (!error && (shmdata = shmat(shmid, NULL, 0)) == (shm_t *) -1) (void) bailout("Unable to attach to shared memory segment"); if (!error && (semid1 = seminit(SEM_KEY1, SEM_PERMS, 0)) == -1) (void) bailout("Unable to create semaphore#1"); if (!error && (semid2 = seminit(SEM_KEY2, SEM_PERMS, 1)) == -1) (void) bailout("Unable to create semaphore#2"); while(!error) { /* wait for semaphore#1 */ if (P(semid1) == -1 && !error) bailout("Unable to wait for semaphore#1"); /* print message to stdout */ if (!error) printf("%s\n", shmdata->msg); /* signal semaphore#2 */ if (V(semid2) == -1 && !error) bailout("Unable to signal semaphore#2"); } /* free resources */ (void) free_resources(); return (error) ? 1 : 0; } /* vim: set et sw=2 ts=2: */