+/**
+ * Message shared by processes. Contains array of process IDs
+ */
+struct message {
+ pid_t pids[3];
+};
+
+struct message * processes = NULL;
+
+/**
+ * Message queue variables
+ */
+key_t qkey;
+int qid_input;
+
+int qid_output1;
+int qid_output2;
+
+struct queue_message {
+ int signo;
+};
+
+/**
+ * Handler for signals.
+ */
+void sig_handler(int signo)
+{
+ fprintf(stderr, "[%s] Received %s!\n", "process3", strsignal(signo));
+ if (signo == SIGUSR1) {
+ fprintf(stderr, "[%s] > Notified!\n", "process3");
+ }
+ else if (signo == SIGTERM) {
+ int i = 0;
+ struct queue_message msg;
+ msg.signo = signo;
+
+ fprintf(stderr, "[%s] > Releasing resources\n", "process3");
+ close(read_descriptor);
+ for (; i < 3; i++) {
+ pid_t pid = processes->pids[i];
+ fprintf(stderr, "[%s] Process %d, PID: %d\n", "process3", i, pid);
+ // Bleh
+ if (i != 2) {
+ msgsnd(pid, &msg, sizeof(msg));
+ kill(pid, SIGUSR1);
+ }
+ }
+ exit(0);
+ }
+ else if (signo == SIGTSTP) {
+ fprintf(stderr, "[%s] > Closing pipe\n", "process3");
+ close(read_descriptor);
+ raise (SIGSTOP);
+ }
+ else if (signo == SIGCONT) {
+ fprintf(stderr, "[%s] > Opening pipe\n", "process3");
+ read_descriptor = open(read_pipe, O_RDONLY);
+ }
+}
+
+/**
+ * Program grabs data (calculated number of characters) from process2 and prints
+ * grabbed data to the standard output.
+ */
+int main(void) {
+ /** Buffer used for storing data from input pipe */