#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <signal.h>
#include <semaphore.h>
#include <fcntl.h>
#include <pthread.h>
#include <ctype.h>

struct msg {
long type;
char text[100];
};

char *shm;
sem_t *mutex;

void handler(int sig) {
printf("PARENT: Signal received from Child 2\n");
}

void *thread_func(void *arg) {
sem_wait(mutex);
printf("THREAD: Reading from shared memory: %s\n", shm);
sem_post(mutex);
return NULL;
}

int main() {

int fd[2];

pipe(fd);

printf("PARENT: Pipe created\n");

int msgid = msgget(1234, 0666 | IPC_CREAT);

printf("PARENT: Message Queue created\n");

int shmid = shmget(5678, 1024, 0666 | IPC_CREAT);

shm = shmat(shmid, NULL, 0);

printf("PARENT: Shared Memory created\n");

mutex = sem_open("/mutex", O_CREAT, 0666, 1);

printf("PARENT: Semaphore initialized\n");

signal(SIGUSR1, handler);

pid_t c1 = fork();

if(c1 == 0) {

printf("CHILD 1: Created\n");

close(fd[1]);

char buf[100];

read(fd[0], buf, sizeof(buf));

printf("CHILD 1: Read from pipe: %s\n", buf);

for(int i = 0; buf[i]; i++)

buf[i] = toupper(buf[i]);

struct msg m;

m.type = 1;

strcpy(m.text, buf);

msgsnd(msgid, &m, sizeof(m.text), 0);

printf("CHILD 1: Sent message to Message Queue\n");

return 0;

}

pid_t c2 = fork();

if(c2 == 0) {

printf("CHILD 2: Created\n");

struct msg m;

msgrcv(msgid, &m, sizeof(m.text), 1, 0);

printf("CHILD 2: Received from Message Queue: %s\n", m.text);

sem_wait(mutex);

strcpy(shm, m.text);

printf("CHILD 2: Written to Shared Memory\n");

sem_post(mutex);

kill(getppid(), SIGUSR1);

printf("CHILD 2: Signal sent to Parent\n");

return 0;

}

close(fd[0]);

write(fd[1], "operating systems lab", 22);

printf("PARENT: Written to pipe\n");

wait(NULL);

wait(NULL);

printf("PARENT: Both children terminated\n");

pthread_t t1;

pthread_create(&t1, NULL, thread_func, NULL);

pthread_join(t1, NULL);

printf("PARENT: Thread execution completed\n");

shmdt(shm);

shmctl(shmid, IPC_RMID, NULL);

msgctl(msgid, IPC_RMID, NULL);

sem_close(mutex);

sem_unlink("/mutex");

printf("PARENT: Resources cleaned up\n");

return 0;

}