2012-06-14 3 views
14

Я работаю с многопоточной программой.C восстановление stdout на терминал

Сначала я перенаправляю свой stdout в определенный файл. Там нет проблем (я использовал dup2(fd, 1), где fd является файловым дескриптором для файла).

После этого мне нужно снова перенаправить мой вывод на терминал.

Мой первый подход:

 /*Declaration*/ 
     fpost_t stream_sdout; 
     /*code*/ 
     if (fgetpos(stdout, &stream_sdout) == -1) 
      perror(Error:); 

Это говорит незаконным искать.
Не знаю, почему это происходит.
Но если я получу это для работы, тогда мне нужно использовать только fsetpos(stdout, &stream_stdout), и он должен работать.

Моя вторая идея состояла в том, чтобы скопировать stdout с помощью dup2(stdout, 4) в таблицу дескриптора файла в позиции 4. Но это тоже не работает.

Как переключить стандартный вывод обратно в исходное место назначения (терминал, труба, файл, что угодно)?

+0

У меня такое чувство, что попытка переместить 'stdout' вокруг, как это, вероятно, плохая идея. Какую позицию должен представлять отчет _terminal_ в' fgetpos() '? Почему бы просто не открыть файл и не вывести его с помощью 'fwrite()' или 'fprintf()' или 'write()' и вывести на терминал через '/ dev/tty', когда вам это нужно? – sarnold

+1

@sarnold: возможно, потому, что у программы есть библиотеки или другой неизменный код, который жестко связан с 'stdout'. – wallyk

+0

@sarnold я на самом деле не думал, что эта возможность. Позвольте мне быстро проверить. – Alessandroempire

ответ

21
#include <unistd.h> 

... 

int saved_stdout; 

... 

/* Save current stdout for use later */ 
saved_stdout = dup(1); 
dup2(my_temporary_stdout_fd, 1); 

... do some work on your new stdout ... 

/* Restore stdout */ 
dup2(saved_stdout, 1); 
close(saved_stdout); 
+2

Вы читали через плечо, когда я набрал? –

+0

Это очень помогло мне. Мне было интересно, но какова функция close (saved_stdout)? Я использовал close для закрытия файлов, но я еще не знаком с тем, как работает весь процесс функции dup. – ThinkBonobo

+1

@ThinkBonobo, 'saved_stdout' является дубликатом (следовательно, * dup() *) исходного дескриптора файла для исходного файла, лежащего в основе файла stdout программы. Когда он снова дублируется на (* dup2() *) stdout (дескриптор файла № 1), программа имеет две копии/дескрипторы/дескрипторы для одного и того же базового файла. Нет необходимости в этом, как только перенаправление вывода будет завершено (и это может привести к ограничению ресурсов или предположениям о блокировке файлов и т. Д.), Поэтому хорошей практикой является отказ от ресурса, когда он больше не нужен. – pilcrow

0

Если программа работает в среде Linux, вы можете freopen ("/dev/stdout", "a", stdout).

Но если вы знаете, что stdout был терминалом, freopen ("/dev/tty", "a", stdout) или эквивалентом для других ОС — даже Windows.

+1

Когда 'dup2()' работает, '/ dev/stdout' должен ссылаться на файл. Полагаю, вы переключили вывод из файла в файл. –

+0

@JonathanLeffler: Если он меняет «fd's around», это будет правда. Из его описания далеко не очевидно, что это то, что происходит. Кажется, он, возможно, меняет соединения FILE. – wallyk

+0

Поскольку он упоминает использование 'dup2()' для переключения стандартного вывода, мне кажется, что он возится с файловыми дескрипторами для начала. Код для сброса вещей в вопросе является странным, чем спасение; переписывается в порядке. Разумеется, это то, о чем должны знать ответы. –

6

Перед тем, как сделать dup2(fd, STDOUT_FILENO), вы должны сохранить текущий открытый дескриптор файла для стандартного вывода, делая int saved_stdout = dup(STDOUT_FILENO); (позволяя dup() выбрать доступный номер дескриптора файла для вас). Затем, после того, как вы закончите с выходом, перенаправленным в файл, вы можете сделать dup2(saved_stdout, STDOUT_FILENO), чтобы восстановить стандартный вывод до того места, где он был, прежде чем вы начали все это (и вы должны закрыть saved_stdout).

Вам нужно беспокоиться о потоке стандартных потоков ввода-вывода (fflush(stdout)) в подходящее время, когда вы обходитесь с этим. Это означает «перед тем, как вы переключаете stdout over».

+3

+1 для STDOUT_FILENO это делает его намного более удобочитаемым. –

Смежные вопросы