Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/sem.h>
- #include <sys/ipc.h>
- #include <sys/types.h>
- #include <sys/shm.h>
- #include <string.h>
- #include <errno.h>
- #include <iostream>
- #define SHMSZ 11
- #define SHMGET_ERROR 10
- #define SHMAT_ERROR 11
- #define SHMDT_ERROR 12
- #define SEMOP_ERROR 20
- #define SEMGET_ERROR 21
- #define SEMCTL_ERROR 22
- #define READ_ERROR 30
- #define WRITE_ERROR 31
- int allocateMemory( char** );
- int semaphoreWait(int, int);
- int semaphoreSignal(int, int);
- int semaphoreCreate(int*);
- int isQuit(std::string);
- void sendMessage(char*, char*);
- int readMessage(char*, int*, char*);
- void receiveMessage(char*, char*);
- int detachMemory(void*);
- int writeMessage(std::string&);
- int isReceivedFully(char*);
- int receiver(int, char*);
- int sender(int, char*);
- int receiveParts(int, char*, std::string&);
- int sendParts(int, char*, std::string&);
- int main(int argc, char *argv[])
- {
- int semid;
- if ( semaphoreCreate(&semid) != 0 )
- {
- return(EXIT_FAILURE);
- }
- printf("Semaphore created with id %d\n", semid);
- char *shm;
- if ( allocateMemory(&shm) != 0 )
- {
- return(EXIT_FAILURE);
- }
- printf("Memory allocated by address %d\n", (int)*shm);
- int childpid = fork();
- if( childpid == 0)
- {
- receiver(semid, shm);
- }
- if(childpid > 0)
- {
- sender(semid, shm);
- }
- if ( detachMemory((void*)shm) != 0)
- {
- return(EXIT_FAILURE);
- }
- return 0;
- }
- int receiver(int semid, char* shm)
- {
- std::string fullMessage;
- while( 1 )
- {
- if ( semaphoreWait(semid, 1) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- if (receiveParts(semid, shm, fullMessage) != 0)
- {
- return(EXIT_FAILURE);
- }
- puts("\nReceived message: ---------------------");
- if ( writeMessage(fullMessage) != 0)
- {
- detachMemory((void*)shm );
- return(EXIT_FAILURE);
- }
- if (isQuit(fullMessage) == 1)
- {
- break;
- }
- fullMessage = "";
- if ( semaphoreSignal(semid, 1) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- }
- }
- int receiveParts(int semid, char* shm, std::string& fullMessage)
- {
- int messageReceivedFully = 0;
- while( messageReceivedFully == 0)
- {
- usleep(100000);
- if ( semaphoreWait(semid, 0) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- char msg[SHMSZ] = {0};
- receiveMessage(shm, msg);
- fullMessage = fullMessage + msg;
- messageReceivedFully = isReceivedFully(shm);
- if ( semaphoreSignal(semid, 0) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- }
- }
- int sender(int semid, char* shm)
- {
- while(1)
- {
- if ( semaphoreWait(semid, 1) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- std::string message;
- puts("\nEnter message ----------------------");
- if ( semaphoreSignal(semid, 1) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- sendParts(semid, shm, message);
- if (isQuit(message) == 1)
- {
- break;
- }
- message = "";
- }
- return 0;
- }
- int sendParts(int semid, char* shm, std::string& message)
- {
- int messageSentFully = 0;
- while( messageSentFully == 0)
- {
- if ( semaphoreWait(semid, 0) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- char msg[SHMSZ] = {0};
- if ( readMessage(msg, &messageSentFully, shm) != 0 )
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- sendMessage(shm, msg);
- message += msg;
- if ( semaphoreSignal(semid, 0) != 0)
- {
- detachMemory( (void*)shm );
- return(EXIT_FAILURE);
- }
- }
- }
- int allocateMemory( char** shm )
- {
- int shmid; // shared memory segment ID
- key_t key = 5513; // key for shared memory
- if ((shmid = shmget(key, SHMSZ, 0666)) < 0)
- {
- printf("shmget() failed with error %s\n", strerror(errno));
- return(SHMGET_ERROR);
- }
- *shm = (char*)shmat(shmid, NULL, 0);
- if ( (int)(**shm) == -1)
- {
- printf("shmat() failed with error %s\n", strerror(errno));
- return(SHMAT_ERROR);
- }
- return 0;
- }
- int semaphoreWait( int semid, int sem_num )
- {
- struct sembuf wait;
- wait.sem_num = sem_num;
- wait.sem_op = -1;
- wait.sem_flg = SEM_UNDO;
- if ( semop(semid, &wait, 1) != 0 )
- {
- printf("semop failed with error %s\n", strerror(errno));
- return SEMOP_ERROR;
- }
- return 0;
- }
- int semaphoreSignal(int semid, int sem_num )
- {
- struct sembuf signal;
- signal.sem_num = sem_num;
- signal.sem_op = 1;
- signal.sem_flg = SEM_UNDO;
- if ( semop(semid, &signal, 1) != 0 )
- {
- printf("semop failed with error %s\n", strerror(errno));
- return SEMOP_ERROR;
- }
- return 0;
- }
- int semaphoreCreate( int* semid )
- {
- key_t key = 12345;
- *semid = semget(key, 2, IPC_CREAT);
- if ( *semid == -1)
- {
- printf("Semafore creation with key %d failed: %s", key, strerror(errno));
- return(SEMGET_ERROR);
- }
- unsigned short semval = 1;
- if ( semctl(*semid, 0, SETVAL, semval) == -1)
- {
- printf("Semafore set value failed: %s\n", strerror(errno));
- return(SEMCTL_ERROR);
- }
- if ( semctl(*semid, 1, SETVAL, semval) == -1)
- {
- printf("Semafore set value failed: %s\n", strerror(errno));
- return(SEMCTL_ERROR);
- }
- return 0;
- }
- int semaphoreRemove(int* semid)
- {
- if ( semctl(*semid, 0, IPC_RMID) == -1)
- {
- printf("Semaphore removing failed: %s\n", strerror(errno));
- return SEMCTL_ERROR;
- }
- return 0;
- }
- int detachMemory( void* addr )
- {
- if ( shmdt(addr) != 0 )
- {
- printf("Memory detaching failed: %s\n", strerror(errno));
- return SHMDT_ERROR;
- }
- return 0;
- }
- int isQuit( std::string str )
- {
- if ( str == "quit\n" )
- {
- return 1;
- }
- return 0;
- }
- int readMessage( char* msg, int* messageSentFully, char* shm )
- {
- int bytesRead = read( STDIN_FILENO, msg, SHMSZ - 1 );
- if ( bytesRead == -1 )
- {
- printf("Read message error: %s\n", strerror(errno));
- return (READ_ERROR);
- }
- char *s = shm;
- if (bytesRead < SHMSZ - 1)
- {
- *messageSentFully = 1;
- s[SHMSZ-1] = '1';
- }
- else
- {
- *messageSentFully = 0;
- s[SHMSZ-1] = '0';
- }
- return 0;
- }
- void sendMessage( char* shm, char* msg )
- {
- char *s = shm;
- for (int i = 0; i < SHMSZ-1; ++i)
- {
- s[i] = msg[i];
- }
- }
- void receiveMessage(char* shm, char* msg)
- {
- char* s = shm;
- for (int i = 0; i < SHMSZ-1; ++i)
- {
- msg[i] = s[i];
- }
- }
- int writeMessage(std::string& msg)
- {
- for (int i = 0; i < msg.length(); ++i)
- {
- printf("%c",msg[i]);
- fflush(stdout);
- usleep(100000);
- }
- return 0;
- }
- int isReceivedFully( char* s)
- {
- if ( s[SHMSZ-1] == '1' )
- {
- return 1;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement