Download | Plain Text | No Line Numbers


  1. /*
  2.  * Name: logc (client)
  3.  * Author: Manuel Mausz, 0728348
  4.  * Description: Client writes log message from commandline to
  5.  * shared memory segment.
  6.  * Created: 25.04.2009
  7.  * Exercise: 2e
  8.  */
  9.  
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #include <string.h>
  15. #include "global.h"
  16.  
  17. /* global variables */
  18. volatile static int shmid = -1; /* shared memory id */
  19. volatile static int semid1 = -1; /* semaphore#1 id */
  20. volatile static int semid2 = -1; /* semaphore#2 id */
  21. volatile static shm_t *shmdata = (shm_t *) -1; /* data pointer to shm */
  22.  
  23. /*
  24.  * NAME: sighandler
  25.  * PURPOSE:
  26.  * signal handler sets global error flag to 1
  27.  *
  28.  * PARAMETERS:
  29.  * int signum ... signal number
  30.  *
  31.  * RETURN VALUE:
  32.  * void
  33.  *
  34.  * GLOBAL VARS:
  35.  * error
  36.  */
  37. static void sighandler(int signum)
  38. {
  39. #ifdef DEBUG
  40. (void) printf("signal %d received\n", signum);
  41. #endif
  42. error = 1;
  43. }
  44.  
  45. /*
  46.  * NAME: usage
  47.  * PURPOSE:
  48.  * prints program usage to stderr and terminates with EXIT_FAILURE
  49.  *
  50.  * PARAMETERS:
  51.  * void
  52.  *
  53.  * RETURN VALUE:
  54.  * void
  55.  *
  56.  * GLOBAL VARS:
  57.  * me
  58.  */
  59. static void usage(void)
  60. {
  61. (void) fprintf(stderr, "Usage: %s <message>\n", me);
  62. (void) bailout(NULL);
  63. }
  64.  
  65. /*
  66.  * NAME: free_resources
  67.  * PURPOSE:
  68.  * frees allocated resources
  69.  *
  70.  * PARAMETERS:
  71.  * void
  72.  *
  73.  * RETURN VALUE:
  74.  * void
  75.  */
  76. void free_resources(void)
  77. {
  78. #ifdef DEBUG
  79. printf("freeing resources...\n");
  80. #endif
  81. /* detach from memory segment */
  82. if (shmdata != (shm_t *) -1)
  83. {
  84. if (shmdt((void *)shmdata) == -1)
  85. {
  86. shmdata = (shm_t *) -1;
  87. bailout("Unable to detach from shared memory segment");
  88. }
  89. shmdata = (shm_t *) -1;
  90. }
  91. }
  92.  
  93. /*
  94.  * NAME: main
  95.  * PURPOSE:
  96.  * install signal handler, allocate resources
  97.  * and write to shared memory segment
  98.  * mutual exclusion is accomplished using 2 semaphores
  99.  *
  100.  * PARAMETERS:
  101.  * standard parameters of main
  102.  *
  103.  * RETURN VALUE:
  104.  * int ... 0 on success, 1 on error
  105.  *
  106.  * GLOBAL VARS:
  107.  * me, error
  108.  */
  109. int main(int argc, char *argv[])
  110. {
  111. struct sigaction new_action, old_action;
  112.  
  113. /* save me */
  114. me = argv[0];
  115.  
  116. /* install signal handler */
  117. new_action.sa_handler = sighandler;
  118. sigemptyset(&new_action.sa_mask);
  119. new_action.sa_flags = 0; /* to avoid restart of blocking syscalls */
  120. INSTALL_SIGNAL(SIGINT, new_action, old_action)
  121. INSTALL_SIGNAL(SIGQUIT, new_action, old_action)
  122. INSTALL_SIGNAL(SIGTERM, new_action, old_action)
  123.  
  124. /* check cmdline options */
  125. if (argc != 2)
  126. (void) usage();
  127.  
  128. /* check message length */
  129. if (strlen(argv[1]) >= MAX_LEN)
  130. bailout("Message is too long (maximum: %d)", MAX_LEN);
  131.  
  132. /* allocate resources */
  133. #ifdef DEBUG
  134. (void) printf("allocating resources...\n");
  135. #endif
  136. if (!error && (shmid = shmget(SHM_KEY, sizeof(shm_t), SHM_PERMS)) == -1)
  137. (void) bailout("Unable to get id of shared memory segment");
  138. if (!error && (shmdata = shmat(shmid, NULL, 0)) == (shm_t *) -1)
  139. (void) bailout("Unable to attach to shared memory segment");
  140. if (!error && (semid1 = semgrab(SEM_KEY1)) == -1)
  141. (void) bailout("Unable to grab semaphore#1");
  142. if (!error && (semid2 = semgrab(SEM_KEY2)) == -1)
  143. (void) bailout("Unable to grab semaphore#2");
  144.  
  145. /* wait for semaphore#2 */
  146. if (P(semid2) == -1)
  147. bailout("Unable to wait for semaphore#2");
  148.  
  149. /* write message to shared memory segment */
  150. if (!error)
  151. {
  152. #ifdef DEBUG
  153. printf("writing message to shared memory segment...\n");
  154. #endif
  155. (void) strncpy((char *)shmdata->msg, argv[1], MAX_LEN);
  156. shmdata->msg[MAX_LEN - 1] = '\0';
  157. }
  158.  
  159. /* signal semaphore#1 */
  160. if (V(semid1) == -1)
  161. bailout("Unable to signal semaphore#1");
  162.  
  163. /* free resources */
  164. (void) free_resources();
  165.  
  166. return (error) ? 1 : 0;
  167. }
  168.  
  169. /* vim: set et sw=2 ts=2: */
  170.