Advertisement
rnort

SPO-3

Nov 22nd, 2012
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.50 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/sem.h>
  5. #include <sys/ipc.h>
  6. #include <sys/types.h>
  7. #include <sys/shm.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <iostream>
  11.  
  12. #define SHMSZ 11
  13.  
  14. #define SHMGET_ERROR 10
  15. #define SHMAT_ERROR 11
  16. #define SHMDT_ERROR 12
  17. #define SEMOP_ERROR 20
  18. #define SEMGET_ERROR 21
  19. #define SEMCTL_ERROR 22
  20. #define READ_ERROR 30
  21. #define WRITE_ERROR 31
  22.  
  23. int allocateMemory( char** );
  24. int semaphoreWait(int, int);
  25. int semaphoreSignal(int, int);
  26. int semaphoreCreate(int*);
  27. int isQuit(std::string);
  28. void sendMessage(char*, char*);
  29. int readMessage(char*, int*, char*);
  30. void receiveMessage(char*, char*);
  31. int detachMemory(void*);
  32. int writeMessage(std::string&);
  33. int isReceivedFully(char*);
  34. int receiver(int, char*);
  35. int sender(int, char*);
  36. int receiveParts(int, char*, std::string&);
  37. int sendParts(int, char*, std::string&);
  38.  
  39.  
  40. int main(int argc, char *argv[])
  41. {
  42.     int semid;
  43.     if ( semaphoreCreate(&semid) != 0 )
  44.     {
  45.         return(EXIT_FAILURE);
  46.     }
  47.     printf("Semaphore created with id %d\n", semid);
  48.     char *shm;
  49.     if ( allocateMemory(&shm) != 0 )
  50.     {
  51.         return(EXIT_FAILURE);
  52.     }
  53.     printf("Memory allocated by address %d\n", (int)*shm);
  54.     int childpid = fork();
  55.     if( childpid == 0)
  56.     {
  57.         receiver(semid, shm);      
  58.     }
  59.     if(childpid > 0)
  60.     {
  61.         sender(semid, shm);
  62.     }
  63.     if ( detachMemory((void*)shm) != 0)
  64.     {
  65.         return(EXIT_FAILURE);
  66.     }
  67.     return 0;
  68. }
  69.  
  70. int receiver(int semid, char* shm)
  71. {
  72.     std::string fullMessage;
  73.     while( 1 )
  74.     {
  75.         if ( semaphoreWait(semid, 1) != 0)
  76.         {
  77.             detachMemory( (void*)shm );
  78.             return(EXIT_FAILURE);
  79.         }
  80.         if (receiveParts(semid, shm, fullMessage) != 0)
  81.         {
  82.             return(EXIT_FAILURE);
  83.         }
  84.         puts("\nReceived message: ---------------------");
  85.         if ( writeMessage(fullMessage) != 0)
  86.         {
  87.             detachMemory((void*)shm );
  88.             return(EXIT_FAILURE);
  89.         }
  90.         if (isQuit(fullMessage) == 1)
  91.         {
  92.             break;
  93.         }
  94.         fullMessage = "";
  95.         if ( semaphoreSignal(semid, 1) != 0)
  96.         {
  97.             detachMemory( (void*)shm );
  98.             return(EXIT_FAILURE);
  99.         }
  100.     }
  101. }
  102.  
  103. int receiveParts(int semid, char* shm, std::string& fullMessage)
  104. {
  105.     int messageReceivedFully = 0;
  106.     while( messageReceivedFully == 0)
  107.     {
  108.         usleep(100000);
  109.         if ( semaphoreWait(semid, 0) != 0)
  110.         {
  111.             detachMemory( (void*)shm );
  112.             return(EXIT_FAILURE);
  113.         }
  114.         char msg[SHMSZ] = {0};
  115.         receiveMessage(shm, msg);
  116.         fullMessage = fullMessage + msg;
  117.         messageReceivedFully = isReceivedFully(shm);
  118.         if ( semaphoreSignal(semid, 0) != 0)
  119.         {
  120.             detachMemory( (void*)shm );
  121.             return(EXIT_FAILURE);
  122.         }
  123.     }
  124. }
  125.  
  126. int sender(int semid, char* shm)
  127. {
  128.     while(1)
  129.     {
  130.         if ( semaphoreWait(semid, 1) != 0)
  131.         {
  132.             detachMemory( (void*)shm );
  133.             return(EXIT_FAILURE);
  134.         }
  135.         std::string message;
  136.         puts("\nEnter message ----------------------");
  137.         if ( semaphoreSignal(semid, 1) != 0)
  138.         {
  139.             detachMemory( (void*)shm );
  140.             return(EXIT_FAILURE);
  141.         }
  142.         sendParts(semid, shm, message);
  143.         if (isQuit(message) == 1)
  144.         {
  145.             break;
  146.         }
  147.         message = "";
  148.     }
  149.     return 0;
  150. }
  151.  
  152. int sendParts(int semid, char* shm, std::string& message)
  153. {
  154.     int messageSentFully = 0;
  155.     while( messageSentFully == 0)
  156.     {
  157.         if ( semaphoreWait(semid, 0) != 0)
  158.         {
  159.             detachMemory( (void*)shm );
  160.             return(EXIT_FAILURE);
  161.         }
  162.         char msg[SHMSZ] = {0};
  163.         if ( readMessage(msg, &messageSentFully, shm) != 0 )
  164.         {
  165.             detachMemory( (void*)shm );
  166.             return(EXIT_FAILURE);
  167.         }
  168.         sendMessage(shm, msg);
  169.         message += msg;
  170.         if ( semaphoreSignal(semid, 0) != 0)
  171.         {
  172.             detachMemory( (void*)shm );
  173.             return(EXIT_FAILURE);
  174.         }
  175.     }
  176. }
  177.  
  178. int allocateMemory( char** shm )
  179. {
  180.     int shmid;          // shared memory segment ID
  181.     key_t key = 5513;   // key for shared memory
  182.     if ((shmid = shmget(key, SHMSZ, 0666)) < 0)
  183.     {
  184.         printf("shmget() failed with error %s\n", strerror(errno));
  185.         return(SHMGET_ERROR);
  186.     }
  187.     *shm = (char*)shmat(shmid, NULL, 0);
  188.     if ( (int)(**shm) ==  -1)
  189.     {
  190.         printf("shmat() failed with error %s\n", strerror(errno));
  191.         return(SHMAT_ERROR);
  192.     }
  193.     return 0;
  194. }
  195.  
  196. int semaphoreWait( int semid, int sem_num )
  197. {
  198.     struct sembuf wait;
  199.     wait.sem_num = sem_num;
  200.     wait.sem_op = -1;
  201.     wait.sem_flg = SEM_UNDO;
  202.     if ( semop(semid, &wait, 1) != 0 )
  203.     {
  204.         printf("semop failed with error %s\n", strerror(errno));
  205.         return SEMOP_ERROR;
  206.     }
  207.     return 0;
  208. }
  209.  
  210. int semaphoreSignal(int semid, int sem_num )
  211. {
  212.     struct sembuf signal;
  213.     signal.sem_num = sem_num;
  214.     signal.sem_op = 1;
  215.     signal.sem_flg = SEM_UNDO;
  216.     if ( semop(semid, &signal, 1) != 0 )
  217.     {
  218.         printf("semop failed with error %s\n", strerror(errno));
  219.         return SEMOP_ERROR;
  220.     }
  221.     return 0;
  222. }
  223.  
  224. int semaphoreCreate( int* semid )
  225. {
  226.     key_t key = 12345;
  227.     *semid = semget(key, 2, IPC_CREAT);
  228.     if ( *semid == -1)
  229.     {
  230.         printf("Semafore creation with key %d failed: %s", key, strerror(errno));
  231.         return(SEMGET_ERROR);
  232.     }
  233.     unsigned short semval = 1;
  234.     if ( semctl(*semid, 0, SETVAL, semval) == -1)
  235.     {
  236.         printf("Semafore set value failed: %s\n", strerror(errno));
  237.         return(SEMCTL_ERROR);
  238.     }
  239.     if ( semctl(*semid, 1, SETVAL, semval) == -1)
  240.     {
  241.         printf("Semafore set value failed: %s\n", strerror(errno));
  242.         return(SEMCTL_ERROR);
  243.     }
  244.     return 0;
  245. }
  246.  
  247. int semaphoreRemove(int* semid)
  248. {
  249.     if ( semctl(*semid, 0, IPC_RMID) == -1)
  250.     {
  251.         printf("Semaphore removing failed: %s\n", strerror(errno));
  252.         return SEMCTL_ERROR;
  253.     }
  254.     return 0;
  255. }
  256.  
  257. int detachMemory( void* addr )
  258. {
  259.     if ( shmdt(addr) != 0 )
  260.     {
  261.         printf("Memory detaching failed: %s\n", strerror(errno));
  262.         return SHMDT_ERROR;
  263.     }
  264.     return 0;
  265. }
  266.  
  267. int isQuit( std::string str )
  268. {
  269.     if ( str == "quit\n" )
  270.     {
  271.         return 1;
  272.     }
  273.     return 0;
  274. }
  275.  
  276. int readMessage( char* msg, int* messageSentFully, char* shm )
  277. {
  278.     int bytesRead = read( STDIN_FILENO, msg, SHMSZ - 1 );
  279.     if ( bytesRead == -1 )
  280.     {
  281.         printf("Read message error: %s\n", strerror(errno));
  282.         return (READ_ERROR);
  283.     }
  284.     char *s = shm;
  285.     if (bytesRead < SHMSZ - 1)
  286.     {
  287.         *messageSentFully = 1;
  288.         s[SHMSZ-1] = '1';
  289.     }
  290.     else
  291.     {
  292.         *messageSentFully = 0;
  293.         s[SHMSZ-1] = '0';
  294.     }
  295.     return 0;
  296. }
  297.  
  298. void sendMessage( char* shm, char* msg )
  299. {
  300.     char *s = shm;
  301.     for (int i = 0; i < SHMSZ-1; ++i)
  302.     {
  303.         s[i] = msg[i];
  304.     }
  305. }
  306.  
  307. void receiveMessage(char* shm, char* msg)
  308. {
  309.     char* s = shm;
  310.     for (int i = 0; i < SHMSZ-1; ++i)
  311.     {
  312.         msg[i] = s[i];
  313.     }
  314. }
  315.  
  316. int writeMessage(std::string& msg)
  317. {
  318.     for (int i = 0; i < msg.length(); ++i)
  319.     {
  320.         printf("%c",msg[i]);
  321.         fflush(stdout);
  322.         usleep(100000);
  323.     }
  324.     return 0;
  325. }
  326.  
  327. int isReceivedFully( char* s)
  328. {
  329.     if ( s[SHMSZ-1] == '1' )
  330.     {
  331.         return 1;
  332.     }
  333.     return 0;
  334. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement