scdmb scdmb - 1 month ago 5x
Bash Question

Sending data to stdin of another process waiting on ppoll

There is following code:

#include <poll.h>

int main(int argc, char *argv[])
pollfd pd;
pd.fd = 0; = POLLIN;
int ret = ::ppoll(&pd, 1, 0, 0);
return 0;

This should wait for some data on stdin and wake up when data appears.

Running program this way, it seems that ppoll is woken up (passing data to stdin via a pipe):

$ echo 1 | ./main

However sending something to the process from another shell doesn't wake up ppoll:

First shell:

$ ./main

Second shell:

$ echo 1 > /proc/$(pgrep main)/fd/0

After that I just see that in the first shell there is printed
, but ppoll doesn't wake up. How to send data correctly to a process's stdin from another shell so ppoll will wake up?


That's simply impossible, unless the process was specially launched in a way that enables feeding data to it from outside (i.e. through a FIFO or a pipe).

Even though /proc/$PID/fd/0 (i.e. standard input stream) points to the process's controlling terminal, so do (in the absence of redirection) /proc/$PID/fd/1 and /proc/$PID/fd/2 (i.e. standard output and standard error streams):

$ ls -l /proc/$$/fd
lrwx------ 1 user user 64 Sep  6 01:36 0 -> /dev/pts/3
lrwx------ 1 user user 64 Sep  6 01:36 1 -> /dev/pts/3
lrwx------ 1 user user 64 Sep  6 01:36 2 -> /dev/pts/3

The terminal is a pseudo-device, that can be both read from and written to. When a process reads from it, the terminal provides data entered from the keyboard or by other means (e.g. pasted from the clipboard). When you write to a terminal, it displays the data. Now when you write to /proc/$PID/fd/0 you write to the terminal rather than to the target process's standard input stream, that's why your data is displayed but the process stays indifferent.