Domanda

dup / dup2 fa, ma ho nessuna idea di quando sarebbe stato utilizzato.

Qualsiasi esempi pratici?

Grazie.

È stato utile?

Soluzione

Un esempio potrebbe essere l'uso redirezione I / O. Per questo fork di un processo figlio e aver chiuso i descrittori di file stdin o stdout (0 e 1) e poi si fa un DUP () su un altro filedescriptor a tua scelta che sarà ora associato al più basso descrittore di file disponibile, che è in questo caso 0 o 1.

Con questo è ora possibile exec qualsiasi processo figlio che è forse a conoscenza della vostra applicazione e ogni volta che il bambino scrive sul stdout (o legge da stdin, qualunque sia configurato) i dati viene scritto sul descrittore di file fornito invece.

Conchiglie utilizzano per implementare comandi con tubi, ad esempio /bin/ls | more collegando lo stdout di un processo per la stdin dell'altro.

Altri suggerimenti

Lo scenario migliore per capire DUP e dup2 è reindirizzamento.
La prima cosa che dobbiamo sapere è che il sistema ha 3 ids di file di default (o variabili che indicano le fonti di uscita o di ingresso) che si occupa di ingresso e uscita. Sono stdin, stdout, stderr, in interi sono 0, 1, 2. La maggior parte delle funzioni come fprintf o cout sono direttamente uscita stdout.
Se vogliamo reindirizzare l'output, un modo è dare, per esempio, fprintf funzionano più argomenti che indicano in e out.
Tuttavia, c'è un modo più elegante: siamo in grado di sovrascrivere gli ID di file predefiniti per renderli punta al file che vogliamo ricevere l'output. dup e dup2 esattamente lavorare in questa situazione.
Cominciamo con un semplice esempio ora: supponiamo di voler reindirizzare l'output di fprintf in un file txt denominato "chinaisbetter.txt". Prima di tutto abbiamo bisogno di aprire questo file

int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);

Poi vogliamo stdout per puntare a "chinaisbetter.txt" utilizzando la funzione DUP:

dup2(fw,1);

Ora stdout (1) indica il descrittore di "chinaisbetter.txt" anche se è ancora 1, ma l'output viene reindirizzato ora.
Quindi è possibile utilizzare printf come normale, ma i risultati saranno nel file txt invece di mostrare direttamente sullo schermo:

printf("Are you kidding me? \n");

PS :

  1. Questo dà solo una spiegazione intuitiva, può essere necessario controllare la pagina di manuale o di informazioni dettagliate. In realtà, noi diciamo "copia" qui, non stanno copiando tutto.

  2. Il file id qui si riferisce al gestore del file. Il descrittore di file di cui sopra è una struct le informazioni del file di record.

Quando si è curiosi di sapere funzioni POSIX, specialmente quelli che sembrano per duplicare se stessi, è generalmente buona a selezionare la norma stessa . Al fondo di solito vedere esempi, così come il ragionamento dietro l'attuazione (e l'esistenza) di entrambi.

In questo caso:

Le sezioni che seguono sono informative.

Esempi

reindirizzare l'output standard di un file

Il seguente esempio chiude uscita standard per gli attuali processi, ri-assegna uscita standard per andare al file indicato da pfd, e chiude il descrittore di file originale per ripulire.

#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...

Reindirizzamento dei messaggi di errore

L'esempio seguente reindirizza i messaggi da stderr a stdout.

#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...

Utilizzo Application

Nessuno.

Motivazioni

Le funzioni dup() e dup2() sono ridondanti. I loro servizi sono forniti anche dalla funzione fcntl(). Sono stati inclusi in questo volume di IEEE Std 1003.1-2001 principalmente per ragioni storiche, dal momento che molte applicazioni esistenti li usano.

Mentre il segmento di codice breve mostrata è molto simile nel comportamento a dup2(), un conforme attuazione basato su altre funzioni definite in questo volume di IEEE Std 1003.1-2001 è molto più complessa. Almeno evidente è il possibile effetto di una funzione segnale cattura che potrebbe essere invocata tra gradini e allocare o deallocare descrittori di file. Questo potrebbe essere evitato bloccando i segnali.

La funzione dup2() non è contrassegnato obsolescenza perché presenta una versione dai tipi di funzionalità fornita in una versione tipo non sicuri fcntl(). E 'utilizzato in associazione POSIX Ada.

La funzione dup2() non è destinato all'uso in regioni critiche come un meccanismo di sincronizzazione.

Nella descrizione di [EBADF], il caso di fildes essendo fuori range è incluso caso proposta di fildes non essere valido. Le descrizioni per fildes e fildes2 sono diversi perché l'unico tipo di invalidità che è rilevante per fildes2 è se è fuori portata; cioè, non importa se fildes2 fa riferimento a un file aperto quando la chiamata viene effettuata dup2().

Direzioni future

Nessuno.

Vedere anche

close(), fcntl(), open(), il volume Base Definitions di IEEE Std 1003.1-2001, <unistd.h>

Cronologia delle modifiche

La prima volta nel Problema 1. Derivato dal numero 1 del SVID.

Un esempio pratico è il reindirizzamento messaggi di output a qualche altro flusso come un file di log. Ecco un codice di esempio per il reindirizzamento I / O.
Si prega di fare riferimento al post originale qui

#include <stdio.h>

main()
{
    int    fd;
    fpos_t pos;

    printf("stdout, ");

    fflush(stdout);
    fgetpos(stdout, &pos);
    fd = dup(fileno(stdout));
    freopen("stdout.out", "w", stdout);

    f();

    fflush(stdout);
    dup2(fd, fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);        /* for C9X */

    printf("stdout again\n");
}

f()
{
printf("stdout in f()");
}

redirezione I / O nel guscio sarebbe molto probabilmente essere implementato utilizzando chiamate di sistema dup2 / fcnlt.

Si può facilmente emulare il tipo $program 2>&1 > logfile.log di reindirizzamento usando la funzione dup2.

Il programma di seguito reindirizza sia stdout e stderr .i.e emula il comportamento del $program 2>&1 > output utilizzando il dup2.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int
main(void){
    int close_this_fd;
    dup2(close_this_fd = open("output", O_WRONLY), 1);
    dup2(1,2);
    close(close_this_fd);
    fprintf(stdout, "standard output\n");
    fprintf(stderr, "standard error\n");
    fflush(stdout);
    sleep(100); //sleep to examine the filedes in /proc/pid/fd level.
    return;
}

vagrant@precise64:/vagrant/advC$ ./a.out
^Z
[2]+  Stopped                 ./a.out
vagrant@precise64:/vagrant/advC$ cat output
standard error
standard output
vagrant@precise64:/vagrant/advC$ ll /proc/2761/fd
total 0
dr-x------ 2 vagrant vagrant  0 Jun 20 22:07 ./
dr-xr-xr-x 8 vagrant vagrant  0 Jun 20 22:07 ../
lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top