/* * Name: logc (client) * Author: Manuel Mausz, 0728348 * Description: Client writes log message from commandline to * shared memory segment. * Created: 25.04.2009 * Exercise: 2e */ #include #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 /* detach from memory segment */ 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; } } /* * NAME: main * PURPOSE: * install signal handler, allocate resources * and write to 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 != 2) (void) usage(); /* check message length */ if (strlen(argv[1]) >= MAX_LEN) bailout("Message is too long (maximum: %d)", MAX_LEN); /* allocate resources */ #ifdef DEBUG (void) printf("allocating resources...\n"); #endif if (!error && (shmid = shmget(SHM_KEY, sizeof(shm_t), SHM_PERMS)) == -1) (void) bailout("Unable to get id of 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 = semgrab(SEM_KEY1)) == -1) (void) bailout("Unable to grab semaphore#1"); if (!error && (semid2 = semgrab(SEM_KEY2)) == -1) (void) bailout("Unable to grab semaphore#2"); /* wait for semaphore#2 */ if (P(semid2) == -1) bailout("Unable to wait for semaphore#2"); /* write message to shared memory segment */ if (!error) { #ifdef DEBUG printf("writing message to shared memory segment...\n"); #endif (void) strncpy((char *)shmdata->msg, argv[1], MAX_LEN); shmdata->msg[MAX_LEN - 1] = '\0'; } /* signal semaphore#1 */ if (V(semid1) == -1) bailout("Unable to signal semaphore#1"); /* free resources */ (void) free_resources(); return (error) ? 1 : 0; } /* vim: set et sw=2 ts=2: */