2012-10-02 33 views
7

Esto puede sonar como una pregunta extraña, pero cuando voy y abrir un archivo:¿Cuánta información se almacena realmente en un descriptor de archivo?

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

¿Qué es exactamente estoy volviendo? Puedo ver que la página del manual dice:
The open() function shall return a file descriptor for the named file that is the lowest file descriptor not currently open for that process

¿Pero es eso? ¿Es solo un int o hay datos adjuntos detrás de las escenas? La razón por la que estoy pidiendo es que encontré algo de código (Linux/C), donde estamos abriendo el archivo desde el espacio de usuario:

//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) { 

continuación, en el extremo del núcleo, las operaciones de archivo para este módulo (que suministra el fd) mapa que dice a la función n_read():

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

a continuación, el descriptor de archivo se utiliza en el n_read(), pero se está accediendo a obtener datos:

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

    dev = (data_t*)file->private_data; 

Así que ... FI gura lo que está sucediendo aquí es ya sea:

A) un descriptor de archivo devuelto desde open() contiene más datos que sólo un valor entero descriptiva
O
B) La asignación entre una llamada a "leer" en el espacio de usuario ISN' Es tan simple como lo estoy haciendo y hay un código que falta en esta ecuación.

¿Alguna entrada que pueda ayudarme a dirigir?

+1

¿Dónde se declara 'fQuit'? Y sí, los descriptores de archivos son solo enteros. Cualquier información sobre ellos debe obtenerse con una llamada al sistema desde la tabla de descriptores de archivos del kernel. –

+0

@ user1700513 - puede suponer que 'fQuite' es 0. – Mike

Respuesta

10

El descriptor de archivo es solo int. El núcleo lo usa como un índice de una tabla que contiene toda la información relacionada, incluida la posición del archivo, las operaciones de archivo (funciones del kernel que proporcionan las llamadas a los sistemas read(), write(), mmap() etc.), y así sucesivamente.

Cuando open() un archivo o dispositivo, el kernel crea una nueva entrada de descriptor de archivo para su proceso, y rellena los datos internos, incluidos los archivos ops.

Cuando se utiliza read(), write(), mmap(), etc, con un descriptor de archivo válido, el kernel simplemente busca la correcta función en el núcleo de llamadas en base a las operaciones de archivo de la tabla de descriptores de archivos que tiene (y que la índices de descriptores de archivos). Es realmente así de simple.

+0

Gracias, buena explicación simple ... Creo que estaba tratando de complicar esto por mi cuenta. :) – Mike

1

Creo que es solo un int. De Wikipedia:

En general, un descriptor de archivo es un índice para una entrada en una estructura de datos del núcleo residente que contiene los detalles de todos los archivos abiertos. En POSIX, esta estructura de datos se denomina tabla de descriptores de archivos, y cada proceso tiene su propia tabla de descriptores de archivos.

3

Además de la buena respuesta existente por @Nominal Aminal, es un número entero pero apunta a una entrada de una estructura en el núcleo denominada tabla de descriptores de archivos. Ese es al menos el caso de Linux. De los varios campos que son parte de esa estructura, muy interesante es:

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

Quizás se encuentre interesado en el seguimiento de API que dada una de FILE * o descriptor, vuelve la otra

How to obtain FILE * from fd and vice versa

+0

' archivo descriptor table', 'sistema abrir archivo tabla': http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic =/com.ibm.aix.genprogc/doc/genprogc/fdescript.htm – n611x007

+0

** Estructuras de datos del kernel para archivos abiertos **: http://www.cim.mcgill.ca/~franco/OpSys-304-427/ lecture-notes/node27.html – n611x007

+0

Esto es completamente incorrecto. En Linux, el 'FILE *' usado por E/S estándar (y 'fileno()' y 'fdopen()') no tiene nada que ver con el kernel ['struct file'] (https: //git.kernel. org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/fs.h # n879), excepto tal vez una similitud pasajera en el nombre. –

Cuestiones relacionadas