0% found this document useful (0 votes)
10 views7 pages

Individual Assignment

Individual Assignment

Uploaded by

Muhammad Jamil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views7 pages

Individual Assignment

Individual Assignment

Uploaded by

Muhammad Jamil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Creating a program that forks into multiple child processes, enables message passing from the

parent to child processes using pipes, allows the parent to enter a message, and displays the
message in child processes is a complex task. #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_CHILDREN 3
#define MESSAGE_SIZE 100

int pipes[MAX_CHILDREN][2]; // Array to hold pipe file descriptors


pid_t child_pids[MAX_CHILDREN];

void interruptHandler(int signal) {


printf("\nCtrl+C interrupt detected. Program terminated.\n");
for (int i = 0; i < MAX_CHILDREN; i++) {
if (child_pids[i] > 0) {
kill(child_pids[i], SIGTERM);
}
}
exit(0);
}

int main() {
signal(SIGINT, interruptHandler); // Register interrupt handler

for (int i = 0; i < MAX_CHILDREN; i++) {


if (pipe(pipes[i]) == -1) {
perror("Pipe creation failed");
exit(1);
}

pid_t child_pid = fork();

if (child_pid == -1) {
perror("Fork failed");
exit(1);
} else if (child_pid == 0) {
// Child process
close(pipes[i][1]); // Close the write end of the pipe

char message[MESSAGE_SIZE];
int bytes_read = read(pipes[i][0], message, MESSAGE_SIZE);
if (bytes_read > 0) {
message[bytes_read] = '\0';
printf("Child %d received message: %s", i, message);
} else {
printf("Child %d received no message.\n", i);
}

close(pipes[i][0]); // Close the read end of the pipe


exit(0);
} else {
// Parent process
child_pids[i] = child_pid; // Store child process IDs
close(pipes[i][0]); // Close the read end of the pipe

char message[MESSAGE_SIZE];
printf("Enter a message for Child %d: ", i);
fgets(message, MESSAGE_SIZE, stdin);
write(pipes[i][1], message, strlen(message) + 1);

close(pipes[i][1]); // Close the write end of the pipe


}
}

// Parent waits for all child processes to finish


for (int i = 0; i < MAX_CHILDREN; i++) {
wait(NULL);
}

return 0;
}

This program creates multiple child processes, sets up pipes for inter-process communication,
allows the parent to enter a message for each child, and displays the messages in the child
processes. It also handles Ctrl+C interrupts gracefully. Note that the number of child processes
can be controlled by changing the `num_children` variable.

Codes Explanation

```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
```

These are the necessary header files included in the code for standard input/output, memory
allocation, process management, and signal handling.

```c
#define MAX_CHILDREN 3
#define MESSAGE_SIZE 100
```

These are constant definitions used in the code. `MAX_CHILDREN` specifies the maximum
number of child processes, and `MESSAGE_SIZE` sets the maximum size for messages
passed between the parent and child processes.

```c
int pipes[MAX_CHILDREN][2]; // Array to hold pipe file descriptors
pid_t child_pids[MAX_CHILDREN];
```

Here, we declare an array to hold file descriptors for pipes, which are used for communication
between parent and child processes. `child_pids` is an array to store the process IDs of the
child processes.

```c
void interruptHandler(int signal) {
printf("\nCtrl+C interrupt detected. Program terminated.\n");
for (int i = 0; i < MAX_CHILDREN; i++) {
if (child_pids[i] > 0) {
kill(child_pids[i], SIGTERM);
}
}
exit(0);
}
```

This function `interruptHandler` is a signal handler for the Ctrl+C (SIGINT) interrupt signal. It
prints a message and gracefully terminates the program, ensuring that child processes are also
terminated.

```c
int main() {
signal(SIGINT, interruptHandler); // Register interrupt handler
```

In the `main` function, we register the `interruptHandler` function to handle the Ctrl+C signal.

```c
for (int i = 0; i < MAX_CHILDREN; i++) {
if (pipe(pipes[i]) == -1) {
perror("Pipe creation failed");
exit(1);
}
```

This loop creates a set of pipes for inter-process communication. If pipe creation fails, an error
message is printed, and the program exits.

```c
pid_t child_pid = fork();

if (child_pid == -1) {
perror("Fork failed");
exit(1);
} else if (child_pid == 0) {
```

Here, we use `fork` to create child processes. If `fork` fails, an error message is printed, and the
program exits. If `fork` succeeds, the code inside the `if (child_pid == 0)` block runs, indicating
that this section is executed only by child processes.
```c
close(pipes[i][1]); // Close the write end of the pipe

char message[MESSAGE_SIZE];
int bytes_read = read(pipes[i][0], message, MESSAGE_SIZE);
if (bytes_read > 0) {
message[bytes_read] = '\0';
printf("Child %d received message: %s", i, message);
} else {
printf("Child %d received no message.\n", i);
}

close(pipes[i][0]); // Close the read end of the pipe


exit(0);
} else {
```

This code is executed by the child processes. It closes the write end of the pipe, reads a
message from the pipe, and prints the received message. It then closes the read end of the pipe
and exits.

```c
child_pids[i] = child_pid; // Store child process IDs
close(pipes[i][0]); // Close the read end of the pipe

char message[MESSAGE_SIZE];
printf("Enter a message for Child %d: ", i);
fgets(message, MESSAGE_SIZE, stdin);
write(pipes[i][1], message, strlen(message) + 1);

close(pipes[i][1]); // Close the write end of the pipe


}
```

This section is executed by the parent process. It stores the child process IDs, closes the read
end of the pipe, allows the user to enter a message, writes the message to the pipe, and closes
the write end of the pipe.

```c
for (int i = 0; i < MAX_CHILDREN; i++) {
wait(NULL);
}
```
Finally, the parent process waits for all child processes to finish before exiting.

You might also like