Skip to content

Fix output pipe deadlock when pipe command output exceeds the socket buffer - #149

Open
pexaxep wants to merge 2 commits into
clicon:masterfrom
pexaxep:fix/pipe-output-deadlock
Open

pexaxep wants to merge 2 commits into
clicon:masterfrom
pexaxep:fix/pipe-output-deadlock

Conversation

@pexaxep

@pexaxep pexaxep commented Oct 19, 2026

Copy link
Copy Markdown

cmd | grep ... (any output pipe) hangs forever when the output of the pipe command is larger than the socket buffer (~200 KB with default net.core.wmem_default).

cligen_output() writes the whole command output to the pipe socketpair with a blocking write(), and the output of the pipe command (eg grep) is only read afterwards in cligen_eval_pipe_post(). If the pipe command produces more output than the socket buffer holds, it blocks in write() and stops reading its input. The input buffer then fills up and cligen_output() blocks as well: both sides wait for each other. Increasing the socket buffer only moves the threshold.

The fix writes to the pipe socket via a new pipe_socket_write() using select() and send(MSG_DONTWAIT | MSG_NOSIGNAL), and reads the pipe command output to stdout while the socket is not writable. The behaviour for small outputs is unchanged, and EPIPE when the pipe command closes its side is handled as before. cligen_eval_pipe_pre() and cligen_eval_pipe_post() are not modified.

Regression tests added to test_pipe.sh (big | grep abc and big | cat, ~1 MB of pipe command output). Without the fix the command hangs (the test times out), with the fix test_pipe.sh passes.

…et buffer

cligen_output wrote the whole command output to the pipe socketpair with a
blocking write(), and only read the pipe command (eg grep) output after the
command output was complete. If the pipe command produced more output than
fits in the socket buffer it blocked writing, stopped reading its input, and
both sides waited for each other forever.

Write with select/send and drain the pipe command output to stdout while
the socket is not writable.
test_pipe.sh: pipe command output (~1MB) larger than the socket buffer
must not deadlock with the writer.
@pexaxep
pexaxep force-pushed the fix/pipe-output-deadlock branch from 61794cf to fda2f90 Compare October 19, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant