Bence Szabari
Bence Szabari

Reputation: 155

C pipe bad value from parent proccess

I have this simple program, but when I wanted to check the value that I get from the child it returns 1995694080 or similiar numbers. I'm a bit confused, how can I achieve to get the real value of msg? It looks like I'm getting some random trash value from somewhere else where I'm not supposed to. I made this pipe sendier based on a tutorial, and it's mostly works just when I'm sending back the data from the child it fails. Any idea or suggestion?

int pipefd[2];

int main()
{
    signal(SIGTERM, handler);
    signal(SIGUSR1, finishedOrder);
    pid_t pid;


    if (pipe(pipefd) == -1)
    {
        perror("Error while making pipe.\n");
        exit(1);
    }

    pid = fork();

    if (pid < 0)
    {
        perror("Fork error.\n");
        exit(1);
    }

    if (pid > 0)
    {
        employer(pid, 4, false);
    }
    else
    {
        employee(getppid());
    }
}

void employer(pid_t pid, int id, bool two)
{
    int rec;

    printf("[Szülő]: várok egy szerelő csapatra! \n");
    sleep(1);

    kill(pid, SIGTERM);

    pause();

    if (two)
    {
        /.../
    }
    else
    {
        printf("[Szülő]: dolgozz a %d. feladaton\n", id);
        close(pipefd[0]);
        write(pipefd[1], &id, sizeof(id)); //this is works.
        close(pipefd[1]);
        sleep(1);

        kill(pid, SIGTERM);

        pause();

        kill(pid, SIGTERM);
    }

    pause();

    close(pipefd[1]);
    read(pipefd[0], &rec, sizeof(rec));

    printf("%d\n", rec); // here I get the strange value

    if (rec == 4)
    {
        printf("[Szülő]: feljegyeztem a módosításokat.\n");
        if (two)
        {
            /**/
        }
        else
        {
            /**/
        }
    }

}

void employee(pid_t emp)
{
    int jobs[2];
    pause();

    printf("[Gyerek]: munkára jelentkezek\n");
    sleep(1);

    kill(emp, SIGTERM);

    pause();

    close(pipefd[1]);

    read(pipefd[0], &jobs[0], sizeof(jobs[0]));
    close(pipefd[0]);
    printf("[Gyerek]: elkezdek dolgozni a %d. feladaton.\n", jobs[0]);
    sleep(1);
    kill(emp, SIGUSR1);
    pause();

    sleep(1);
    read(pipefd[0], &jobs[1], sizeof(jobs[1]));


    if (jobs[1] != 0)
    {
        printf("[Gyerek]: elkezdek dolgozni a %d. feladaton.\n", jobs[1]);
        sleep(1);

        kill(emp, SIGUSR1);
    }

    close(pipefd[0]);
    fflush(NULL);
    int msg = 4;
    printf("%d\n", msg);
    write(pipefd[1], &msg, sizeof(msg));
    close(pipefd[1]);

    sleep(1);
    kill(emp, SIGTERM);
}

void handler(int signum)
{
}

void finishedOrder()
{
}

Upvotes: 1

Views: 181

Answers (2)

GandhiGandhi
GandhiGandhi

Reputation: 1350

In your employer() function, you close the read end of the pipe with close(pipefd[0]); then try to read from it later with read(pipefd[0], &rec, sizeof(rec));

Trying to read from a closed fd probably causes weird values. will do what Johnathan Leffler says it will do.

rustyx is right in the comments - checking the return value of read() is good idea, because it would uncover this kind of error.

Upvotes: 1

Chris Turner
Chris Turner

Reputation: 8142

read(pipefd[0], &rec, sizeof(rec));

You don't check the value returned by read to see how much data you've received. If you did, you'll probably find that it is not what you expect because earlier on in your code you did this...

    close(pipefd[0]);

You can't read from a file descriptor after you've closed it. And somewhat more importantly, the "pipe" you created isn't bi-directional. If you want to send and receive, you need to do two calls to pipe to get two pairs of file descriptors.

Given that you also do close(pipefd[1]) before the read which means that you've closed both ends of the pipe, it looks like you've misunderstood what the purpose of closeing is for in this context. The child and parent close the end of the pipe that they're not using - that's it. It doesn't signify anything about who is reading or writing to the pipe.

Upvotes: 4

Related Questions