hi there!here's the problem in a nutshell:
there are 2 files.the program creates 2 processes:
the parent process outputs text lines from the 1st file and for each one of these lines the child process outputs relative info from the 2nd file.
e.g.
<1st line from file1>
<relative info from file2>
<relative info from file2>
...
<2nd line from file1>
<relative info from file2>
...
the problem is that after printing everything it keeps running. to be more specific, the parent process remains in a wait state and the child process gets stuck in a pipe_w state.
I'm clearly missing something but can't seem to be able to find it, so any help would be much appreciated!
here's the code:

#include <stdio.h>
#include <string.h>

void client(int readfd, int writefd);
void server(int readfd, int writefd);

int main(){
    int childpid, pipe[2], pipe[2], status;
    if((pipe(pipe1)< 0)||pipe(pipe2)< 0)){
        printf("Pipes were not created.\n";
        exit(1);
    }

    childpid = fork();
    if(childpid == -1){
        printf("Server wasn't created.\n);
        exit(1);
    }

    if(childpid > 0){ //parent
        close(pipe2[1]);
        close(pipe1[0]);
        client(pipe2[0], pipe1[1]);
        wait(&status);
        close(pipe2[0]);
        close(pipe1[1]);
        exit(0);
    }
    else{ //child
        close(pipe1[1]);
        close(pipe2[0]);
        server(pipe1[0], pipe2[1]);
        close(pipe1[0]);
        close(pipe2[1]);
        exit(0);
    }

    return 0;
}//end of main

void client(int readfd, int writefd){
    FILE *fp;
    fp = fopen("file1", "r");
    char buff[1024];
    char comm[320];
    char am[80];
    while(fgets(buff, sizeof buff, fp) != NULL){
        printf("%s \n", buff);

        //...(am is initialised here)

        writefd(writefd, am, strlen(am));
        while(read(readfd, comm, sizeof comm) <= 0){}
    }
    fclose(fp);
}

void server(int readfd, int writefd){
    char buff[1024];
    char am[80];
    while(read(readfd, am, sizeof am) > 0){
        FILE *fp;
        fp = fopen("file2", "r");
        while(fgets(buff, sizeof buff, fp) != NULL){
            //...
        }
        write(writefd, "done", 4);
        fclose(fp);
    }
}

Dani AI

Generated

The symptom (parent stuck in wait while the child is blocked on a pipe) is the classic consequence of leaving unused pipe ends open across the fork. A reader on a pipe does not get EOF until every writer for that pipe has closed its descriptor. If the parent still holds the child's write-end (or the child still holds the parent's read-end) after the work is done, the other side will block forever waiting for more data and the parent will never reap the child.

Practical checklist:

  • Close each unused end immediately after fork so each process keeps only the descriptors it actually uses.
  • Close the parent's copy of the pipe the child reads from before calling wait, so the child can see EOF and exit.
  • Check return values for read()/write() and handle partial writes and EINTR/EPIPE.
  • Replace busy-spin loops waiting on read() with a proper blocking read() or use poll()/select() if you need timeouts.
  • Use waitpid() and check its return to handle child termination reliably.

Debug tips that helped other posters here: add short printf checkpoints as suggested, and use strace -p <pid> or lsof -p <pid> to see which syscall and which file descriptors are blocking. correctly flagged that the busy-wait on read() is suspicious; ’s advice to close the pipes before waiting is the direct fix, which confirmed. For background on semantics see the system-call docs: pipe(2), read(2) and waitpid(2).

Recommended Answers

All 7 Replies

while(read(readfd, comm, sizeof comm) <= 0){}

What is this supposed to do?

just check the code at line 21 and 22 i think problem is there

: It waits for the child process to finish printing before outputing the next line from file1.
While server is printing it doesn't write anything to the pipe. When it's done line 67 is executed:

write(writefd, "done", 4);

and client continues with the outer loop.

(By the way "done" is just an example, it could be any string)

Perhaps i haven't understood completely the way pipes work...Do you think it's not needed?

: actually i think the execution freezes at line 24, so the problem must be either in server or client..

Try
    if(childpid > 0){ //parent
        close(pipe2[1]);
        close(pipe1[0]);
        client(pipe2[0], pipe1[1]);
        //---------------------------------------------------
        // I moved these, you have to close the pipes 
        // so the server can exit and then the wait 
        // will catch the exit of the server.
        close(pipe2[0]);
        close(pipe1[1]);
        wait(&status);
        exit(0);
    }
Now while(read(readfd, am, sizeof am) > 0) will see the EOF and read will return -1 and you break out of the while loop.

Put in checkpoints in your code like printf("Client: Now entering client function.");

Tell us what happens.

histrungalot, that was it, it works fine now!thanks a lot!!! :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.