2012-06-14 32 views
14

Estoy trabajando con un programa de hilos múltiples.C restaurar stdout al terminal

Primero redirijo mi stdout a un determinado archivo. No hay problema allí (utilicé dup2(fd, 1) donde fd es el descriptor de archivo para el archivo).

Después, necesito redirigir mi stdout a la terminal de nuevo.

Mi primer acercamiento:

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

Dice ilegales buscan.
No tengo idea de por qué sucede esto.
Pero si logro que esto funcione, entonces solo necesito usar fsetpos(stdout, &stream_stdout) y debería funcionar.

Mi segunda idea fue copiar el stdout usando dup2(stdout, 4) en la tabla de descriptores de archivos, en la posición 4. Pero eso tampoco funciona.

¿Cómo puedo devolver la salida estándar a su destino original (terminal, tubería, archivo, lo que sea)?

+0

Tengo la sensación de que intentar mover 'stdout' de esta forma probablemente sea una mala idea, ¿qué posición debería exactamente informar el _terminal_ en' fgetpos() '? ¿Por qué no simplemente abrir un archivo y enviarlo usando 'fwrite()' o 'fprintf()' o 'write()' y salir al terminal a través de '/ dev/tty' cuando lo necesite? – sarnold

+1

@sarnold: probablemente porque el programa tiene bibliotecas u otro código inalterable que están cableados a 'stdout'. – wallyk

+0

@sarnold en realidad no pensé en esa posibilidad. Déjame revisar rápidamente. – Alessandroempire

Respuesta

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

¿Estabas leyendo por encima de mi hombro mientras escribía? –

+0

Esto realmente me ayudó mucho. Sin embargo, me preguntaba ¿cuál es la función de close (saved_stdout)? He usado close para cerrar archivos, pero todavía no estoy familiarizado con el funcionamiento del proceso de función de dúplex completo. – ThinkBonobo

+1

@ThinkBonobo, 'saved_stdout' es un duplicado (por lo tanto, * dup() *) del descriptor de archivo original para el archivo original que subyace al stdout del programa. Cuando se duplica nuevamente a (* dup2() *) stdout (descriptor de archivo n. ° 1), el programa tiene dos copias/identificadores/descriptores para el mismo archivo subyacente. No es necesario hacerlo una vez que la redirección de salida haya finalizado (y puede confundir los límites de recursos o las suposiciones sobre bloqueos de archivos, etc.), por lo que una buena práctica es descartar el recurso cuando ya no sea necesario. – pilcrow

0

Si el programa se ejecuta en un entorno Linux, puede freopen ("/dev/stdout", "a", stdout).

Pero si sabe que stdout fue el terminal, freopen ("/dev/tty", "a", stdout) o el equivalente para otros sistemas operativos — incluso Windows.

+1

Cuando el 'dup2()' funciona, '/ dev/stdout' debe hacer referencia al archivo. Creo que cambiaste el resultado del archivo al archivo. –

+0

@JonathanLeffler: Si está cambiando el 'fd's, eso sería cierto. Está lejos de ser evidente por su descripción que es lo que está sucediendo. Parece que podría estar cambiando las conexiones FILE en su lugar. – wallyk

+0

Dado que él menciona el uso de 'dup2()' para cambiar la salida estándar, me parece que está jugando con descriptores de archivos para comenzar. El código para restablecer las cosas en la pregunta es extraño más allá del rescate; una reescritura está en orden. Pero de eso se tratan las respuestas, por supuesto. –

6

Antes de hacer la dup2(fd, STDOUT_FILENO), debe guardar el descriptor de archivo abierto actual de la salida estándar al hacer int saved_stdout = dup(STDOUT_FILENO); (dejando dup() elegir un número de descriptor de archivo disponible para usted). Luego, después de que haya terminado con la salida redirigida a un archivo, puede hacer dup2(saved_stdout, STDOUT_FILENO) para restaurar la salida estándar a donde estaba antes de comenzar todo esto (y también debe cerrar saved_stdout).

No tiene que preocuparse por el flujo de las transmisiones de E/S estándar (fflush(stdout)) en los momentos oportunos, ya que se pierde la vida con esto. Eso significa 'antes de cambiar la salida estándar'.

+3

+1 para STDOUT_FILENO lo hace mucho más legible. –

Cuestiones relacionadas