#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define READ 0
#define WRITE 1
#define P -1
#define V 1
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int init_sem(int semid, int s[], int n)
{
int i, ret;
union semun myun;
for(i = 0; i < n; i++){
myun.val = s[i];
ret = semctl(semid, i, SETVAL, myun);
if(ret < 0){
perror("semctl");
return -1;
}
}
return 0;
}
int sem_pv(int semid, int num, int op)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = op;
buf.sem_flg = 0;
int ret = semop(semid, &buf, 1);
if(ret < 0){..
perror("semop");
return -1;
}
return 0;
}
void sig_handler(int sig)
{
if(sig == SIGCHLD){
waitpid(-1, NULL, WNOHANG);
exit(0);
}
}
int main()
{
int s[] = {0, 1};
key_t key = ftok(".", 'a');
if(key < 0){
perror("ftok");
return -1;
}
/*1. create share memory*/
int shmid = shmget(key, 512, IPC_CREAT | 0666);
if(shmid < 0){
perror("shmget");
return -1;
}
/*2. shm mmap*/
char *shmaddr = shmat(shmid, NULL, 0);
if(shmaddr == (void *)-1){
perror("shmat");
goto _error1;
}
/*3. create sem*/
int semid = semget(key, 2, IPC_CREAT | 0666);
if(semid < 0){
perror("semget");
goto _error1;
}
/*4. init sem*/
int ret = init_sem(semid, s, 2);
if(ret < 0)
goto _error2;
pid_t pid = fork();
if(pid < 0){
perror("fork");
goto _error2;
}else if(pid == 0){
//child -- function : delete space
char *p, *q;
while(1){
//P - read
sem_pv(semid, READ, P);
p = q = shmaddr;
while(*p != '\0'){
if(*p != ' ')
*q++ = *p;
p++;
}
*q = '\0';
printf("result : %s", shmaddr);
if(strncasecmp(shmaddr, "quit\n", 5) == 0)
goto _error2;
//V - write
sem_pv(semid, WRITE, V);
}
}else{
//parent -- function: fgets strings
signal(SIGCHLD, sig_handler);
while(1){
//P - write
sem_pv(semid, WRITE, P);
fgets(shmaddr, 256, stdin);
//V - read
sem_pv(semid, READ, V);
}
}
_error2:
semctl(semid, 0, IPC_RMID);
_error1:
shmctl(shmid, IPC_RMID, NULL);
}