Reabrir descripciones de archivos stdout y stdin después de cerrarlos

Estoy escribiendo una función, que, dado un argumento, redirigirá el stdout a un archivo o lee el stdin de un archivo. Para hacer esto cierro el descriptor de archivo asociado con stdout o stdin, de modo que cuando abro el archivo se abre bajo el descriptor que acabo de cerrar. Esto funciona, pero el problema es que una vez hecho esto, necesito restaurar el stdout y el stdin a lo que realmente deberían ser.

Lo que puedo hacer por stdout está abierto (“/ dev / tty”, O_WRONLY); Pero no estoy seguro de por qué esto funciona, y más importante aún, no sé de una statement equivalente para stdin.

Así que lo hice, para stdout

close(1); if (creat(filePath, O_RDWR) == -1) { exit(1); } 

y para stdin

 close(0); if (open(filePath, O_RDONLY) == -1) { exit(1); } 

Debería usar dup () y dup2 () para clonar un descriptor de archivo.

 int stdin_copy = dup(0); int stdout_copy = dup(1); close(0); close(1); int file1 = open(...); int file2 = open(...); < do your work. file1 and file2 must be 0 and 1, because open always returns lowest unused fd > close(file1); close(file2); dup2(stdin_copy, 0); dup2(stdout_copy, 1); close(stdin_copy); close(stdout_copy); 

Sin embargo, hay un pequeño detalle con el que deberías tener cuidado (desde man dup):

Los dos descriptores no comparten banderas de descriptores de archivos (close-on-execflag). El indicador close-on-exec (FD_CLOEXEC; ver fcntl (2)) para el descriptor duplicado está desactivado.

Si esto es un problema, es posible que deba restaurar el indicador de cierre de ejecución, posiblemente utilizando dup3 () en lugar de dup2 () para evitar condiciones de carrera.

Además, tenga en cuenta que si su progtwig tiene múltiples subprocesos, es posible que otros subprocesos escriban / lean accidentalmente en su stdin / stdout reasignado.

Creo que puedes “guardar” los descriptores antes de redirigirlos :

 int save_in, save_out; save_in = dup(STDIN_FILENO); save_out = dup(STDOUT_FILENO); 

Más tarde puede usar dup2 para restaurarlos:

 /* Time passes, STDIN_FILENO isn't what it used to be. */ dup2(save_in, STDIN_FILENO); 

No estoy haciendo ningún error al verificar en ese ejemplo, deberías.

Puede crear un proceso hijo y configurar la redirección dentro del elemento secundario solamente. Luego espere a que el niño termine y continúe trabajando en el proceso principal. De esta forma, no tiene que preocuparse por revertir su redirección.

Solo busque ejemplos de código usando fork () y wait ().