Subprocess doesn't get stdin sometimes.

Ilya Kazakevich <[email protected]>
Newsgroups org.kernel.vger.dash
Message-ID <CAMQsgbSZnEac=ETYnR6a_ysnAysaHThwY03pnoDxC=p5FqtAag@mail.gmail.com>
Hello,

I am not sure if it is a `dash` bug or my scenario isn't correct (it
works with `bash`, however).

I execute command that reads N bytes and send this bytes directly
after execution, i.e `head -c 2 \n ab`

Here is a showcase: it forks shell , sends data and reads output
```
#include <stdio.h>
#include <unistd.h>
#include <string.h>


static void child(int read_pipe, int write_pipe) {
    dup2(write_pipe, STDOUT_FILENO);
    dup2(read_pipe, STDIN_FILENO);
    execlp("/bin/bash", "/bin/bash", NULL);
}


static void parent(int read_pipe, int write_pipe) {
    char buf[] = "head -c 2\n";
    write(write_pipe, buf, sizeof buf - 1);

    char buf2[] = "ab\n";
    write(write_pipe, buf2, sizeof buf2 - 1);


    char answer[112] = {0};
    read(read_pipe, answer, sizeof answer);
    answer[sizeof answer - 1] = 0;
    printf("%s", answer);
}

int main() {
    int to_process[2];
    pipe(to_process);
    int to_process_read_pipe = to_process[0];
    int to_process_write_pipe = to_process[1];

    int from_process[2];
    pipe(from_process);
    int from_process_read_pipe = from_process[0];
    int from_process_write_pipe = from_process[1];


    if (fork() == 0) {
        close(from_process_read_pipe);
        close(to_process_write_pipe);
        child(to_process_read_pipe, from_process_write_pipe);
    } else {
        close(to_process_read_pipe);
        close(from_process_write_pipe);
        parent(from_process_read_pipe, to_process_write_pipe);
    }
}
```

It works perfectly for `bash`.

If I use `dash` -- it freezes. In `strace` I see that `dash` calls
`vfork` followed by `execve`.
`head` then calls `read` and waits forever.

However: when I insert `sleep(1);` after the first `write(..."head..)` it works!

It seems that we have a race condition here: I should have "waited"
before stdin got connected to the new child. If I write data too
early, it simply drops and never reaches the child.

A couple of questions:
1. Is it a bug or do I simply misuse shell? Should it work? I haven't
found any POSIX statement that confirms so.
2. I am curious: why use `vfork` nowadays? `bash` uses `close`.

Thank you.

Ilya.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.