0

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.

Ann
  • 79
  • 10

2 Answers2

1

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.

Jens
  • 69,818
  • 15
  • 125
  • 179
0

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).

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • If I make this way: ` char mb[PIPE_BUF]; snprintf(mb,PIPE_BUF,"%d hello\n",getpid());` It won't send null? – Ann Mar 19 '14 at 09:19
  • Do like that and use send length `strlen(mb)` (instead of `strlen(mb) + 1`). – Klas Lindbäck Mar 19 '14 at 09:39
  • I still don't get what I want.. Parent receives all messages in one like you said, but I need to write "Process send message: %s\n", buffer); for every child process separately :( – Ann Mar 19 '14 at 10:01
  • Split the read string on `\n`. http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c – Klas Lindbäck Mar 19 '14 at 10:08