Sto scrivendo una funzione, che, dato un argomento, reindirizzerà lo stdout a un file o leggerà lo stdin da un file. Per fare questo chiudo il descrittore di file associato allo stdout o allo stdin, in modo che quando apro il file si apra sotto il descrittore che ho appena chiuso. Funziona, ma il problema è che una volta fatto questo, ho bisogno di ripristinare lo stdout e lo stdin su cosa dovrebbero essere realmente.
Quello che posso fare per stdout è aperto (“/ dev / tty”, O_WRONLY); Ma non sono sicuro del perché funzioni e, cosa più importante, non so di una dichiarazione equivalente per stdin.
Quindi ho, per stdout
close(1); if (creat(filePath, O_RDWR) == -1) { exit(1); }
e per stdin
close(0); if (open(filePath, O_RDONLY) == -1) { exit(1); }
Dovresti usare dup () e dup2 () per clonare un descrittore di file.
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);
Tuttavia, c’è un piccolo dettaglio che potresti voler fare attenzione (da man dup):
I due descrittori non condividono i flag dei descrittori di file (il close-on-execflag). Il flag close-on-exec (FD_CLOEXEC; vedi fcntl (2)) per il descrittore duplicato è distriggersto.
Se questo è un problema, potresti dover ripristinare il flag close-on-exec, possibilmente usando dup3 () invece di dup2 () per evitare condizioni di competizione.
Inoltre, tieni presente che se il tuo programma è multi-thread, altri thread potrebbero accidentalmente scrivere / leggere sul tuo rimappato stdin / stdout.
Penso che puoi “salvare” i descrittori prima di redirect :
int save_in, save_out; save_in = dup(STDIN_FILENO); save_out = dup(STDOUT_FILENO);
In seguito puoi usare dup2
per ripristinarli:
/* Time passes, STDIN_FILENO isn't what it used to be. */ dup2(save_in, STDIN_FILENO);
Non sto facendo alcun controllo degli errori in quell’esempio, dovresti.
È ansible creare un processo figlio e impostare il reindirizzamento solo all’interno del figlio. Quindi attendi che il bambino termini e continua a lavorare nel processo genitore. In questo modo non devi preoccuparti di invertire il tuo reindirizzamento.
Cerca solo esempi di codice usando fork () e wait ().