Не гарантируется, что существует какой-либо способ повторно подключить stdin
к исходному файлу после переназначения его через freopen()
.В частности, не указано, расширяется ли макрос stdin
до модифицируемого lvalue, тем более что эффект, присваиваемый результату, имеет.Это на самом деле причина freopen()
во-первых.
Метод, который вы пытаетесь использовать, правдоподобен, но, опять же, не гарантированно сработает, и я наблюдаю то же поведение, которое вы описываете для себя.Возможно, ваша версия printf
и моя оптимизированы с идентификатором stdout
, так что присвоение нового значения этому символу не влияет на назначение вывода этой функции, которое вы закрываете перед печатью.
Вы используете интерфейсы POSIX (dup
и dup2
), и в реализации, соответствующей POSIX, наиболее вероятный подход к работе - избегать закрытия stdin
, а вместо этого переопределять файл, в который он записывает, с помощью dup2()
только.В этом случае вы должны быть осторожны с fflush()
перед таким обменом, что-то вроде этого:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void funcB() {
printf("this should be redirected\n");
fflush(stdout);
}
int main() {
int stdout_fd = dup(STDOUT_FILENO);
int rd_fileno = open("/tmp/redirected", O_WRONLY | O_CREAT | O_TRUNC, 0600);
dup2(rd_fileno, STDOUT_FILENO);
funcB();
fflush(stdout);
dup2(stdout_fd, STDOUT_FILENO);
close(stdout_fd);
printf("this shouldn't be redirected\n");
fflush(stdout); // shouldn't make a difference if this is here
}
Эта версия работает для меня и основана на той же основе, что и перенаправление, как правило, в POSIX.В частности, обратите внимание, что stdout
никогда не закрывается (за исключением автоматического завершения программы).