Cryptos90
Cryptos90

Reputation: 3

FIFO pipe - Child wont read properly

I try to use two FIFOs, one for the child process and one for the parent. First, the child should write a question in the parent FIFO. Parent waits until question arrives, then reads it, answers it and writes the answer in the child's FIFO. Child waits for the answer, then reads it and puts it out.

Problem is, somehow the child reads always an empty answer and I don't know why.

Code below:

MAIN:

int main() {

    pid_t child, parent;
    char quest[PIPE_BUF];
    int n=0;
    switch(fork()) {

        case CHILD: {

            while(n==0){
                printf("Bitte Frage stellen\n");
                n=scanf("%s", quest);
            }
        }
            child = getpid();
            question(quest, child);
            break;
        case ERROR:
            perror("fork():");
            break;

        default:
            printf("waiting for input\n");
            parent = getpid();
            oracle(parent);
    }

    return EXIT_SUCCESS;

}

CHILD FUNCTION

void question(const char *buf, pid_t pid ){
    char filename[PIPE_BUF];

    if (mkfifo(ANSW, 0666) == -1){
        if(errno == EEXIST)
            perror(" oracle mkfifo:");
        else{
            perror(" oracle mkfifo:");
            exit(EXIT_FAILURE);
        }
    }
    int fd, fd2;
    fd = open(FIFO, O_WRONLY);
    char quest[PIPE_BUF + 1];
    char answer[PIPE_BUF + 1];
    int n = 0;

    sprintf(quest, "%d:", pid);
    strcat(quest,buf);
    write(fd,quest,strlen(quest));
    sleep(2);
    fd2= open(ANSW,O_RDONLY);

    printf("%s\n", answer);
    while(1) {
        n=read(fd2, answer, strlen(answer));
        if (n == -1) {
            perror(" client read():");
            break;
        } else if (n > 0){
            puts(answer);
            break;
        }
    }
    remove("/tmp/answer.me");
    unlink(FIFO);
    unlink(ANSW);
    close(fd);
    close(fd2);
}

PARENT FUNCTIONS:

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;
}

int answer(char * buf, pid_t pid){
    int i = 0;
    int fd = open(ANSW, O_WRONLY);
    char answer[PIPE_BUF + 1];
    size_t x = strlen(buf);
    buf[x+1] = '\0';
    do{
        i++;
        if(buf[i] == '\0'){
            --i;
            if(buf[i] != '?'){

                sprintf(answer, "%s","Dies ist keine Frage.\n");
                write(fd,answer, strlen(answer));
                i++;
            }else if(isVokal(buf,i)){

                sprintf(answer, "%s","Yes!\n");
                write(fd,answer, strlen(answer));
                i++;
            }else{

                sprintf(answer, "%s","No!\n");
                write(fd,answer, strlen(answer));
                i++;
            }
        }

    }while ( buf[i] != '\0');
    close(fd);

    return 0;
}

void oracle(pid_t pid) {
    int i = 1;
    if ((mkfifo(FIFO, 0666) == -1)){
        if(errno == EEXIST)
            perror(" oracle mkfifo:");
        else{
            perror(" oracle mkfifo:");
            exit(EXIT_FAILURE);
        }
    }
    int fd = open(FIFO, O_RDONLY);
    if(fd == -1)
        perror(" oracle open():");
    char buf[PIPE_BUF + 1];

    while (i) {
        printf("waiting for input\n");
        int n = read(fd, buf, PIPE_BUF);

        if (n == -1)
            perror(" oracle read():");
        else if (n >= 0)
            i=answer(buf, pid);

    }
    close(fd);
    remove("/tmp/ask.me");
    unlink(FIFO);
    unlink(ANSW);

}

Upvotes: 0

Views: 101

Answers (0)

Related Questions