Question: The parent process reads in an integer input through standard input (terminal), passes the input to the child (through a pipe), the child passes the

The parent process reads in an integer input through standard input (terminal), passes the input to the child (through a pipe), the child passes the input to the grandchild through a pipe, the grandchild replies back to the child with the square of the input (also through a pipe), the child multiplies the received square with the input to calculate the cube of the input before passing the cube to the parent (also through a pipe), and the parent displays the cube through the standard output (terminal) before prompting the user for the next input. This procedure repeats till the user enters a negative (-ve) input. Given a -ve input, the grandchild still computes the square of the input, and the child still computes the cube of the input based on the square of the input received from the grandchild and replies to the parent about the cube to display on the terminal before the program exits.

The program should (1) create only one child process and for only once and (2) create only one grandchild process and, also, for only once. That is, fork() is called only twice during the course of your program once for the child and once for the grandchild. Each of child process and the grandchild process is reused for computing of all input values. Below attached is what I have so far for the program. Also, this is a program in C. In my program, it is printing "Error: Could not create a child process. Error code: 87". It is having trouble with creating the child process. My question is, can you help fix and debug my code to help it create the parent, child and grandchild process so that it can calculate the cube of the input? My program:

#include  #include  #include  #include  #define BUF_SIZE 16 int main() { int num, square, cube, negsquare, negcube; HANDLE read_handle1, write_handle1, read_handle2, write_handle2; char buffer[BUF_SIZE]; SECURITY_ATTRIBUTES sec_attr; PROCESS_INFORMATION child_process_info, grandchild_process_info; STARTUPINFO startup_info; BOOL success; // Create the first pipe sec_attr.nLength = sizeof(sec_attr); sec_attr.bInheritHandle = TRUE; sec_attr.lpSecurityDescriptor = NULL; success = CreatePipe(&read_handle1, &write_handle1, &sec_attr, BUF_SIZE); if (!success) { fprintf(stderr, "Error: Could not create pipe. Error code: %d ", GetLastError()); return 1; } // Create the second pipe success = CreatePipe(&read_handle2, &write_handle2, &sec_attr, BUF_SIZE); if (!success) { fprintf(stderr, "Error: Could not create pipe. Error code: %d ", GetLastError()); return 1; } // Initialize the startup info structure for the child process ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); startup_info.hStdInput = read_handle1; startup_info.hStdOutput = write_handle2; startup_info.dwFlags |= STARTF_USESTDHANDLES; // Create the child process ZeroMemory(&child_process_info, sizeof(child_process_info)); success = CreateProcess( NULL, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &child_process_info ); if (!success) { fprintf(stderr, "Error: Could not create child process. Error code: %d ", GetLastError()); CloseHandle(read_handle1); CloseHandle(write_handle1); CloseHandle(read_handle2); CloseHandle(write_handle2); return 1; } // Create the grandchild process ZeroMemory(&grandchild_process_info, sizeof(grandchild_process_info)); success = CreateProcess( NULL, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &grandchild_process_info ); if (!success) { fprintf(stderr, "Error: Could not create grandchild process. Error code: %d ", GetLastError()); CloseHandle(read_handle1); CloseHandle(write_handle1); CloseHandle(read_handle2); CloseHandle(write_handle2); CloseHandle(child_process_info.hThread); CloseHandle(child_process_info.hThread); CloseHandle(child_process_info.hProcess); return 1; } // Loop to read input from the user and write it to the child process while (1) { printf("Enter a number: "); if (fgets(buffer, BUF_SIZE, stdin) == NULL) { perror("fgets"); exit(1); } num = atoi(buffer); if (num < 0) { if (!WriteFile(write_handle1, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "WriteFile failed. Error code: %d ", GetLastError()); return 1; } break; } if (!WriteFile(write_handle1, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "WriteFile failed. Error code: %d ", GetLastError()); return 1; } if (!ReadFile(read_handle2, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "ReadFile failed. Error code: %d ", GetLastError()); return 1; } square = atoi(buffer); cube = square * num; printf("Parent process: I received %d. ", cube); // Write the result back to the parent process snprintf(buffer, BUF_SIZE, "%d", cube); if (!WriteFile(write_handle1, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "WriteFile failed. Error code: %d ", GetLastError()); return 1; } // Read the result from the grandchild process if (!ReadFile(read_handle1, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "ReadFile failed. Error code: %d ", GetLastError()); return 1; } square = atoi(buffer); negsquare = square * -1; // Write the result back to the child process snprintf(buffer, BUF_SIZE, "%d", negsquare); if (!WriteFile(write_handle2, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "WriteFile failed. Error code: %d ", GetLastError()); return 1; } } // Wait for the grandchild process to exit and get its exit code DWORD grandchild_status; if (WaitForSingleObject(grandchild_process_info.hProcess, INFINITE) != WAIT_OBJECT_0) { fprintf(stderr, "WaitForSingleObject failed. Error code: %d ", GetLastError()); return 1; } if (!GetExitCodeProcess(grandchild_process_info.hProcess, &grandchild_status)) { fprintf(stderr, "GetExitCodeProcess failed. Error code: %d ", GetLastError()); return 1; } // Read the result from the child process if (!ReadFile(read_handle2, buffer, BUF_SIZE, NULL, NULL)) { fprintf(stderr, "ReadFile failed. Error code: %d ", GetLastError()); return 1; } negcube = atoi(buffer); // Wait for the child process to exit and get its exit code DWORD child_status; if (WaitForSingleObject(child_process_info.hProcess, INFINITE) != WAIT_OBJECT_0) { fprintf(stderr, "WaitForSingleObject failed. Error code: %d ", GetLastError()); return 1; } if (!GetExitCodeProcess(child_process_info.hProcess, &child_status)) { fprintf(stderr, "GetExitCodeProcess failed. Error code: %d ", GetLastError()); return 1; } // Display the result to the user printf("Grandchild process: I received %d. ", square); printf("Child process: I received %d from grandchild. ", square); printf("Parent process: I received %d. ", negcube); // Close the handles to the pipes and the processes if (!CloseHandle(read_handle1)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(write_handle1)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(read_handle2)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(write_handle2)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(child_process_info.hThread)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(child_process_info.hProcess)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(grandchild_process_info.hThread)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } if (!CloseHandle(grandchild_process_info.hProcess)) { fprintf(stderr, "CloseHandle failed. Error code: %d ", GetLastError()); return 1; } return 0; } 

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!