The sending process can write until the pipe buffer is full (64k on Linux since 2.6.11). After that, write(2) will block.
The receiving process will block until data is available to read(2).
For a more detailed look into pipe buffering, look at https://unix.stackexchange.com/a/11954.
For example, this program
#include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, char *argv[]) { int pipefd[2]; pid_t cpid; char wbuf[32768]; char buf[16384]; /* Initialize writer buffer with 012...89 sequence */ for (int i = 0; i < sizeof(wbuf); i++) wbuf[i] = '0' + i % 10; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { /* Child reads from pipe */ close(pipefd[1]); /* Close unused write end */ while (read(pipefd[0], &buf, sizeof(buf)) > 0); close(pipefd[0]); _exit(EXIT_SUCCESS); } else { /* Parent writes sequence to pipe */ close(pipefd[0]); /* Close unused read end */ for (int i = 0; i < 5; i++) write(pipefd[1], wbuf, sizeof(wbuf)); close(pipefd[1]); /* Reader will see EOF */ wait(NULL); /* Wait for child */ exit(EXIT_SUCCESS); } }
will produce the following sequence when run with gcc pipes.c && strace -e trace=open,close,read,write,pipe,clone -f ./a.out:
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 close(3) = 0 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\3\2\0\0\0\0\0"..., 832) = 832 close(3) = 0 pipe([3, 4]) = 0 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f32117489d0) = 21114 close(3) = 0 write(4, "01234567890123456789012345678901"..., 32768) = 32768 write(4, "01234567890123456789012345678901"..., 32768) = 32768 write(4, "01234567890123456789012345678901"..., 32768strace: Process 21114 attached <unfinished ...> [pid 21114] close(4) = 0 [pid 21114] read(3, "01234567890123456789012345678901"..., 16384) = 16384 [pid 21114] read(3, <unfinished ...> [pid 21113] <... write resumed> ) = 32768 [pid 21114] <... read resumed> "45678901234567890123456789012345"..., 16384) = 16384 [pid 21113] write(4, "01234567890123456789012345678901"..., 32768 <unfinished ...> [pid 21114] read(3, "01234567890123456789012345678901"..., 16384) = 16384 [pid 21114] read(3, <unfinished ...> [pid 21113] <... write resumed> ) = 32768 [pid 21114] <... read resumed> "45678901234567890123456789012345"..., 16384) = 16384 [pid 21113] write(4, "01234567890123456789012345678901"..., 32768 <unfinished ...> [pid 21114] read(3, "01234567890123456789012345678901"..., 16384) = 16384 [pid 21114] read(3, <unfinished ...> [pid 21113] <... write resumed> ) = 32768 [pid 21114] <... read resumed> "45678901234567890123456789012345"..., 16384) = 16384 [pid 21113] close(4) = 0 [pid 21114] read(3, "01234567890123456789012345678901"..., 16384) = 16384 [pid 21114] read(3, "45678901234567890123456789012345"..., 16384) = 16384 [pid 21114] read(3, "01234567890123456789012345678901"..., 16384) = 16384 [pid 21114] read(3, "45678901234567890123456789012345"..., 16384) = 16384 [pid 21114] read(3, "", 16384) = 0 [pid 21114] close(3) = 0 [pid 21114] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21114, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++
You'll notice that the reads and writes are interleaved and that the writing and reading processes will block a few times as either the pipe is full or not enough data is available for reading.