tuberias read procesos pipes nombre funcion fifos entre ejemplos ejemplo con comunicacion archivos arbol c++ c linux unix file-descriptor

read - ¿Por qué los descriptores de archivos UNIX no están implementados por su propio tipo, especialmente en C++?



mkfifo c ejemplo (3)

Historia, si nada más. En la década de 1970, probablemente no parecía un problema utilizar simplemente int (y el valor era, de hecho, un índice en una tabla de tamaño fijo). Más tarde, cambiarlo a otro tipo habría roto el código.

He estado utilizando una buena cantidad de descriptores de archivos recientemente, y me he estado preguntando por qué se implementan como enteros.

Significa que son fáciles de confundir con otros enteros, y no hay manera de saber sin contexto qué son, qué señalan, si están abiertos, etc.

En C, FILE es un tipo de struct opaca. Muchas personas también status_t por ejemplo, status_t como un entero, por lo que su función es obvia. Parece que lo mejor sería implementarlos como un tipo opaco o (por ejemplo, en C ++) como una clase que puede encargarse de parte de la implementación, y también limpiar un poco el namespace (una llamada a pipe() o open() parece tan inocuo, y no es obvio lo que estás instalando o abriendo sin contexto). Como, por ejemplo, std::file_descriptor , con constructores / funciones de fábrica para crear canalizaciones o abrir archivos, etc.

Espero que esto sea sobre el tema de este sitio; Traté de expresarlo como " ¿Por qué se tomó esta decisión en particular? " Si alguien sabe en algún lugar que encajaría mejor, hágamelo saber.


La interfaz de Unix se describe en términos del lenguaje C, pero es igualmente importante que los sistemas tengan un ABI, no solo una API.

Las estructuras de datos sofisticadas específicas de un lenguaje de programación complican el ABI. En el nivel ABI, solo tiene tipos de datos de bajo nivel como "entero sin signo de 32 bits" y agregados simples de los mismos.

Dicho esto, la interfaz de Unix hace uso de tipos como pid_t y otras cosas, así que ¿por qué no una de estas typedefs para descriptores de archivos?

Los descriptores de archivo tienen ciertos valores conocidos, y cuando se abre un nuevo descriptor de archivo, siempre se utiliza el valor positivo más pequeño disponible. Los valores de los descriptores de archivos actúan efectivamente como índices de matriz en una tabla de descriptores, y el diseño es deliberadamente de esa manera. El modelo de descriptores de archivo del programador es que hay una estructura de tipo matriz en el núcleo. La función dup2 puede duplicar un descriptor de archivo de una ranura a otra. Dichos índices de matriz también podrían ser int , con un valor negativo para errores de señalización.

Los typedefs de C no compran comprobaciones de tipos adicionales, pero aportan un poco de legibilidad y también abstracción: independencia de un tipo entero en particular. Un tipo fd_t podría ser un int en un sistema y un long en otro. Pero dado que la int ha extendido a casi 32 bits de ancho hace varias décadas, no hay una necesidad real de abstraerla para poder ampliarla con el mismo nombre. Es muy inusual que un programa necesite más de dos mil millones de descriptores de archivos abiertos.

Por el contrario, sería muy inconveniente para los implementadores si se utilizara un int simple en lugar de pthread_t , por ejemplo.

int descriptores int resultaron ser difíciles de tragar para los diseñadores de la API de Windows Socket, quienes inventaron un typedef SOCKET , cuyos valores no son los enteros positivos más bajos disponibles; Sólo uno de los caprichos que llevan a las molestias de portabilidad. Sin embargo, existe una diferencia semántica real en ese código que se basa en que estos descriptores son valores pequeños en un rango que no funcionarán o se comportarán de manera ineficiente.

Hay instancias históricas de Unix que se ha revisado para reemplazar un tipo int simple con algún typedef. Por ejemplo, en una función de accept , el tamaño de la estructura de dirección remota solía ser simplemente int . Entonces se convirtió en socklen_t . No hay necesidad técnica de que socklen_t exista; se inventó como una solución de curita para salvar las diferencias entre los sistemas que usaban el int tradicional y aquellos cuyos mantenedores cambiaron celosamente el argumento de usar size_t . Si bien esos dos tipos llevaron al mismo ABI, no hubo ningún problema, hasta que los sistemas con 64 bit size_t y 32 bit int .


Tu pregunta se puede dividir en dos:

¿Por qué es int descriptor de archivos POSIX?

Como la mayoría de las cosas en herramientas y bibliotecas ya establecidas, la respuesta es probablemente por razones históricas. La respuesta de James señala esto.

Hacer que el descriptor de archivo sea opaco es probablemente una buena idea, pero no por la razón que mencionó. Hacer el tipo opaco es bueno para tener un tipo diferente basado en algunos parámetros. Por ejemplo, en algunos sistemas es posible que desee un descriptor de archivo tan long long como el long long . Sin embargo, como parece que sucede, nadie en ninguna parte ha necesitado 2 mil millones de archivos abiertos al mismo tiempo y, por lo tanto, nadie se ha preocupado de solucionar este problema que no existe.

Por otro lado, algo así como typedef int file_descriptor; no solucionará ninguno de los problemas que mencionaste anteriormente:

Significa que son fáciles de confundir con otros enteros ...

Si confundes tus variables, tengo malas noticias para ti. El compilador tampoco te ayudará ya que file_descriptor e int son del mismo tipo, por lo que cualquier operación en una está permitida en la otra.

... y no hay forma de saber sin contexto qué son, a qué apuntan, si están abiertos, etc.

Tampoco puedes hacer eso con FILE . Es por eso que tiene funciones que consultan la información que busca y la devuelven, al igual que con FILE . escribir el tipo no le dará ninguna información adicional.

¿Por qué POSIX no tiene un envoltorio de C ++ para ello?

En resumen, porque excepto Microsoft, ningún desarrollador de sistemas operativos está enamorado de C ++. Windows es apenas POSIX, por lo que no hay esperanza para que Microsoft intente mejorar algo POSIX. Otros sistemas operativos que son compatibles con POSIX tienen una API de C como el lenguaje de programación de facto del sistema (en parte porque, como dice nm , casi todos los lenguajes pueden enlazarse a C).

De hecho, C ++ es popular entre los desarrolladores de aplicaciones, pero no tanto entre los programadores de sistemas. El comité POSIX tampoco parece estar particularmente interesado en C ++. Es por eso que vería C y solo C soluciones y argumentos con respecto a la API POSIX. También tenga en cuenta que POSIX fue creado para estandarizar la interfaz de UNIX en particular , que fue escrita en C y uno de sus descendientes más importantes, Linux, también está fuertemente vinculado a C.