Download | Plain Text | No Line Numbers


  1. /*
  2.  * Name: logd (server)
  3.  * Author: Manuel Mausz, 0728348
  4.  * Description: Server reads log messages from shared memory (written from
  5.  * client) and prints message to stdout
  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 "global.h"
  15.  
  16. /* global variables */
  17. volatile static int shmid = -1; /* shared memory id */
  18. volatile static int semid1 = -1; /* semaphore#1 id */
  19. volatile static int semid2 = -1; /* semaphore#2 id */
  20. volatile static shm_t *shmdata = (shm_t *) -1; /* data pointer to shm */
  21.  
  22. /*
  23.  * NAME: sighandler
  24.  * PURPOSE:
  25.  * signal handler sets global error flag to 1
  26.  *
  27.  * PARAMETERS:
  28.  * int signum ... signal number
  29.  *
  30.  * RETURN VALUE:
  31.  * void
  32.  *
  33.  * GLOBAL VARS:
  34.  * error
  35.  */
  36. static void sighandler(int signum)
  37. {
  38. #ifdef DEBUG
  39. (void) printf("signal %d received\n", signum);
  40. #endif
  41. error = 1;
  42. }
  43.  
  44. /*
  45.  * NAME: usage
  46.  * PURPOSE:
  47.  * prints program usage to stderr and terminates with EXIT_FAILURE
  48.  *
  49.  * PARAMETERS:
  50.  * void
  51.  *
  52.  * RETURN VALUE:
  53.  * void
  54.  *
  55.  * GLOBAL VARS:
  56.  * me
  57.  */
  58. static void usage(void)
  59. {
  60. (void) fprintf(stderr, "Usage: %s\n", me);
  61. (void) bailout(NULL);
  62. }
  63.  
  64. /*
  65.  * NAME: free_resources
  66.  * PURPOSE:
  67.  * frees allocated resources
  68.  *
  69.  * PARAMETERS:
  70.  * void
  71.  *
  72.  * RETURN VALUE:
  73.  * void
  74.  */
  75. void free_resources(void)
  76. {
  77. #ifdef DEBUG
  78. printf("freeing resources...\n");
  79. #endif
  80.  
  81. /* remove semaphore#1 */
  82. if (semid1 != -1)
  83. {
  84. if (semrm(semid1) == -1)
  85. {
  86. semid1 = -1;
  87. bailout("Unable to remove semaphore#1");
  88. }
  89. semid1 = -1;
  90. }
  91.  
  92. /* remove semaphore#2 */
  93. if (semid2 != -1)
  94. {
  95. if (semrm(semid2) == -1)
  96. {
  97. semid2 = -1;
  98. bailout("Unable to remove semaphore#2");
  99. }
  100. semid2 = -1;
  101. }
  102.  
  103. /* detach from memory segmnet */
  104. if (shmdata != (shm_t *) -1)
  105. {
  106. if (shmdt((void *)shmdata) == -1)
  107. {
  108. shmdata = (shm_t *) -1;
  109. bailout("Unable to detach from shared memory segment");
  110. }
  111. shmdata = (shm_t *) -1;
  112. }
  113.  
  114. /* remove shared memory segment */
  115. if (shmid != -1)
  116. {
  117. if (shmctl(shmid, IPC_RMID, NULL) == -1)
  118. {
  119. shmid = -1;
  120. bailout("Unable to remove shared memory segment");
  121. }
  122. shmid = -1;
  123. }
  124. }
  125.  
  126. /*
  127.  * NAME: main
  128.  * PURPOSE:
  129.  * install signal handler, allocate resources
  130.  * and read from shared memory segment
  131.  * mutual exclusion is accomplished using 2 semaphores
  132.  *
  133.  * PARAMETERS:
  134.  * standard parameters of main
  135.  *
  136.  * RETURN VALUE:
  137.  * int ... 0 on success, 1 on error
  138.  *
  139.  * GLOBAL VARS:
  140.  * me, error
  141.  */
  142. int main(int argc, char *argv[])
  143. {
  144. struct sigaction new_action, old_action;
  145.  
  146. /* save me */
  147. me = argv[0];
  148.  
  149. /* install signal handler */
  150. new_action.sa_handler = sighandler;
  151. sigemptyset(&new_action.sa_mask);
  152. new_action.sa_flags = 0; /* to avoid restart of blocking syscalls */
  153. INSTALL_SIGNAL(SIGINT, new_action, old_action)
  154. INSTALL_SIGNAL(SIGQUIT, new_action, old_action)
  155. INSTALL_SIGNAL(SIGTERM, new_action, old_action)
  156.  
  157. /* check cmdline options */
  158. if (argc > 1)
  159. (void) usage();
  160.  
  161. /* allocate resources */
  162. #ifdef DEBUG
  163. (void) printf("allocating resources...\n");
  164. #endif
  165. if (!error && (shmid = shmget(SHM_KEY, sizeof(shm_t), SHM_PERMS | IPC_CREAT | IPC_EXCL)) == -1)
  166. (void) bailout("Unable to allocate shared memory segment");
  167. if (!error && (shmdata = shmat(shmid, NULL, 0)) == (shm_t *) -1)
  168. (void) bailout("Unable to attach to shared memory segment");
  169. if (!error && (semid1 = seminit(SEM_KEY1, SEM_PERMS, 0)) == -1)
  170. (void) bailout("Unable to create semaphore#1");
  171. if (!error && (semid2 = seminit(SEM_KEY2, SEM_PERMS, 1)) == -1)
  172. (void) bailout("Unable to create semaphore#2");
  173.  
  174. while(!error)
  175. {
  176. /* wait for semaphore#1 */
  177. if (P(semid1) == -1 && !error)
  178. bailout("Unable to wait for semaphore#1");
  179.  
  180. /* print message to stdout */
  181. if (!error)
  182. printf("%s\n", shmdata->msg);
  183.  
  184. /* signal semaphore#2 */
  185. if (V(semid2) == -1 && !error)
  186. bailout("Unable to signal semaphore#2");
  187. }
  188.  
  189. /* free resources */
  190. (void) free_resources();
  191.  
  192. return (error) ? 1 : 0;
  193. }
  194.  
  195. /* vim: set et sw=2 ts=2: */
  196.