Я изучил пару вещей, продолжая исследовать эту проблему, и я думаю, что ответ на мой вопрос:
По существу: да, безопасно fread
из FILE*
, возвращенного popen
до pclose
. Предполагая, что буфер, заданный для fread
, достаточно велик, вы не пропустите вывод, сгенерированный command
, переданным popen
.
Возвращаясь назад и тщательно обдумывая, что делает fread
: он эффективно блокирует, пока (size
* nmemb
) байтов не будет прочитано или не будет обнаружен конец файла (или ошибка).
Благодаря C - трубе без использования popen , я лучше понимаю, что popen
делает под капотом: он делает dup2
, чтобы перенаправить его stdout
на конец записи канала оно использует. Важно: он выполняет некоторую форму exec
для выполнения указанного command
в разветвленном процессе, , и после завершения этого дочернего процесса дескрипторы его открытых файлов, включая 1
(stdout
), закрываются . То есть завершение указанного command
- это условие, при котором дочерний процесс 'stdout
закрывается.
Затем я вернулся и подумал, что на самом деле EOF
в этом контексте. Вначале у меня возникло ошибочное и ошибочное впечатление, что «fread
пытается читать из FILE*
так быстро, как может, и возвращает / разблокирует после считывания последнего байта ». Это не совсем так: как отмечалось выше: fread
будет считывать / блокировать до тех пор, пока не будет прочитано целевое число байтов или пока не будет обнаружена EOF
или ошибка. FILE*
, возвращаемое popen
, происходит от fdopen
конца чтения канала, используемого popen
, поэтому его EOF
происходит, когда дочерний процесс 'stdout
- который был dup2
ed с записью конца трубы - закрыто .
Итак, в итоге мы имеем: popen
создание канала, конец записи которого получает выходные данные дочернего процесса, выполняющего указанный command
, и конец чтения которого, если fdopen
преобразовано в FILE*
передано fread
. (Предполагая, что буфер fread
достаточно большой), fread
будет блокироваться до тех пор, пока не произойдет EOF
, что соответствует закрытию конца записи канала popen
в результате завершения выполнения command
. То есть поскольку fread
блокируется до тех пор, пока не встретится EOF
, а EOF
не произойдет после command
- выполнение в дочернем процессе popen
- завершится, можно использовать fread (с достаточно большим буфером) для захвата полный вывод command
, переданного popen
.
Благодарен, если кто-нибудь может проверить мои выводы и выводы.