mod_shell_stream: flush inherited stdio buffers in child before dup2 to stop console log leaking into the audio pipe - #3121
Open
asdf3309 wants to merge 1 commit into
Conversation
The child branch forks from the parent while FreeSWITCH console logs are still sitting in the block-buffered stdout FILE* stream. After dup2(fds[1], STDOUT_FILENO), switch_system() forks a grandchild that runs the shell command; when that grandchild exits, stdio flushes the inherited buffered console log text into the audio pipe, and the playback pump plays those log bytes as audio -- a pop/clip noise at the end of every shell_stream:// stream. Flush stdout/stderr in the child before dup2 so there is nothing buffered to leak into the pipe. Verified on 1.10.12: pipe no longer contains log text after stream data, RTP tail is silence. Fixes signalwire#3120
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes pop/clip noise at the end of every
shell_stream://playback (see #3120).The child branch forks from the parent while FreeSWITCH console logs (e.g. sofia's
hash(insert/...last_dial/...)notices) are still sitting in the block-buffered stdoutFILE*stream. The sequence:fprintf(runtime.console = stdout)buffers console log text, not flushed yetswitch_fork()— the child inherits a copy of the buffered datadup2(fds[1], STDOUT_FILENO)points stdout at the audio pipeswitch_system()forks a grandchild that runssystem(dcmd)(the audio source); when itexit(0)s, stdio flushes the inherited stdout buffer into the audio pipeThis patch flushes
stdout/stderrin the child before thedup2, so there is nothing buffered to leak into the pipe. The flush must happen beforedup2, otherwise the logs get flushed into the pipe.Type of Change
Related Issues
Fixes #3120
Testing
With a pure-silence repro (
shell_stream://sh -c "dd if=/dev/zero bs=24000 count=4"), the pipe previously contained 1,145 bytes of log text after the 96,000 bytes of stream data, e.g.:After the fix the pipe contains exactly the stream data, RTP capture shows a clean silence tail, and the audible pop is gone. Note this is a different failure mode than #3104 (blocking
wait()infile_open): that one is addressed separately.Note:
master'sprintf("EOF")sentinel and 1.10.12'sread()==0end-of-stream both leave the leak path intact; flushing in the child fixes the leak for both.