Download | Plain Text | Line Numbers
/*
* 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 <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#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 <message>\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: */