Loading src/shell.cpp +20 −0 Changes for src/shell.cpp: 20 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2879,6 +2879,26 @@ int fresh::Shell::runSegmentWords(const std::string &input,const std::vector<She status=parse(body); } // Flush BEFORE restoring the real fds below: std::cout/cerr's // own userspace buffering can still be holding output the // group's own commands already wrote (fd 1/2 themselves // already point at the redirected target above, but a // buffered iostream write only actually reaches whatever fd 1/ // 2 point to AT FLUSH TIME) -- without this, that output // surfaces later instead, once something ELSE finally flushes // it, by which point the dup2() calls just below have already // put the ORIGINAL fds back, sending it to the wrong place // entirely (confirmed directly: kbuild's own "{ $(filechk_... // ); } > $(tmp-target)" pattern, used by every scripts/ // Kbuild.include filechk-generated header, otherwise printed // the generated content to the terminal instead of writing it // into the tmp file at all). Same hazard runCaptured()'s own // pre-fork flush and runPipeline()'s per-stage fork already // guard against, just without a fork here to also copy the // unflushed buffer contents into two places at once. std::cout.flush(); std::cerr.flush(); if(savedStdin>=0){ dup2(savedStdin,0); close(savedStdin); } if(savedStdout>=0){ dup2(savedStdout,1); close(savedStdout); } if(savedStderr>=0){ dup2(savedStderr,2); close(savedStderr); } Loading Loading
src/shell.cpp +20 −0 Changes for src/shell.cpp: 20 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2879,6 +2879,26 @@ int fresh::Shell::runSegmentWords(const std::string &input,const std::vector<She status=parse(body); } // Flush BEFORE restoring the real fds below: std::cout/cerr's // own userspace buffering can still be holding output the // group's own commands already wrote (fd 1/2 themselves // already point at the redirected target above, but a // buffered iostream write only actually reaches whatever fd 1/ // 2 point to AT FLUSH TIME) -- without this, that output // surfaces later instead, once something ELSE finally flushes // it, by which point the dup2() calls just below have already // put the ORIGINAL fds back, sending it to the wrong place // entirely (confirmed directly: kbuild's own "{ $(filechk_... // ); } > $(tmp-target)" pattern, used by every scripts/ // Kbuild.include filechk-generated header, otherwise printed // the generated content to the terminal instead of writing it // into the tmp file at all). Same hazard runCaptured()'s own // pre-fork flush and runPipeline()'s per-stage fork already // guard against, just without a fork here to also copy the // unflushed buffer contents into two places at once. std::cout.flush(); std::cerr.flush(); if(savedStdin>=0){ dup2(savedStdin,0); close(savedStdin); } if(savedStdout>=0){ dup2(savedStdout,1); close(savedStdout); } if(savedStderr>=0){ dup2(savedStderr,2); close(savedStderr); } Loading