Reputation: 3
My Client.c ask for user input and writes it to the FIFO of the oracle.c called ask.me. While my oracle.c is waiting to read something. If the client writes something,the oracle reads it and writes an answer in the fifo of the client called answer.(pid of the client). The client waits and the reads the answer and puts it out.
everything works fine, til the client has to read and put the answer out. Because the client always puts out a empty line and i dont know if the oracle doesnt write anything or the client cant read it.
please help
ORACLE.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define FIFO "/tmp/ask.me"
int isVokal(const char* buf, int i){
if (buf[i] == '?' && ((buf[i-1] == 'a') || (buf[i-1] == 'e') ||(buf[i-1] == 'i') || (buf[i-1] == 'o') || (buf[i-1] == 'u')))
return 1;
else
return 0;
}
char *adress(const char *buf){
char tmp[500];
char adress[500] = "/tmp/answer.";
int i = 0;
while(buf[i] != ':'){
tmp[i] = buf[i];
i++;
}
strcat(adress, tmp);
puts(adress);
return adress;
}
int answer(char * buf){
int i = 0;
int fd = open(adress(buf), O_WRONLY | O_NONBLOCK );
char *answer = malloc(PIPE_BUF);
do{
i++;
if(buf[i] == '\0'){
--i;
if(buf[i] != '?'){
sprintf(answer, "%s","Dies ist keine Frage.\n");
write(fd,answer, PIPE_BUF);
i++;
}else if(isVokal(buf,i)){
sprintf(answer, "%s","Yes!\n");
write(fd,answer, PIPE_BUF);
i++;
}else{
sprintf(answer, "%s","No!\n");
write(fd,answer, PIPE_BUF);
i++;
}
}
}while ( buf[i] != '\0');
free(answer);
close (fd);
return 0;
}
void oracle() {
int i = 1;
char *buf;
buf = malloc(PIPE_BUF);
if ((mkfifo(FIFO, 0666)) == -1)
perror(" oracle mkfifo:");
int fd = open(FIFO, O_RDONLY );
if(fd == -1)
perror(" oracle open():");
while (i) {
printf("waiting for input\n");
int n = read(fd, buf, PIPE_BUF);
if (n == -1) {
perror(" oracle read():");
exit(EXIT_FAILURE);
}else{
i=answer(buf);
}
sleep(2);
}
free(buf);
close(fd);
}
int main(){
oracle();
return 0;
}
CLIENT.c
#include <fcntl.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define FIFO "/tmp/ask.me"
void question(){
id_t pid = getpid();
int fd2,fd;
char *quest = malloc(PIPE_BUF);
char *answer = malloc(PIPE_BUF);
char *buf= malloc(PIPE_BUF);
char *myID= malloc(PIPE_BUF);
int n = 0;
char adress[500] = "/tmp/answer.";
sprintf(myID, "%d", pid);
strcat (adress, myID);
if (mkfifo(adress, 0666) == -1){
if(errno == EEXIST)
perror(" oracle mkfifo:");
else{
perror(" oracle mkfifo:");
exit(EXIT_FAILURE);
}
}
fd = open(FIFO, O_WRONLY );
if(fd == -1){
perror("client fd open():");
exit(EXIT_FAILURE);
}
while(n==0){
printf("Bitte Frage stellen\n");
n=scanf("%s", buf);
}
sprintf(quest, "%d :", pid);
strcat(quest, buf);
write(fd,quest,PIPE_BUF);
close(fd);
sleep(5);
fd2 = open(adress, O_RDONLY|O_NONBLOCK);
if(fd2 == -1){
perror("client fd2 open():");
exit(EXIT_FAILURE);
}
while(1) {
n=read(fd2, answer, PIPE_BUF);
if (n == -1) {
perror(" client read():");
break;
} else{
puts(answer);
break;
}
sleep(2);
}
free(quest);
free(answer);
free(buf);
free(myID);
close(fd2);
unlink(adress);
}
int main(){
question();
return 0;
}
Upvotes: 0
Views: 58
Reputation: 48672
Lots of problems here:
return adress;
returns a pointer that immediately becomes dangling, so using it is Undefined Behavior.:
in CLIENT.c, so ORACLE tries to open the wrong filename.O_NONBLOCK
only works if you're opening it for reading. It will fail with ENXIO
if you try to open it with O_WRONLY
and there's no reader yet.O_NONBLOCK
will fail with EWOULDBLOCK
if there's no data to read yet.Fix all of those things and your client program will be able to print Dies ist keine Frage.
By the way, your sleep(2);
in CLIENT.c will never run, and you're usually reading and writing a bunch of uninitialized garbage after the data you intend to transfer.
Upvotes: 0