Ann
Ann

Reputation: 79

parent doesn't read from pipe

I want to communicate children process with parent process. I create 5 children and everyone send to pipe message "Hello". But parrent read only one message.. I'm very beginner and I don't know what I'm doing wrong... My code so far:

int main(int argc, char** argv) {
    int n, p1[2], p2[2];
    n = 2*atoi(argv[1]);
    if(pipe(p1)) ERR("pipe1");
    if(pipe(p2)) ERR("pipe2");
    create_children(n, p1, p2);
        if(TEMP_FAILURE_RETRY(close(p1[1]))) ERR("close");
    parent_work(p1);
    if(TEMP_FAILURE_RETRY(close(p1[0]))) ERR("close");
    return EXIT_SUCCESS;
}

void create_children(int number, int p1[2], int p2[2]) {
    while (number-- > 0) {
        switch (fork()) {
            case 0:
                if(TEMP_FAILURE_RETRY(close(p1[0]))) ERR("close");
                if(TEMP_FAILURE_RETRY(close(p2[0]))) ERR("close");
                child_work(p1[1], p2[1]);
                if(TEMP_FAILURE_RETRY(close(p1[1]))) ERR("close");
                if(TEMP_FAILURE_RETRY(close(p2[1]))) ERR("close");
                exit(EXIT_SUCCESS);

            case -1: ERR("Fork:");
        }
    }
}

void child_work(int fd, int fd1, char *name, int which) {
    char buffer[PIPE_BUF];
    size_t *len = (size_t*)buffer;

    char mb[PIPE_BUF];
    snprintf(mb,PIPE_BUF,"%d hello\n",getpid());
    if (-1 == TEMP_FAILURE_RETRY (write (fd, mb, (strlen(mb)+1))))  /
            ERR ("sending witaj");
            else
            printf("%s\n",mb);  
}

void parent_work(int fd) {
    char buffer[PIPE_BUF];
    if(TEMP_FAILURE_RETRY(read(fd, buffer, PIPE_BUF))==PIPE_BUF)ERR("read:");   
    printf("Process send message: %s\n", buffer);

    while(TEMP_FAILURE_RETRY(wait(NULL))>0);
}

When I create 5 children, I received only 1 message.

Upvotes: 0

Views: 160

Answers (2)

Klas Lindbäck
Klas Lindbäck

Reputation: 33273

The children send null-terminated messages, so if the parent receives all messages in one read the parent will only print the first message.

I suggest that you let the children send newline-terminated messages instead (append a \n to the send string and don't send the null terminator).

Upvotes: 0

Jens
Jens

Reputation: 72639

This can't work:

char mb[]=" ";
snprintf(mb,PIPE_BUF,"%d",getpid());
strcat(mb,"hello");

You write past the end of mb which has only room for two characters since it was initialized with a space followed by a NUL byte. In C, arrays don't magically grow when you write past their end, as you do with the snprintf and strcat.

Technically you invoke what is called undefined behavior, which means anything can happen.

Upvotes: 1

Related Questions