I'm having trouble with two programs that work with pipes, processes, and signals. The first program, prompt.c, takes the path of the executable of the second program, toupper.c, as its command-line argument. It then creates a child process that runs the second program. The parent process should prompt the user to enter a line of text, which is read and sent via a pipe to standard input of the child process. The parent process should then send a SIGUSR1 signal to the child process and pause until it receives a SIGUSR2 signal from the child, after which it resumes execution and prompts the user to enter the next line. The toupper.c program, run by the child process, should contain a loop, within which it should wait until it receives a SIGUSR1 signal from the parent process, then it should read a line of text from standard input, convert the line to uppercase, print the resulting line on the terminal, and send a SIGUSR2 signal back to the parent process to indicate that it has finished processing that line. If the user does not enter any line one minute after a prompt, the parent process should print a helpful message on the terminal and continue to wait for a line.
Here's prompt.c
Code:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#define Max_characters 1000
static int alarm_off = 0;
static int stat_val;
void int_quit_handler(int signal)
{
printf("Goodbye.\n"); //Prints out Goodbye to screen.
kill (getppid(), SIGTERM);
wait(&stat_val);
}
void handler(int signal)
{
}
void ding(int sig)
{
alarm_off = 1;
}
int main(int argc, char * argv[])
{
char *filepath; //Makes a char variable named filepath,
char msg[Max_characters+2]; //Makes a char named msg.
int pipedes[2]; //Makes variable for pipes.
pid_t pid;
int stat_val;
pid_t child_pid;
struct sigaction int_handler;
struct sigaction quit_handler;
struct sigaction usr2_handler;
if (argc != 2)
{
printf("Not enough arguments. Next time, remember to enter the filepath of Toupper.c.\n"); //Prints error message if
//user does not enter enough arguments.
return (EXIT_FAILURE); //Exits on failure.
}
child_pid = wait(&stat_val);
filepath = argv[1];
int_handler.sa_handler = int_quit_handler;
quit_handler.sa_handler = int_quit_handler;
usr2_handler.sa_handler = handler;
int_handler.sa_flags = 0;
quit_handler.sa_flags = 0;
usr2_handler.sa_flags = 0;
sigemptyset(&int_handler.sa_mask);
sigemptyset(&quit_handler.sa_mask);
sigemptyset(&usr2_handler.sa_mask);
sigaction(SIGINT, &int_handler, 0);
sigaction(SIGQUIT, &quit_handler, 0);
sigaction(SIGUSR2, &usr2_handler, 0);
pipe(pipedes); //Makes pipes.
switch(fork())
{
case -1:
perror("Error with fork.\n"); //Prints out error message if the fork fails.
return (EXIT_FAILURE); //Exits on failure.
case 0:
close(pipedes[1]);
dup2(pipedes[0], 0);
close(pipedes[0]);
execl("Toupper", "Toupper", 0);
kill(getppid(), SIGUSR2);
exit(1);
}
printf("Please enter a line of text: "); //Asks user to enter a line of text.
fgets(msg, sizeof(msg), stdin); //Reads in the line.
write(pipedes[1], msg, strlen(msg)); //Writes line to the pipe.
//sleep(60);
//printf("Please enter a line of text as soon as possible.\n");
//kill(getppid(), SIGALRM);
//signal(SIGALRM, ding);
//signal(SIGUSR2, handler);
//signal(SIGINT, int_quit_handler);
//signal(SIGQUIT, int_quit_handler);
close(pipedes[1]);
return (EXIT_SUCCESS); //Exits on success.
}
And here's Toupper.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <ctype.h>
#include <sys/wait.h>
void handler(int signal)
{
}
int main()
{
int ch; //Makes an int variable named ch.
sigset_t mask1, mask2; //Makes sigset_t variables named mask1 and mask2.
struct sigaction usr1_handler; //Makes a sigaction variable named usr1_handler.
usr1_handler.sa_handler = handler;
usr1_handler.sa_flags = 0;
sigemptyset(&usr1_handler.sa_mask);
sigaction(SIGUSR1, &usr1_handler, 0);
sigemptyset(&mask1);
sigaddset(&mask1, SIGINT);
sigaddset(&mask1, SIGQUIT);
sigprocmask(SIG_BLOCK, &mask1, 0);
while((ch = getchar()) != EOF)
{
putchar(toupper(ch)); //Prints the standard input to the screen in all uppercase.
fflush(stdin); //Flushes the standard input.
}
kill(getppid(), SIGUSR2);
return(EXIT_SUCCESS); //Returns success.
}