Commit cfbf4096 authored by Taddeüs Kroes's avatar Taddeüs Kroes

- Implemented signals in OS ass3.

parent ea3add61
......@@ -6,6 +6,8 @@
#include <errno.h>
#include <signal.h>
static pid_t parent_pid;
/*
* Read from pipe (child processes only).
*/
......@@ -22,49 +24,47 @@ static void gup(FILE * log1, FILE * log2, int pipe_id[2], int myNumber)
fprintf(log1, "This is child number %d\n", myNumber);
fprintf(log2, "This is child number %d\n", myNumber);
/* just for sure - open one more log file .... */
/* Open a line buffered log. */
log3 = fopen("child.log3", "wt+");
setvbuf(log3, NULL, _IOLBF, BUFSIZ);
/* log3 is line buffered - a line of output is written
immediately on encountering an end-of-line */
fprintf(log3, "This is child number %d\n", myNumber);
do
{
/* Read next character from pipe */
/* Read next character from pipe */
if( read(pipe_id[0], &c, 1) <= 0 )
{
/* Error while reading from the pipe, exit */
/* Error while reading from the pipe, exit */
fprintf(log1, "Child %d read from pipe with error "
"and exited \n", myNumber);
"and exited \n", myNumber);
fprintf(log2, "Child %d read from pipe with error "
"and exited \n", myNumber);
"and exited \n", myNumber);
fprintf(log3, "Child %d read from pipe with error "
"and exited \n", myNumber);
"and exited \n", myNumber);
fclose(log1);
fclose(log2);
fclose(log3);
exit(1);
}
/* Character read successfully, process it */
/* Character read successfully, process it */
fprintf(log1, "Child %d read character %x: '%c'\n", myNumber, c, c);
fprintf(log2, "Child %d read character %x: '%c'\n", myNumber, c, c);
fprintf(log3, "Child %d read character %x: '%c'\n", myNumber, c, c);
if( c == 'P' )
{
/* Decrease antidote level or exit the process */
{
/* Decrease antidote level or exit the process */
if( !antidote )
{
fprintf(log1, "Child %d has no antidote for poison "
"and will exit \n", myNumber);
"and will exit \n", myNumber);
fprintf(log2, "Child %d has no antidote for poison "
"and will exit \n", myNumber);
"and will exit \n", myNumber);
fprintf(log3, "Child %d has no antidote for poison "
"and will exit \n", myNumber);
break;
"and will exit \n", myNumber);
break;
}
else
{
......@@ -72,11 +72,11 @@ static void gup(FILE * log1, FILE * log2, int pipe_id[2], int myNumber)
fprintf(log1, "antidote used (%d left) \n", antidote);
fprintf(log2, "antidote used (%d left) \n", antidote);
fprintf(log3, "antidote used (%d left) \n", antidote);
}
}
}
else if( c == 'A' )
{
/* Increase antidote level */
else if( c == 'A' )
{
/* Increase antidote level */
antidote++;
fprintf(log1, "Child %d finds antidote (now has %d) \n",
myNumber, antidote);
......@@ -87,7 +87,7 @@ static void gup(FILE * log1, FILE * log2, int pipe_id[2], int myNumber)
}
} while( c != '\0' );
/* Close logs and exit normally */
/* Close logs and exit normally */
fprintf(log1, "Child %d normal exit \n", myNumber);
fprintf(log2, "Child %d normal exit \n", myNumber);
fprintf(log3, "Child %d normal exit \n", myNumber);
......@@ -103,18 +103,34 @@ static void gup(FILE * log1, FILE * log2, int pipe_id[2], int myNumber)
void
signal_handler(int signum)
{
switch( signum )
{
case SIGINT:
break;
case SIGTERM:
break;
case SIGCHLD:
break;
}
char *sig = "TERM";
pid_t pid;
switch( signum )
{
case SIGINT:
sig = "INT";
case SIGTERM:
if( (pid = getpid()) == parent_pid )
{
printf("Parent process received SIG%s and will exit \n", sig);
}
else
{
printf("Process with id %d received SIG%s and will exit \n",
pid, sig);
}
exit(1);
case SIGCHLD:
puts("Parent process received SIGCHLD");
pid = wait(NULL);
printf("Child with id %d exited \n", pid);
break;
default:
puts("This handler is unapplicable for this type of signal");
}
errno = 0;
}
/*
......@@ -126,38 +142,54 @@ main(int argc, char * argv[])
FILE * log1;
FILE * log2;
char c;
int kiddoCount = 0, pipe_id[2];//, i = 1;
struct sigaction action;
int kiddoCount = 0, pipe_id[2];
struct sigaction action = {.sa_handler = signal_handler};
/* Save parent process id for signal handler */
parent_pid = getpid();
/* Open one buffered and one unbuffered log */
printf("argc: %d\n", argc);
log1 = fopen("child.log1", "wt+");
log2 = fopen("child.log2", "wt+");
setvbuf(log2, NULL, _IONBF, BUFSIZ);
/* So log1 is buffered; log2 is not buffered, which means that output
* to log2 is written immediately. */
/* Create pipe, exit with error on failure */
if( pipe(pipe_id) )
if( pipe(pipe_id) )
{
fprintf(stderr, "Error %d occured while creating the pipe \n",
errno);
errno);
exit(1);
}
/* Bind signal handlers */
action.sa_handler = signal_handler;
if( sigaction(SIGINT, &action, NULL) < 0
|| sigaction(SIGTERM, &action, NULL) < 0
|| sigaction(SIGCHLD, &action, NULL) < 0 )
{
perror("An error occured while binding the signal handlers \n");
exit(1);
}
/* Keep reading input */
/* Bind signal handlers */
if( sigaction(SIGINT, &action, NULL)
+ sigaction(SIGTERM, &action, NULL)
+ sigaction(SIGCHLD, &action, NULL) < 0 )
{
perror("An error occured while binding the signal handlers \n");
exit(1);
}
/* Keep reading input */
while( (c = getchar()) )
{
if( c == EOF )
{
if( errno == EINTR )
{
/* Wait for signal handler to end */
continue;
}
else
{
puts("Error while reading input from stdin");
fclose(log1);
fclose(log2);
exit(1);
}
}
/* Ignore newlines and spaces */
if( c == '\n' || c == 32 )
{
......@@ -170,25 +202,25 @@ main(int argc, char * argv[])
if( c == 'q' )
{
/* Exit program */
/* Exit program */
break;
}
else if( c != 'f' )
{
/* Write character to pipe for child processes */
if( write(pipe_id[1], &c, 1) != 1 )
/* Write character to pipe for child processes */
if( write(pipe_id[1], &c, 1) <= 0 )
{
perror("Cannot write to pipe \n");
exit(1);
}
/* Wait for child process to 'eat the poison' */
if( c == 'P' )
wait(NULL);
/* Wait for child process to 'eat the poison' */
//if( c == 'P' )
// wait(NULL);
}
else
{
pid_t child_id;
pid_t child_id;
kiddoCount++;
......@@ -198,24 +230,26 @@ main(int argc, char * argv[])
switch( (child_id = fork()) )
{
case -1:
/* An error occured while forking */
/* An error occured while forking */
perror("Child could not be created \n");
exit(1);
case 0:
/* Child process after fork: read from pipe */
/* Child process after fork: Start reading from pipe */
gup(log1, log2, pipe_id, kiddoCount);
break;
default:
/* Parent proces after fork: Print child's process id */
/* Parent proces after fork: Print child's process id */
fprintf(log1, "Started child process %d with id %d \n",
kiddoCount, child_id);
kiddoCount, child_id);
fprintf(log2, "Started child process %d with id %d \n",
kiddoCount, child_id);
kiddoCount, child_id);
printf("Started child process %d with id %d \n",
kiddoCount, child_id);
}
}
}
/* Close logs and exit normally */
/* Close logs and exit normally */
fprintf(log1, "Program exited normally \n");
fprintf(log2, "Program exited normally \n");
fclose(log1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment