2009-07-23 23 views
5

Sé que es posible obtener una ruta de acceso absoluta de un archivo con la función realpath(). Sin embargo, según la sección BUGS de la página de manual, hay algunos problemas en su implementación. Los detalles son los siguientes:¿Cómo obtener la ruta absoluta de un archivo mediante programación con out realpath() en Linux?


FALLOS

evitar el uso de esta función. Está roto por diseño ya que (a menos que se use la función no estándar resolve_path == NULL) es imposible determinar un tamaño adecuado para el buffer de salida, resolved_path. Según POSIX, basta con un búfer de tamaño PATH_MAX, 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 mallocing. Y, por otro lado, pathconf (3) puede devolver -1 para indicar que PATH_MAX no está limitado.

La implementación de libc4 y libc5 contiene un desbordamiento de búfer (corregido en libc-5.4.13). Por lo tanto, los programas set-user-ID como mount (8) necesitan una versión privada.


Entonces, la pregunta es, ¿cuál es la mejor práctica para obtener la ruta absoluta de un archivo?

+0

Duplicado de "[Recuperando de forma programática la ruta absoluta de una aplicación de línea de comandos de OS X] (http://stackoverflow.com/questions/799679/programatically-retrieving-the-absolute-path-of-an-os- x-command-line-app) "? – bortzmeyer

+0

No. No son lo mismo. Quiero saber cómo obtener la ruta absoluta de un archivo ordinario en lugar de la ruta de ejecutable. – jcadam

Respuesta

2

Desde el shell, puedo obtener una ruta completa usando readlink -f $FILE. Hay una función readlink() en glibc, quizás eso te ayude.

# man 2 readlink 
+0

He leído el código fuente del comando readlink en el paquete coreutils. Hay una solución simple: simplemente defina el PATH_MAX a 1024 !!!! -__- !!! – jcadam

3

Uso getcwd() y readlink(), que permite dar un tamaño de búfer volver a implementar realpath(). Tenga en cuenta que debe resolver enlaces simbólicos, "." y ".." de izquierda a derecha para hacerlo correctamente.

5

Sé que esta pregunta es antigua, pero no veo ninguna respuesta que aborde el problema principal: La página de manual de OP a la que se hace referencia es incorrecta y obsoleta, al menos por dos razones.

Una es que POSIX 2008 agregó/requirió soporte para la opción de argumento NULL, mediante el cual realpath asigna la cadena por usted. Los programas que utilizan esta función serán portátiles para todas las versiones relevantes de GNU/Linux, probablemente la mayoría de los demás sistemas modernos, y todo lo que se ajuste a POSIX 2008.

La segunda razón por la que la página de manual es incorrecta es la advertencia contra PATH_MAX. Esta es una ideología religiosa puramente GNU contra "límites arbitrarios". En el mundo real, no tener un límite de longitud de nombre de ruta agregaría todo tipo de avenidas para abuso/DoS, agregaría muchos casos de falla a tareas que de otro modo no podrían fallar, y rompería más interfaces que solo realpath.

Si le preocupa la portabilidad máxima, probablemente sea mejor utilizar una combinación de ambos métodos. Consulte la documentación de POSIX para más detalles:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html

me gustaría utilizar un tamaño fijo, tampón de llamadas proporcionado por si se ha definido PATH_MAX, y de otra manera pasar NULL. Esto parece cubrir todos los casos, pero es posible que también desee comprobar versiones anteriores de POSIX para ver si tienen alguna guía sobre qué hacer si no está definido PATH_MAX.

Cuestiones relacionadas