2012-10-02 6 views
7

Questo può sembrare una domanda strana, ma quando vado e aprire un file:Quante informazioni sono effettivamente memorizzate in un descrittore di file?

int fd; 
fd = open("/dev/somedevice", O_RDWR); 

Che cosa sono io tornare? Vedo la pagina man:
The open() function shall return a file descriptor for the named file that is the lowest file descriptor not currently open for that process

Ma è così? È solo uno int o ci sono dati allegati dietro le quinte? Il motivo che mi chiedo è che ho trovato un po 'di codice (Linux/C), dove stiamo aprendo il file dallo spazio utente:

//User space code: 
int fdC; 

if ((fdC = open(DEVICE, O_RDWR)) < 0) { 
    printf("Error opening device %s (%s)\n", DEVICE, strerror(errno)); 
    goto error_exit; 
} 
while (!fQuit) { 
    if ((nRet = read(fdC, &rx_message, 1)) > 0) { 

poi alla fine del kernel, le operazioni sui file per questo modulo (che fornisce il fd) mappa legge alla funzione n_read():

struct file_operations can_fops = { 
    owner:  THIS_MODULE, 
    lseek: NULL, 
    read: n_read, 

Poi il descrittore di file è utilizzato nel n_read(), ma è in corso l'accesso per ottenere i dati:

int n_read(struct file *file, char *buffer, size_t count, loff_t *loff) 
{ 
    data_t * dev; 

    dev = (data_t*)file->private_data; 

Allora ... ho Fi gura cosa sta succedendo qui è uno:

A) un descrittore di file restituito da open() contiene più dati rispetto a solo un valore intero descrittiva
O
B) La mappatura tra una chiamata di "leggere" nel isn spazio utente' t semplice come lo sto rendendo e c'è del codice mancante in questa equazione.

Qualsiasi input che potrebbe aiutarmi a orientarmi?

+1

Dove viene dichiarato 'fQuit'? E sì i descrittori di file sono solo numeri interi. Qualsiasi informazione su di essi deve essere ottenuta con una chiamata di sistema dalla tabella dei descrittori del file del kernel. –

+0

@ user1700513 - si può presupporre che 'fQuite' sia 0. – Mike

risposta

10

Il descrittore di file è solo un int. Il kernel lo usa come indice per una tabella che contiene tutte le informazioni correlate, tra cui la posizione del file, i file op (funzioni del kernel che forniscono le soglie read(), write(), mmap() ecc.) E così via.

Quando si carica un file o un dispositivo, il kernel crea una nuova voce descrittore del file per il processo e popola i dati interni, incluse le operazioni sui file.

Quando si utilizza read(), write(), mmap(), ecc, con un descrittore di file valido, il kernel semplicemente cerca il corretto funzionamento in-kernel per chiamata in base alle ops file nella tabella descrittore di file che ha (e che la indici dei descrittori di file). E 'davvero così semplice.

+0

Grazie, bella spiegazione semplice ... Penso che stavo solo cercando di complicare troppo questo per me stesso. :) – Mike

1

Penso che sia solo un int. Da Wikipedia:

In generale, un descrittore di file è un indice per una voce in una struttura dati kernel residente che contiene i dettagli di tutti i file aperti. In POSIX questa struttura dati è chiamata tabella descrittore di file e ogni processo ha una propria tabella descrittore di file.

3

In aggiunta alla buona risposta esistente da @Nominal Aminal è un numero intero ma punta a una voce di una struttura nel kernel chiamata tabella dei descrittori di file. Questo è almeno il caso di Linux. Tra i diversi campi che fanno parte di quel struct, un interessante è:

FILE * pointer; // descriptor to/from reference counts etc. 

potreste essere interessati a seguire API che dato uno dei FILE * o descrittore, restituite l'altra

How to obtain FILE * from fd and vice versa

+0

' tabella descrittore file', 'tabella file aperto di sistema': http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic =/com.ibm.aix.genprogc/doc/genprogc/fdescript.htm – n611x007

+0

** Strutture dati del kernel per file aperti **: http://www.cim.mcgill.ca/~franco/OpSys-304-427/ lecture-notes/node27.html – n611x007

+0

Questo è completamente errato. In Linux, il 'FILE *' usato dagli I/O standard (e 'fileno()' e 'fdopen()') non ha nulla a che fare con il kernel ['struct file'] (https: //git.kernel. org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/fs.h # n879), tranne forse una somiglianza di passaggio nel nome. –