2011-10-22 13 views
17

So che dup, dup2, dup3 "crea una copia del descrittore di file oldfd" (dalle pagine man). Comunque non posso digerirlo.Qualcuno può spiegare cosa dup() in C fa?

Come so che i descrittori di file sono solo numeri per tenere traccia delle posizioni dei file e la loro direzione (input/output). Non sarebbe più semplice solo

fd=fd2; 

Ogni volta che vogliamo duplicare un descrittore di file?

E un'altra cosa ..

DUP() utilizza il descrittore inutilizzato numero più basso per il nuovo descrittore.

Questo significa che si può anche prendere come valore stdin, stdout o stderr Se assumiamo che abbiamo close() -ed uno di quelli?

+3

Per la prima domanda è necessario ricordare che il kernel tiene traccia del numero di aprire gli handle di file. 'dup' è il tuo modo di dire al kernel che vuoi tenere traccia di un altro di questi handle di file (riferendosi allo stesso file) finché non lo chiudi. – user786653

risposta

12

Volevo solo rispondere a me stesso sulla seconda domanda dopo aver sperimentato un po '.

La risposta è SI. Un descrittore di file che si crea può assumere un valore 0, 1, 2 se stdin, stdout o stderr sono chiusi.

Esempio:

close(1);  //closing stdout 
newfd=dup(1); //newfd takes value of least available fd number 

Dove questo accade a file descrittori:

0 stdin  .--------------.  0 stdin  .--------------.  0 stdin 
1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 
2 stderr '--------------'     '--------------'  2 stderr 
+1

Ancora una domanda: come posso 'dup()' un descrittore di file che ho già chiuso? – Pithikos

+0

Dalla definizione, dup() utilizza il descrittore inutilizzato con il numero più basso per il nuovo descrittore. E quando chiudi un descrittore di file, significa che è disponibile per l'uso. –

2

vedono questo page, stdout può essere alias come dup(1) ...

+0

+1. collegamento impressionante –

5

Diciamo che si sta scrivendo un programma di shell e si desidera reindirizzare stdin e stdout in un programma che si desidera eseguire. Potrebbe essere simile a questa:

fdin = open(infile, O_RDONLY); 
fdout = open(outfile, O_WRONLY); 
// Check for errors, send messages to stdout. 
... 
int pid = fork(0); 
if(pid == 0) { 
    close(0); 
    dup(fdin); 
    close(fdin); 
    close(1); 
    dup(fdout); 
    close(fdout); 
    execvp(program, argv); 
} 
// Parent process cleans up, maybe waits for child. 
... 

dup2() è un po 'più conveniente per farlo il DUP close()() può essere sostituito dal seguente:

dup2(fdin, 0); 
dup2(fdout, 1); 

Il motivo per cui si desidera per fare ciò è necessario segnalare gli errori a stdout (o stderr) in modo che non sia possibile chiuderli e aprire un nuovo file nel processo figlio. In secondo luogo, sarebbe uno spreco fare la forcella se la chiamata di open() ha restituito un errore.

9

Un descrittore di file è un po 'più di un numero. Contiene anche vari stati semi-nascosti con esso (se è aperto o meno, a quale descrizione del file si riferisce, e anche alcuni flag). dup duplica queste informazioni, quindi puoi ad es. chiudi i due descrittori in modo indipendente. fd=fd2 no.

+1

Questo. Il "numero" è un indice in una struttura di dati gestita dal kernel. La famiglia di funzioni 'dup' clona lo stato di un nodo in quella struttura dati e passa l'indice al nuovo nodo. – dmckee

+3

@dmckee: "Kernel" e "index" sono dettagli di implementazione. Alcuni dati sono associati a "il numero" che non può essere manipolato direttamente dal programma e che è clonato da 'dup()'. Questo è tutto ciò che il programmatore deve sapere. A proposito, non è una parte di dati molto interessante, sono solo un paio di flag e un indice per i dati veramente interessanti (la descrizione del file aperto) che è ** non ** clonata da 'dup()'. –

5

La cosa più importante circa DUP() è restituisce il più piccolo intero a disposizione per un nuovo descrittore di file.Questa è la base di reindirizzamento:

int fd_redirect_to = open("file", O_CREAT); 
close(1); /* stdout */ 
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */ 
close(fd_redirect_to); /* we don't need this */ 

Dopo questo qualsiasi cosa scritta nel descrittore di file 1 (stdout), va magicamente in "file".

+0

Assumendo (non irragionevolmente) che il descrittore di file 0 sia attualmente aperto. Il supporto per i reindirizzamenti come '200> somefile' è molto scomodo senza' dup2() '(o' dup3() ', ma questa è una recente aggiunta ai sistemi). –

0

Solo un suggerimento su "duplicazione dell'output standard".

su alcuni sistemi Unix (ma non GNU/Linux)

fd = open("/dev/fd/1", O_WRONLY); 

è equivalente a:

fd = dup(1); 
Problemi correlati