Перенаправление stdin и stdout в C
я хочу открыть stdin и stdout (и, возможно,stderr пока я на нем) filehandles, так что будущие вызовы printf() или putchar() или puts() будет идти в файл, и будущие вызовы getc() и такие будут исходить из файла.
1) я не хочу постоянно терять стандартный ввод/вывод/ошибку. Возможно, я захочу использовать их позже в программе.
2) я не хочу открывать новые файловые хэндлы, потому что эти файловые хэндлы должны быть либо переданы много или глобально (содрогание).
3) я не хочу использовать любой open() или fork() или другие зависящие от системы функции, если я не могу помочь ему.
так что в принципе, это работает для этого:
stdin = fopen("newin", "r");
и, если это так, как я могу получить исходное значение stdin обратно? Я должен хранить его в FILE * и просто вернуть его позже?
8 ответов:
зачем использовать
freopen()? Спецификация C89 имеет ответ в одной из концевых сносок для раздела на<stdio.h>:116. Основное использование
freopenфункция заключается в изменении файла, связанного со стандартом текстовая трансляция (stderr,stdinилиstdout), поскольку эти идентификаторы не должны быть изменяемые значения, к которым относится значение возвращаемыхfopen
Я думаю, что вы ищете что-то вроде
freopen()
Это модифицированная версия метода Тима поста; я использовал /dev /tty вместо/dev / stdout. Я не знаю, почему это не работает с stdout (это ссылка на /proc / self/fd / 1):
freopen("log.txt","w",stdout); ... ... freopen("/dev/tty","w",stdout);С помощью /dev / tty вывод перенаправляется на терминал, с которого было запущено приложение.
надеюсь, что эта информация полезна.
функции ОС dup2() должны обеспечить то, что вам нужно (если не ссылки на то, что именно вам нужно).
более конкретно, вы можете dup2() файловый дескриптор stdin в другой файловый дескриптор, делать другие вещи с stdin, а затем скопировать его обратно, когда вы хотите.
функция dup () дублирует открытый файловый дескриптор. В частности, он предоставляет альтернативный интерфейс для службы, предоставляемой функцией fcntl () с помощью Значение постоянной команды F_DUPFD, с 0 в качестве третьего аргумента. Дублированный файловый дескриптор совместно использует все блокировки с оригиналом.
при успешном выполнении dup () возвращает новый файловый дескриптор, который имеет следующее общее с оригиналом:
- тот же открытый файл (или труба)
- один и тот же указатель на файл (оба дескриптора файлов имеют один указатель на файл)
- же режим доступа (чтение, запись или чтение/запись)
freopen("/my/newstdin", "r", stdin); freopen("/my/newstdout", "w", stdout); freopen("/my/newstderr", "w", stderr); ... do your stuff freopen("/dev/stdin", "r", stdin); ... ...это пики иглы на моем круглом-колышек-квадрат-отверстие-о-метр, что вы пытаетесь достичь?
Edit:
помните, что stdin, stdout и stderr являются файловыми дескрипторами 0, 1 и 2 для каждого вновь созданного процесса. freopen () должен сохранять те же fd, просто назначать им новые потоки.
Итак, хороший способ убедиться, что это на самом деле делает то, что вы хотите, чтобы это было:
printf("Stdout is descriptor %d\n", fileno(stdout)); freopen("/tmp/newstdout", "w", stdout); printf("Stdout is now /tmp/newstdout and hopefully still fd %d\n", fileno(stdout)); freopen("/dev/stdout", "w", stdout); printf("Now we put it back, hopefully its still fd %d\n", fileno(stdout));Я считаю, что это ожидаемое поведение freopen (), как вы можете видеть, вы все еще используете только три файловых дескриптора (и связанные потоки).
это переопределит любое перенаправление оболочки, так как для перенаправления оболочки не будет ничего. Тем не менее, его, вероятно, собирается сломать трубы. Возможно, вы хотите быть уверены, чтобы создать обработчик на сигнал sigpipe, в случае, если ваша программа находит себя на блокирование конец трубы (не ФИФО, трубы).
Так, ./your_program --стандартный вывод в /tmp/вывода.txt --stderr / tmp / stderr.txt должен быть легко выполнен с freopen () и сохранением тех же фактических файловых дескрипторов. То, что я не понимаю, почему вам нужно будет положить их обратно, как только вы их измените? Конечно, если бы кто-то передал любой вариант, они хотели бы, чтобы он сохранялся до завершения программы?
freopenрешает легко. Сохранение старого stdin не сложно, если вы ничего не читали, и если вы готовы использовать системные вызовы POSIX, такие какdupилиdup2. Если вы начали читать из него, все ставки выключены.может быть, вы можете сказать нам контекст, в котором возникает эта проблема?
Я бы посоветовал вам придерживаться ситуаций, когда вы готовы отказаться от старого
stdinиstdoutи поэтому может использоватьfreopen.
а тем временем, есть библиотека исходного кода C, которая будет делать все это для вас, перенаправляя stdout или stderr. Но самое интересное, что он позволяет назначать столько функций обратного вызова, сколько вы хотите для перехваченных потоков, что позволяет вам очень легко отправлять одно сообщение в несколько мест назначения, БД, текстовый файл и т. д.
кроме того, это делает его тривиальным для создания новых потоков, которые выглядят и ведут себя так же, как stdout и stderr, где вы можете перенаправить их новые потоки в нескольких местах, а также.
ищите библиотеку U-Streams C на *oogle.
Comments