hört sich ja schwer nach sysprog an. naja, hier bitte:
/* MASTERMIND by Ernst Schwartz, 0004444*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#define MAXCHAR 5
const char *szCommand = "<not yet set>";
static int pipe_father2son[2];
static int pipe_son2father[2];
static FILE *stream_father2son = (FILE *) 0;
static FILE *stream_son2father = (FILE *) 0;
int status;
pid_t pid;
pid_t wpid;
void BailOut(const char *szMessage);
void FreeRessources(void);
/* GENERATES RANDOM 4-DIGIT NUMBER & STORES IT IN AN CHAR-ARRAY */
char *GenerateRandom(void)
{
static char random_number[MAXCHAR];
srand(time(NULL)*rand());
(void) sprintf(random_number, "%04d\0", rand()%10000);
return random_number;
}
/* COMPARES 2 NUMBERS AND RETURNS THE POINTS & X */
char *CompareNumbers(char *number1, char *number2)
{
int i;
int j;
int anzahl_X; /* Ziffern vorhanden, aber an der falschen Stelle */
int anzahl_Punkte; /* Ziffern an der richtigen Stelle */
char *result = "\0";
i = j = anzahl_X = anzahl_Punkte = 0;
/* printf("%s vs. %s\n", number1, number2); */
while(i<(MAXCHAR-1))
{
while(j<(MAXCHAR-1))
{
if(number1[i] == number2[j])
{
if(i==j)
{
anzahl_X++;
/* printf("%d - %d, %c - %c: X: %d\n", i, j, number1[i], number2[j], anzahl_X); */
} else
{
anzahl_Punkte++;
/* printf("%d - %d, %c - %c: Punkte: %d\n", i, j, number1[i], number2[j], anzahl_Punkte); */
}
number2[j] = 'X';
/* printf("number1: %s, number2: %s\n", number1, number2); */
break;
}
j++;
}
i++;
j=0;
}
if (anzahl_X == 4)
(void) sprintf(result, "Du hast meine Zahl erraten!\n");
else
(void) sprintf(result, "X = %d, Punkte = %d\n", anzahl_X, anzahl_Punkte);
return(result);
}
/* CHECKS IF INPUT IS CORRECT (only digits, not too short) */
int CheckInput(char *text)
{
int i = 0;
do
{
if(!isdigit(text[i]) && text[i] != '\0')
return 1;
} while (text[i++] != '\0');
return 0;
}
/* HOW TO USE THIS PROGRAM */
void Usage(void)
{
(void) fprintf(stderr, "USAGE: %s\n", szCommand);
BailOut((const char *) 0);
}
/* PRINTS ERROR-MESSAGES */
void BailOut(const char *szMessage)
{
if (szMessage != (const char *) 0)
(void) fprintf(stderr, "%s", szMessage);
exit(EXIT_FAILURE);
}
/* THE CHILD PROCESS; GENERATES RANDOM NUMBER & COMPARES IT TO WHAT IT GETS FROM THE FATHER */
/* RETURNS THE RESULT TO THE FATHER */
void ChildProcess(void)
{
char *number, *number_tmp = "\0";
char buffer[MAXCHAR];
char *result;
number = GenerateRandom();
(void) printf("CHILD: created number %s\n", number);
if (close(pipe_father2son[1]) == -1)
{
BailOut("Error closing the write descriptor father -> son!");
}
/* printf("CHILD (134): CLOSED WRITE DESCRIPTOR father -> son.\n"); */
if ((stream_father2son = fdopen(pipe_father2son[0], "r")) == (FILE *) NULL)
{
BailOut("Cannot open pipe father -> son for reading!");
}
/* printf("CHILD (141): OPENED PIPE father -> son FOR READING.\n"); */
if (close(pipe_son2father[0]) == -1)
{
BailOut("Error closing the read descriptor son -> father!");
}
/* printf("CHILD (169): CLOSED READ DESCRIPTOR son -> father.\n"); */
if ((stream_son2father = fdopen(pipe_son2father[1], "w")) == (FILE *) NULL)
{
BailOut("Cannot open pipe son -> father for writing!");
}
/* printf("CHILD (177): OPENED PIPE son -> father FOR WRITING.\n"); */
/* NOW READING FROM FATHER ! */
do {
(void) strncpy(number_tmp, number, sizeof(number));
/* printf("ANFANG: %s\n", number); */
if (fgets(buffer, MAXCHAR, stream_father2son) == NULL)
{
BailOut("Can't read from stream father -> son!");
}
/* printf("CHILD (148): READ FROM PIPE father -> son.\n"); */
/* printf("VOR COMPARE: %s vs. %s\n", number, buffer); */
result = CompareNumbers(number_tmp, buffer);
/* printf("NACH COMPARE: %s vs. %s\n", number, buffer); */
/* printf("CHILD: FUNCTION RETURNED: %s\n", result); */
/* printf("CHILD (158): CHECKED RESULT.\n"); */
/* NOW WRITING TO FATHER ! */
if (fprintf(stream_son2father, result) < 0)
{
BailOut("Cannot write to pipe son -> father!");
}
/* printf("CHILD (185): WROTE TO PIPE son -> father.\n"); */
if (fflush(stream_son2father) == EOF)
{
BailOut("Cannot flush pipe son -> father!");
}
/* printf("CHILD (193): FLUSHED PIPE son -> father.\n"); */
if(result[0] == 'D')
break;
/* printf("ENDE: %s\n", number); */
} while (1);
FreeRessources();
/* printf("CHILD (205): FREE'D RESSOURCES.\n"); */
exit(EXIT_SUCCESS);
}
/* FATHER PROCESS; GETS USER INPUT, SENDS IT TO CHILD, RECEIVES RESULTS FROM CHILD */
/* AND PRINTS THEM ON stdout */
void FatherProcess(void)
{
char input[MAXCHAR];
char result[1024];
result[0] = '\0';
if (close(pipe_father2son[0]) == -1)
{
BailOut("Error closing the read descriptor father -> son!");
}
/* printf("PARENT (227): CLOSED READ DESCRIPTOR father -> son.\n"); */
if ((stream_father2son = fdopen(pipe_father2son[1], "w")) == (FILE *) NULL)
{
BailOut("Cannot open pipe father -> son for writing!");
}
/* printf("PARENT (235): OPENED PIPE father -> son FOR WRITING.\n"); */
if (close(pipe_son2father[1]) == -1)
{
BailOut("Error closing the write descriptor son -> father!");
}
/* printf("PARENT (261): CLOSED WRITE DESCRIPTOR son -> father.\n"); */
if ((stream_son2father = fdopen(pipe_son2father[0], "r")) == (FILE *) NULL)
{
BailOut("Cannot open pipe son -> father for reading!");
}
/* printf("PARENT (269): OPENED PIPE son -> father FOR READING.\n"); */
while (result[0] != 'D')
{
result[0] = '\0';
do
{
input[0] = '\0';
(void) printf("PARENT: Write something: ");
if (fgets(input, MAXCHAR, stdin) == NULL)
{
BailOut("Couldn't read from stdin!");
}
if (fflush(stdin) == EOF)
{
BailOut("Couldn't flush stdin!");
}
if(CheckInput(input) == 1)
{
(void) printf("%s: Bad bad input!\n", input);
continue;
}
break;
} while(1);
/* NOW WRITING TO SON ! */
if (fprintf(stream_father2son, input) < 0)
{
BailOut("Can't write to pipe father -> son!");
}
/* printf("PARENT (243): WROTE TO PIPE father -> son.\n"); */
if(fflush(stream_father2son) == EOF)
{
BailOut("Can't flush stream father -> son");
}
/* printf("PARENT (251): FLUSHED STREAM father -> son.\n"); */
/* NOW READING FROM SON ! */
if (fgets(result, 1024, stream_son2father) == NULL)
{
BailOut("Can't read from stream son -> father!");
}
/* printf("PARENT (277): READ FROM PIPE son -> father.\n"); */
(void) printf("%s", result);
}
FreeRessources();
/* printf("PARENT (282): FREE'D RESSOURCES.\n"); */
}
/* MAKES THE PIPES */
void AllocateRessources(void)
{
if (pipe(pipe_father2son) == -1)
BailOut("Cannot create pipe father -> son!");
if (pipe(pipe_son2father) == -1)
BailOut("Cannot create pipe son -> father!");
}
/* CLOSES THE STREAMS */
void FreeRessources(void)
{
if (stream_father2son != (FILE *) 0)
{
if (fclose((FILE *) stream_father2son) == EOF)
{
stream_father2son = (FILE *) 0;
BailOut("Cannot close pipestream!");
}
stream_father2son = (FILE *) 0;
}
if (stream_son2father != (FILE *) 0)
{
if (fclose((FILE *) stream_son2father) == EOF)
{
stream_son2father = (FILE *) 0;
BailOut("Cannot close pipestream!");
}
stream_son2father = (FILE *) 0;
}
}
/* MAIN METHOD; FORKS CHILD, PLAYS GAME, WAITS FOR CHILD TO EXIT, THEN EXITS */
int main(int argc, char *argv[])
{
szCommand = argv[0];
if (argc != 1)
{
Usage();
}
AllocateRessources();
switch(pid=fork())
{
case -1:
perror("fork"); /* something went wrong */
exit(1); /* parent exits */
case 0:
ChildProcess();
default:
(void) printf("%s\n", "== MASTERMIND ==");
FatherProcess();
while ((wpid = wait(&status)) != pid)
{
if (wpid != -1)
{
continue;
}
if (errno == EINTR)
{
continue;
}
BailOut("Error waiting for child process!");
}
}
exit(EXIT_SUCCESS);
}
Alles anzeigen