From 0e52435d9b0d5dbf36b195af07262102e5b95da4 Mon Sep 17 00:00:00 2001 From: ItsMAX0112 Date: Sat, 2 Nov 2024 16:54:07 +0530 Subject: [PATCH] working on shared mem --- lab4/.gitignore | 5 + lab4/images/1_out.ppm | 0 lab4/src/shared.cpp | 211 ++++++++++----------- lab4/src/sharedMemory/important.cpp | 283 ++++++++++++++++++++++++++++ lab4/src/sharedMemory/important.h | 19 ++ lab4/src/sharedMemory/shared.cpp | 254 +++++++++++++++++++++++++ 6 files changed, 664 insertions(+), 108 deletions(-) create mode 100644 lab4/.gitignore create mode 100644 lab4/images/1_out.ppm create mode 100644 lab4/src/sharedMemory/important.cpp create mode 100644 lab4/src/sharedMemory/important.h create mode 100644 lab4/src/sharedMemory/shared.cpp diff --git a/lab4/.gitignore b/lab4/.gitignore new file mode 100644 index 0000000..bf40b23 --- /dev/null +++ b/lab4/.gitignore @@ -0,0 +1,5 @@ +/tijsrc + +/sidWala + +/subhashWala \ No newline at end of file diff --git a/lab4/images/1_out.ppm b/lab4/images/1_out.ppm new file mode 100644 index 0000000..e69de29 diff --git a/lab4/src/shared.cpp b/lab4/src/shared.cpp index 14faff6..5cfbb68 100644 --- a/lab4/src/shared.cpp +++ b/lab4/src/shared.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace std; @@ -23,13 +24,45 @@ int main(int argc, char *argv[]) { // exit(0); // } - // struct image_t *input_image = read_ppm_file(argv[1]); - // struct image_t *smoothened_image = S1_smoothen(input_image); - char buf; + + const char *shm1_name = "/shm_parent_child"; + const char *shm2_name = "/shm_child_grandchild"; + const char *sem1_name = "/sem_parent_child"; + const char *sem2_name = "/sem_child_grandchild"; + + int shm_fd = shm_open(shm1_name, O_CREAT | O_RDWR, 0666); + if (shm_fd == -1) { + perror("shm_open"); + return 1; + } + + // Resize the shared memory object to the desired size + if (ftruncate(shm_fd, size) == -1) { + perror("ftruncate"); + return 1; + } + + // Map the shared memory object into the process address space + void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (ptr == MAP_FAILED) { + perror("mmap"); + return 1; + } + + sem_t *sem_parent_child = sem_open(sem1_name, O_CREAT, 0666, 0); // Initially locked (0) + sem_t *sem_child_grandchild = sem_open(sem2_name, O_CREAT, 0666, 0); // Initially locked (0) + + if (sem_parent_child == SEM_FAILED || sem_child_grandchild == SEM_FAILED) { + perror("sem_open failed"); + exit(EXIT_FAILURE); + } + + + // size_t size = input_image->height * input_image->width * 3 * sizeof(uint8_t); + size_t size = 1024; + pid_t CHILD; - - CHILD = fork(); if (CHILD == -1) { perror("fork failed!"); @@ -39,32 +72,20 @@ int main(int argc, char *argv[]) { // Parent Process if(CHILD != 0){ - const char *name = "/parent-child"; - int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); - if (shm_fd == -1) { - perror("shm_open"); - return 1; - } - - // Set the size of the shared memory region - // size_t size = smoothened_image->height * smoothened_image->width * 3; - size_t size = 1024; - - // Resize the shared memory object to the desired size - if (ftruncate(shm_fd, size) == -1) { - perror("ftruncate"); - return 1; - } - - // Map the shared memory object into the process address space - void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - if (ptr == MAP_FAILED) { - perror("mmap"); - return 1; - } + char buffer[1024] = {'p', 'a', 'c', 'k', 'e', 't', '\0'}; + buffer[7] = '\0'; // Write data to the shared memory - sprintf((char *)ptr, "...PACKET..."); + for(int i = 1; i < 5; i++){ + // printf("parent writing to shm\n"); + buffer[6] = '0' + i; + memcpy(ptr, buffer, 1024); // Copy 1024 bytes to shared memory + + // Optional: Print what is being written to shared memory for verification + printf("P - Writing to shared memory: %s\n", (char *)ptr); + sem_post(sem_parent_child); + sem_wait(sem_child_grandchild); + } // Unmap the shared memory object if (munmap(ptr, size) == -1) { @@ -78,21 +99,13 @@ int main(int argc, char *argv[]) { return 1; } - // Unlink the shared memory object - // if (shm_unlink(name) == -1) { - // perror("shm_unlink"); - // return 1; - // } - - - printf("parent writing to shm\n"); + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); wait(NULL); /* Wait for child */ } // Child process else if (CHILD == 0) { /* Child reads from pipe */ - - pid_t GRAND_CHILD = fork(); if (GRAND_CHILD == -1) { @@ -102,28 +115,12 @@ int main(int argc, char *argv[]) { // Child Process if(GRAND_CHILD != 0){ - // close(pipe1[1]); /* Close unused write end for s1_s2 pipe */ - // close(pipe2[0]); /* Close unused read end for s2_s3 pipe */ - // char to_print[] = "C : x\n"; - // while (read(pipe1[0], &buf, 1) > 0) - // { - // printf("child reading from pipe\n"); - // to_print[4] = buf; - // write(STDOUT_FILENO, &to_print, strlen(to_print)); - // } - - printf("Child reading from shm...\n"); - - const char *name = "/parent-child"; - int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); + int shm_fd = shm_open(shm1_name, O_CREAT | O_RDWR, 0666); if (shm_fd == -1) { perror("shm_open"); return 1; } - // Set the size of the shared memory region - size_t size = 1024; - // Resize the shared memory object to the desired size if (ftruncate(shm_fd, size) == -1) { perror("ftruncate"); @@ -137,40 +134,12 @@ int main(int argc, char *argv[]) { return 1; } - sleep(2); - - // Print the contents of the shared memory - char *packet = (char *)ptr; - printf("Shared memory contents: %s\n", packet); - - char buffer[1024]; - strncpy(buffer, packet, 1024); - - // Unmap the shared memory object - if (munmap(ptr, size) == -1) { - perror("munmap"); - return 1; - } - - // Close the shared memory file descriptor - if (close(shm_fd) == -1) { - perror("close"); - return 1; - } - - printf("child writing to shm\n"); - - const char *name2 = "/child-grandchild"; - int shm2_fd = shm_open(name2, O_CREAT | O_RDWR, 0666); + int shm2_fd = shm_open(shm2_name, O_CREAT | O_RDWR, 0666); if (shm2_fd == -1) { perror("shm_open"); return 1; } - // Set the size of the shared memory region - // size_t size = smoothened_image->height * smoothened_image->width * 3; - // size_t size = 1024; - // Resize the shared memory object to the desired size if (ftruncate(shm2_fd, size) == -1) { perror("ftruncate"); @@ -184,8 +153,30 @@ int main(int argc, char *argv[]) { return 1; } - // Write data to the shared memory - sprintf((char *)ptr2, buffer, 1024); + for(int i=0; i<5; i++){ + // printf("Child reading from shm1 and writing to shm2...\n"); + sem_wait(sem_parent_child); + // Print the contents of the shared memory + char *packet = (char *)ptr; + printf("C - Shared memory contents: %s\n", packet); + // char buffer[1024]; + // strncpy(buffer, (char *)ptr, 1024); + memcpy(ptr2, ptr, 1024); + sem_post(sem_child_grandchild); // Signal parent + } + + // Unmap the shared memory object + if (munmap(ptr, size) == -1) { + perror("munmap"); + return 1; + } + + // Close the shared memory file descriptor + if (close(shm_fd) == -1) { + perror("close"); + return 1; + } + // printf("child writing to shm\n"); // Unmap the shared memory object if (munmap(ptr2, size) == -1) { @@ -199,61 +190,65 @@ int main(int argc, char *argv[]) { return 1; } - + shm_unlink(shm1_name); + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); wait(NULL); exit(EXIT_SUCCESS); } - // GrandChild Process else if (GRAND_CHILD == 0) { /* GrandChild reads from pipe */ - - printf("Grandchild reading from shm...\n"); - - const char *name = "/child-grandchild"; - int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); - if (shm_fd == -1) { + int shm2_fd = shm_open(shm2_name, O_CREAT | O_RDWR, 0666); + if (shm2_fd == -1) { perror("shm_open"); return 1; } - // Set the size of the shared memory region - size_t size = 1024; - // Resize the shared memory object to the desired size - if (ftruncate(shm_fd, size) == -1) { + if (ftruncate(shm2_fd, size) == -1) { perror("ftruncate"); return 1; } // Map the shared memory object into the process address space - void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - if (ptr == MAP_FAILED) { + void *ptr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm2_fd, 0); + if (ptr2 == MAP_FAILED) { perror("mmap"); return 1; } - sleep(2); - - // Print the contents of the shared memory - printf("Shared memory contents: %s\n", (char *)ptr); + for(int i=0; i<5; i++){ + sem_wait(sem_child_grandchild); + // Print the contents of the shared memory + // printf("Grandchild reading from shm...\n"); + printf("GC - Shared memory contents: %s\n", (char *)ptr2); + } // Unmap the shared memory object - if (munmap(ptr, size) == -1) { + if (munmap(ptr2, size) == -1) { perror("munmap"); return 1; } // Close the shared memory file descriptor - if (close(shm_fd) == -1) { + if (close(shm2_fd) == -1) { perror("close"); return 1; } - exit(EXIT_SUCCESS); + shm_unlink(shm2_name); + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); + exit(EXIT_SUCCESS); } } + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); + sem_unlink(sem1_name); + sem_unlink(sem2_name); + cout << "success" << endl; return 0; } \ No newline at end of file diff --git a/lab4/src/sharedMemory/important.cpp b/lab4/src/sharedMemory/important.cpp new file mode 100644 index 0000000..9f72711 --- /dev/null +++ b/lab4/src/sharedMemory/important.cpp @@ -0,0 +1,283 @@ +#include +#include "important.h" +#include +#include +#include + +using namespace std; + +struct image_t *S1_smoothen(struct image_t *input_image) +{ + // cout << input_image->width << input_image->height << " " << input_image->image_pixels << endl; + int width = input_image->width; + int height = input_image->height; + + // memory allocation + struct image_t *smoother = new struct image_t; + smoother->height = height; + smoother->width = width; + smoother->image_pixels = new uint8_t **[height]; + for (int i = 0; i < height; i++) + { + smoother->image_pixels[i] = new uint8_t *[width]; + for (int j = 0; j < width; j++) + smoother->image_pixels[i][j] = new uint8_t[3]; + } + + for (int i = 1; i < height - 1; i++) + { + for (int j = 1; j < width - 1; j++) + { + for (int k = 0; k < 3; k++) + { + // image->image_pixels[i][j][k] = val; + // edge cases + if (i == 0 && j == 0) + { // i-1 and j - 1 doesnt exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i][j][k] / 4 + input_image->image_pixels[i][j + 1][k] / 4 + input_image->image_pixels[i + 1][j][k] / 4 + input_image->image_pixels[i + 1][j + 1][k] / 4); + } + else if (i == height - 1 && j == 0) + { // i+1 and j-1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i - 1][j][k] / 4 + input_image->image_pixels[i - 1][j + 1][k] / 4 + input_image->image_pixels[i][j][k] / 4 + input_image->image_pixels[i][j + 1][k] / 4); + } + + else if (i == 0 && j == width - 1) + { // i-1 and j+1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i][j - 1][k] / 4 + input_image->image_pixels[i][j][k] / 4 + input_image->image_pixels[i + 1][j - 1][k] / 4 + input_image->image_pixels[i + 1][j][k] / 4); + } + else if (i == height - 1 && j == width - 1) + { // i+1 and j+1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i - 1][j - 1][k] / 4 + input_image->image_pixels[i - 1][j][k] / 4 + input_image->image_pixels[i][j - 1][k] / 4 + input_image->image_pixels[i][j][k] / 4); + } + else if (i == 0) + { // i - 1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i][j - 1][k] / 6 + input_image->image_pixels[i][j][k] / 6 + input_image->image_pixels[i][j + 1][k] / 6 + input_image->image_pixels[i + 1][j - 1][k] / 6 + input_image->image_pixels[i + 1][j][k] / 6 + input_image->image_pixels[i + 1][j + 1][k] / 6); + } + + else if (j == 0) + { // j -1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i - 1][j][k] / 6 + input_image->image_pixels[i - 1][j + 1][k] / 6 + input_image->image_pixels[i][j][k] / 6 + input_image->image_pixels[i][j + 1][k] / 6 + input_image->image_pixels[i + 1][j][k] / 6 + input_image->image_pixels[i + 1][j + 1][k] / 6); + } + + else if (i == height - 1) + { // i+1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i - 1][j - 1][k] / 6 + input_image->image_pixels[i - 1][j][k] / 6 + input_image->image_pixels[i - 1][j + 1][k] / 6 + input_image->image_pixels[i][j - 1][k] / 6 + input_image->image_pixels[i][j][k] / 6 + input_image->image_pixels[i][j + 1][k] / 6); + } + else if (j == width - 1) + { // j + 1 does not exist + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i - 1][j - 1][k] / 6 + input_image->image_pixels[i - 1][j][k] / 6 + input_image->image_pixels[i][j - 1][k] / 6 + input_image->image_pixels[i][j][k] / 6 + input_image->image_pixels[i + 1][j - 1][k] / 6 + input_image->image_pixels[i + 1][j][k] / 6); + } + else + { + smoother->image_pixels[i][j][k] = (input_image->image_pixels[i - 1][j - 1][k] / 9 + input_image->image_pixels[i - 1][j][k] / 9 + input_image->image_pixels[i - 1][j + 1][k] / 9 + input_image->image_pixels[i][j - 1][k] / 9 + input_image->image_pixels[i][j][k] / 9 + input_image->image_pixels[i][j + 1][k] / 9 + input_image->image_pixels[i + 1][j - 1][k] / 9 + input_image->image_pixels[i + 1][j][k] / 9 + input_image->image_pixels[i + 1][j + 1][k] / 9); + } + } + } + } + + return smoother; +} + +struct image_t *S2_find_details(struct image_t *input_image, struct image_t *smoothened_image) +{ + // TODO + int width = input_image->width; + int height = input_image->height; + + struct image_t *details = new struct image_t; + details->height = height; + details->width = width; + details->image_pixels = new uint8_t **[height]; + + for (int i = 0; i < height; i++) + { + details->image_pixels[i] = new uint8_t *[width]; + for (int j = 0; j < width; j++) + details->image_pixels[i][j] = new uint8_t[3]; + } + + for (int i = 1; i < height - 1; i++) + { + for (int j = 1; j < width - 1; j++) + { + for (int k = 0; k < 3; k++) + { + details->image_pixels[i][j][k] = max(0, input_image->image_pixels[i][j][k] - smoothened_image->image_pixels[i][j][k]); + } + } + } + + return details; +} + +struct image_t *S3_sharpen(struct image_t *input_image, struct image_t *details_image) +{ + // TODO + int width = input_image->width; + int height = input_image->height; + + int a = 1; + + struct image_t *sharp = new struct image_t; + sharp->height = height; + sharp->width = width; + sharp->image_pixels = new uint8_t **[height]; + + for (int i = 0; i < height; i++) + { + sharp->image_pixels[i] = new uint8_t *[width]; + for (int j = 0; j < width; j++) + sharp->image_pixels[i][j] = new uint8_t[3]; + } + + for (int i = 1; i < height - 1; i++) + { + for (int j = 1; j < width - 1; j++) + { + for (int k = 0; k < 3; k++) + { + sharp->image_pixels[i][j][k] = min(255, input_image->image_pixels[i][j][k] + details_image->image_pixels[i][j][k]) * a; + } + } + } + return sharp; // TODO remove this line when adding your code +} + +uint8_t skip_blanks_comments_while_reading(ifstream *read_stream) // returns the byte at the first position after the skipping of the blank space +{ + uint8_t val; + while (true) + { + val = read_stream->get(); + if (val == '#') + { + while (val != '\n') + { + val = read_stream->get(); + } + } + if (val == '\n' || val == ' ' || val == '\t') + { + continue; + } + else if (val != '#') + return val; + } + return val; +} + +struct image_t *read_ppm_file(char *path_to_input_file) +{ + // cout << "input image file = " << path_to_input_file << "\n"; + + ifstream read_stream(path_to_input_file, ios::binary | ios::in); + + if (read_stream.is_open()) + { + struct image_t *image = new struct image_t; + + uint8_t val = skip_blanks_comments_while_reading(&read_stream); // 'P' + val = read_stream.get(); //'6' + + // width + val = skip_blanks_comments_while_reading(&read_stream); + while (true) + { + if (val == ' ' || val == '\t' || val == '\n') + break; + image->width = image->width * 10 + (val - '0'); + val = read_stream.get(); + } + // cout << "width = " << image->width << "\n"; + + // height + val = skip_blanks_comments_while_reading(&read_stream); + while (true) + { + if (val == ' ' || val == '\t' || val == '\n') + break; + image->height = image->height * 10 + (val - '0'); + val = read_stream.get(); + } + // cout << "height = " << image->height << "\n"; + + image->image_pixels = new uint8_t **[image->height]; + for (int i = 0; i < image->height; i++) + { + image->image_pixels[i] = new uint8_t *[image->width]; + for (int j = 0; j < image->width; j++) + image->image_pixels[i][j] = new uint8_t[3]; + } + + // maxval + val = skip_blanks_comments_while_reading(&read_stream); + while (true) + { + if (val == ' ' || val == '\t' || val == '\n') + break; + val = read_stream.get(); + } + + // get pixel values + val = skip_blanks_comments_while_reading(&read_stream); + for (int i = 0; i < image->height; i++) + { + for (int j = 0; j < image->width; j++) + { + for (int k = 0; k < 3; k++) + { + image->image_pixels[i][j][k] = val; + val = read_stream.get(); // assuming maxval of <=255 + } + } + } + // read_stream.seekg(-1, ios_base::cur); + // read_stream.read(((char*)image->image_pixels), image->height * image->width * 3); //assuming maxval of <=255 + + read_stream.close(); + + return image; + } + else + { + cerr << "failed to open file " << path_to_input_file << "\n\n"; + exit(1); + } +} + +void write_ppm_file(char *path_to_output_file, struct image_t *image) +{ + // cout << "output image file = " << path_to_output_file << "\n"; + + ofstream write_stream(path_to_output_file, ios::binary | ios::out); + + if (write_stream.is_open()) + { + write_stream.write("P6\n", 3); + std::string width_string = std::to_string(image->width); + // cout << "width = " << width_string << "\n"; + write_stream.write(width_string.c_str(), width_string.length()); + write_stream.write(" ", 1); + std::string height_string = std::to_string(image->height); + // cout << "height = " << height_string << "\n"; + write_stream.write(height_string.c_str(), height_string.length()); + write_stream.write("\n255\n", 5); + for (int i = 0; i < image->height; i++) + { + for (int j = 0; j < image->width; j++) + { + for (int k = 0; k < 3; k++) + { + write_stream.put(image->image_pixels[i][j][k]); // assuming maxval of <=255 + } + } + } + // write_stream.write(((char*)image->image_pixels), image->height * image->width * 3); + write_stream.close(); + } + else + { + cerr << "failed to open file " << path_to_output_file << "\n\n"; + exit(1); + } +} diff --git a/lab4/src/sharedMemory/important.h b/lab4/src/sharedMemory/important.h new file mode 100644 index 0000000..b536603 --- /dev/null +++ b/lab4/src/sharedMemory/important.h @@ -0,0 +1,19 @@ +#ifndef IMPORTANT_H +#define IMPORTANT_H +#include + +struct image_t +{ + int width; + int height; + uint8_t*** image_pixels; +}; + +struct image_t* S1_smoothen(struct image_t *input_image); +struct image_t* S2_find_details(struct image_t *input_image, struct image_t *smoothened_image); +struct image_t* S3_sharpen(struct image_t *input_image, struct image_t *details_image); + +struct image_t* read_ppm_file(char* path_to_input_file); +void write_ppm_file(char* path_to_output_file, struct image_t* image); + +#endif \ No newline at end of file diff --git a/lab4/src/sharedMemory/shared.cpp b/lab4/src/sharedMemory/shared.cpp new file mode 100644 index 0000000..5cfbb68 --- /dev/null +++ b/lab4/src/sharedMemory/shared.cpp @@ -0,0 +1,254 @@ +#include "important.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +int main(int argc, char *argv[]) { + + // if(argc != 3) + // { + // cout << "usage: ./a.out \n\n"; + // exit(0); + // } + + // struct image_t *input_image = read_ppm_file(argv[1]); + + const char *shm1_name = "/shm_parent_child"; + const char *shm2_name = "/shm_child_grandchild"; + const char *sem1_name = "/sem_parent_child"; + const char *sem2_name = "/sem_child_grandchild"; + + int shm_fd = shm_open(shm1_name, O_CREAT | O_RDWR, 0666); + if (shm_fd == -1) { + perror("shm_open"); + return 1; + } + + // Resize the shared memory object to the desired size + if (ftruncate(shm_fd, size) == -1) { + perror("ftruncate"); + return 1; + } + + // Map the shared memory object into the process address space + void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (ptr == MAP_FAILED) { + perror("mmap"); + return 1; + } + + sem_t *sem_parent_child = sem_open(sem1_name, O_CREAT, 0666, 0); // Initially locked (0) + sem_t *sem_child_grandchild = sem_open(sem2_name, O_CREAT, 0666, 0); // Initially locked (0) + + if (sem_parent_child == SEM_FAILED || sem_child_grandchild == SEM_FAILED) { + perror("sem_open failed"); + exit(EXIT_FAILURE); + } + + + // size_t size = input_image->height * input_image->width * 3 * sizeof(uint8_t); + size_t size = 1024; + + pid_t CHILD; + CHILD = fork(); + if (CHILD == -1) { + perror("fork failed!"); + exit(EXIT_FAILURE); + } + + // Parent Process + if(CHILD != 0){ + + char buffer[1024] = {'p', 'a', 'c', 'k', 'e', 't', '\0'}; + buffer[7] = '\0'; + + // Write data to the shared memory + for(int i = 1; i < 5; i++){ + // printf("parent writing to shm\n"); + buffer[6] = '0' + i; + memcpy(ptr, buffer, 1024); // Copy 1024 bytes to shared memory + + // Optional: Print what is being written to shared memory for verification + printf("P - Writing to shared memory: %s\n", (char *)ptr); + sem_post(sem_parent_child); + sem_wait(sem_child_grandchild); + } + + // Unmap the shared memory object + if (munmap(ptr, size) == -1) { + perror("munmap"); + return 1; + } + + // Close the shared memory file descriptor + if (close(shm_fd) == -1) { + perror("close"); + return 1; + } + + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); + wait(NULL); /* Wait for child */ + } + + // Child process + else if (CHILD == 0) { /* Child reads from pipe */ + pid_t GRAND_CHILD = fork(); + + if (GRAND_CHILD == -1) { + perror("fork failed!"); + exit(EXIT_FAILURE); + } + + // Child Process + if(GRAND_CHILD != 0){ + int shm_fd = shm_open(shm1_name, O_CREAT | O_RDWR, 0666); + if (shm_fd == -1) { + perror("shm_open"); + return 1; + } + + // Resize the shared memory object to the desired size + if (ftruncate(shm_fd, size) == -1) { + perror("ftruncate"); + return 1; + } + + // Map the shared memory object into the process address space + void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (ptr == MAP_FAILED) { + perror("mmap"); + return 1; + } + + int shm2_fd = shm_open(shm2_name, O_CREAT | O_RDWR, 0666); + if (shm2_fd == -1) { + perror("shm_open"); + return 1; + } + + // Resize the shared memory object to the desired size + if (ftruncate(shm2_fd, size) == -1) { + perror("ftruncate"); + return 1; + } + + // Map the shared memory object into the process address space + void *ptr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm2_fd, 0); + if (ptr2 == MAP_FAILED) { + perror("mmap"); + return 1; + } + + for(int i=0; i<5; i++){ + // printf("Child reading from shm1 and writing to shm2...\n"); + sem_wait(sem_parent_child); + // Print the contents of the shared memory + char *packet = (char *)ptr; + printf("C - Shared memory contents: %s\n", packet); + // char buffer[1024]; + // strncpy(buffer, (char *)ptr, 1024); + memcpy(ptr2, ptr, 1024); + sem_post(sem_child_grandchild); // Signal parent + } + + // Unmap the shared memory object + if (munmap(ptr, size) == -1) { + perror("munmap"); + return 1; + } + + // Close the shared memory file descriptor + if (close(shm_fd) == -1) { + perror("close"); + return 1; + } + // printf("child writing to shm\n"); + + // Unmap the shared memory object + if (munmap(ptr2, size) == -1) { + perror("munmap"); + return 1; + } + + // Close the shared memory file descriptor + if (close(shm2_fd) == -1) { + perror("close"); + return 1; + } + + shm_unlink(shm1_name); + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); + wait(NULL); + exit(EXIT_SUCCESS); + } + + // GrandChild Process + else if (GRAND_CHILD == 0) { /* GrandChild reads from pipe */ + int shm2_fd = shm_open(shm2_name, O_CREAT | O_RDWR, 0666); + if (shm2_fd == -1) { + perror("shm_open"); + return 1; + } + + // Resize the shared memory object to the desired size + if (ftruncate(shm2_fd, size) == -1) { + perror("ftruncate"); + return 1; + } + + // Map the shared memory object into the process address space + void *ptr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm2_fd, 0); + if (ptr2 == MAP_FAILED) { + perror("mmap"); + return 1; + } + + for(int i=0; i<5; i++){ + sem_wait(sem_child_grandchild); + // Print the contents of the shared memory + // printf("Grandchild reading from shm...\n"); + printf("GC - Shared memory contents: %s\n", (char *)ptr2); + } + + // Unmap the shared memory object + if (munmap(ptr2, size) == -1) { + perror("munmap"); + return 1; + } + + // Close the shared memory file descriptor + if (close(shm2_fd) == -1) { + perror("close"); + return 1; + } + + shm_unlink(shm2_name); + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); + exit(EXIT_SUCCESS); + } + } + + sem_close(sem_parent_child); + sem_close(sem_child_grandchild); + sem_unlink(sem1_name); + sem_unlink(sem2_name); + + cout << "success" << endl; + return 0; +} \ No newline at end of file