pthread_create pthread c++ c linux unix posix

c++ - pthread - ¿Hay un equivalente a MAX_PATH de WinAPI en Linux/Unix?



pthreads php (6)

Bueno, en Linux al menos, hay:

  • PATH_MAX (definido en limits.h )

  • FILENAME_MAX (definido en stdio.h )

ambos están configurados en 4096 en mi sistema (x86 Linux).

Actualización:: alguna información del manual de glibc sobre este

Cada una de las siguientes macros se define en limits.h solo si el sistema tiene un límite fijo y uniforme para el parámetro en cuestión. Si el sistema permite que los diferentes sistemas de archivos o archivos tengan límites diferentes, entonces la macro no está definida; use pathconf o fpathconf para averiguar el límite que se aplica a un archivo en particular

Si deseo asignar una matriz char (en C) que garantice que sea lo suficientemente grande como para contener cualquier ruta de acceso absoluta válida + nombre de archivo, qué tan grande debe ser.

En Win32, está la definición MAX_PATH. ¿Cuál es el equivalente para Unix / Linux?


FILENAME_MAX es parte del estándar ISO C, funciona en UNIX y Windows. Sin embargo, la documentación de la biblioteca GNU C contiene las siguientes advertencias:

"A diferencia de PATH_MAX, esta macro se define incluso si no se impone un límite real. En tal caso, su valor suele ser un número muy grande. Este es siempre el caso en el sistema GNU.

Nota de uso: ¡No use FILENAME_MAX como el tamaño de una matriz en la que almacenar un nombre de archivo! ¡No se puede hacer una matriz tan grande! Use la asignación dinámica ".


Las otras respuestas hasta ahora parecen estar a punto sobre el lado * nix de las cosas, pero añadiré una advertencia al respecto en Windows.

La documentación le ha mentido (por omisión).

MAX_PATH está definido, y probablemente incluso se aplica a los archivos almacenados en FAT o FAT32. Sin embargo, cualquier nombre de ruta puede tener el prefijo //?/ Para decirle a la API de Windows que ignore MAX_PATH y deje que el controlador del sistema de archivos se decida por sí mismo. Después de eso, las definiciones se vuelven borrosas.

Agregue a la mezcla el hecho de que los nombres de las rutas son realmente Unicode (bueno, UTS-16) y que cuando se utiliza la API "ANSI", la conversión hacia y desde el nombre Unicode interno depende de varios factores, incluida la página de códigos actual. y tienes una receta para la confusión.

Una buena descripción de las reglas para Windows está en MSDN . Las reglas son mucho más complicadas de lo que he resumido aquí.

Editar: Cambié //./ //?/ En lo anterior gracias al comentario de KitsuneYMG.

Las rutas de Windows y los espacios de nombres son complicados. Algunos incluso podrían argumentar que son demasiado complicados. Una fuente de complejidad es que la API Win32 (y ahora Win64) es un subsistema que se ubica sobre el sistema nativo de Windows NT.

Una ruta sin prefijo es compatible en la más amplia gama de plataformas de Windows. Si está restringido a caracteres ASCII de 7 bits, entonces es compatible con DOS de 16 bits desde la versión 2.0 o más (siempre que se introdujeron subdirectorios, que en realidad podrían haber estado en DOS 3, pero DOS 1.0 solo tenía directorios raíz y el / el personaje no tenía un significado especial).

El prefijo //?/ Hace que el saldo del nombre de la ruta se transmita textualmente al controlador del sistema de archivos apropiado, que es lo que produce el efecto de MAX_PATH la restricción a los caracteres MAX_PATH . Si el nombre de ruta larga también está en un recurso compartido de red, entonces puede usar un nombre UNC extendido para él con el prefijo //?/UNC/server/share/ lugar del nombre UNC normal //server/share/ . El uso de este prefijo restringe la portabilidad a las plataformas Win32 y posteriores de Windows, pero a menos que necesite soporte para Windows de 16 bits en hardware heredado, eso no es un gran problema.

El prefijo //./ Es un animal diferente. Permite el acceso a los objetos del dispositivo más allá del conjunto de dispositivos con nombre especial que son asignados automáticamente por Windows como nombres de archivo especiales en cada carpeta de archivos. Esos nombres especiales incluyen CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, ​​COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 y LPT9. Tenga en cuenta que todos esos nombres son especiales ya sea que se use o no una extensión, o en cualquier combinación de mayúsculas o minúsculas. Pero es posible que tenga 10 o más puertos COM instalados. Esto sucede rápidamente si juega con módems USB o adaptadores de puerto serie USB, ya que a cada puerto serie único basado en USB se le asignará un nombre COMn distinto. Si necesita acceder al puerto número 50, entonces solo puede hacerlo con el nombre //./COM50 porque COM50 no es un nombre especial como COM1.

La página de MSDN que mencioné arriba tenía la distinción correcta, simplemente escribí el prefijo incorrecto en mi respuesta original.


Puede usar pathconf() para averiguar en tiempo de ejecución, pero también hay un preprocesador PATH_MAX definido en <limits.h> .


Puede usar la función realpath para asignar un búfer lo suficientemente grande para una ruta específica. Si le pasa un puntero nulo como segundo argumento, asignará un búfer lo suficientemente grande para la ruta. La página del hombre probablemente lo explica mejor que yo:

realpath () expande todos los enlaces simbólicos y resuelve las referencias a /./, /../ y caracteres extra ''/'' en la cadena terminada en nulo nombrada por ruta para producir un nombre de ruta absoluto canonicalizado. El nombre de ruta resultante se almacena como una cadena terminada en nulo, hasta un máximo de bytes PATH_MAX, en el búfer al que apunta resolve_path. La ruta resultante no tendrá ningún enlace simbólico, /./ o /../ componentes.

Si ruta_resuelta se especifica como NULL, entonces realpath () usa malloc (3) para asignar un búfer de hasta PATH_MAX bytes para mantener el nombre de ruta resuelto, y devuelve un puntero a este búfer. La persona que llama debería desasignar este búfer usando free (3).

http://linux.die.net/man/3/realpath


Hay un PATH_MAX , pero es un poco problemático. De la sección de errores de la página man de realpath(3) :

La versión estándar POSIX.1-2001 de esta función está rota por diseño, ya que es imposible determinar un tamaño adecuado para el buffer de salida, resolved_path . De acuerdo con POSIX.1-2001, un búfer de tamaño PATH_MAX es suficiente, pero PATH_MAX no necesita ser una constante definida, y puede tener que obtenerse usando pathconf(3) . Y preguntar pathconf(3) realmente no ayuda, ya que, por un lado, POSIX advierte que el resultado de pathconf(3) puede ser enorme e inadecuado para la memoria mallada, y por otro lado pathconf(3) puede devolver -1 a significa que PATH_MAX no está limitado.