una significa rutas ruta relativas relativa qué que ejercicios ejemplo comandos comando archivos absolutas absoluta c macos unix

significa - Recuperación programática de la ruta absoluta de una aplicación de línea de comandos de OS X



rutas absolutas y relativas linux (7)

En Linux, una aplicación puede obtener fácilmente su ruta absoluta consultando /proc/self/exe . En FreeBSD, es más complicado, ya que tienes que crear una llamada a sysctl:

int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; char buf[1024]; size_t cb = sizeof(buf); sysctl(mib, 4, buf, &cb, NULL, 0);

pero todavía es completamente factible. Sin embargo, no puedo encontrar una manera de determinar esto en OS X para una aplicación de línea de comandos. Si está ejecutando desde un paquete de aplicaciones, puede determinarlo ejecutando [[NSBundle mainBundle] bundlePath] , pero como las aplicaciones de línea de comandos no están en paquetes, esto no ayuda.

(Nota: consultar argv[0] no es una respuesta razonable, ya que, si se inicia desde un enlace simbólico, argv[0] será ese enlace simbólico, no la ruta final al ejecutable llamado. argv[0] también puede encontrarse si un La aplicación tonta usa una llamada exec() y se olvida de inicializar argv correctamente, lo que he visto en la naturaleza.)


¿Por qué no simplemente realpath(argv[0], actualpath); ? Es cierto que realpath tiene algunos límites (documentados en la página del manual) pero maneja bien los enlaces simbólicos. Probado en FreeBSD y Linux

% ls -l foobar lrwxr-xr-x 1 bortzmeyer bortzmeyer 22 Apr 29 07:39 foobar -> /tmp/get-real-name-exe % ./foobar My real path: /tmp/get-real-name-exe

#include <limits.h> #include <stdlib.h> #include <stdio.h> #include <libgen.h> #include <string.h> #include <sys/stat.h> int main(argc, argv) int argc; char **argv; { char actualpath[PATH_MAX + 1]; if (argc > 1) { fprintf(stderr, "Usage: %s/n", argv[0]); exit(1); } realpath(argv[0], actualpath); fprintf(stdout, "My real path: %s/n", actualpath); exit(0); }

Si el programa se inicia a través de PATH, vea la solución de pixelbeat.


Creo que hay una solución mucho más elegante, que en realidad funciona para cualquier PID y también devuelve la ruta absoluta directamente:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <libproc.h> int main (int argc, char* argv[]) { int ret; pid_t pid; char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; pid = getpid(); ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf)); if ( ret <= 0 ) { fprintf(stderr, "PID %d: proc_pidpath ();/n", pid); fprintf(stderr, " %s/n", strerror(errno)); } else { printf("proc %d: %s/n", pid, pathbuf); } return 0; }


Esto es tarde, pero [[NSBundle mainBundle] executablePath] funciona bien para programas de línea de comandos no empaquetados.


La función _NSGetExecutablePath devolverá una ruta completa al ejecutable (GUI o no). La ruta puede contener enlaces simbólicos, " .. ", etc., pero la función realpath se puede usar para limpiarlos si es necesario. Vea _NSGetExecutablePath para más información.

char path[1024]; uint32_t size = sizeof(path); if (_NSGetExecutablePath(path, &size) == 0) printf("executable path is %s/n", path); else printf("buffer too small; need size %u/n", size);

El secreto de esta función es que el kernel de Darwin coloca la ruta ejecutable en la pila del proceso inmediatamente después de la matriz envp cuando crea el proceso. El editor de enlaces dinámicos dyld esto en la inicialización y mantiene un puntero a él. Esta función utiliza ese puntero.


No hay una forma garantizada, creo. Si argv [0] es un enlace simbólico, entonces podría usar readlink (). Si el comando se ejecuta a través de $ PATH, entonces se podría probar: search (getenv ("PATH")), getenv ("_"), dladdr ()


Parece que la respuesta es que no puedes hacerlo:

Estoy tratando de lograr algo como la funcionalidad de lsof y reunir un montón de estadísticas e información sobre los procesos en ejecución. Si el lsof no fuera tan lento, estaría feliz de seguir adelante.

Si reimplementas lsof, encontrarás que es lento porque está haciendo mucho trabajo.

Supongo que no es realmente porque lsof es el modo de usuario, es más que tiene que escanear el espacio de direcciones de una tarea en busca de cosas respaldadas por un buscapersonas externo. ¿Hay alguna forma más rápida de hacer esto cuando estoy en el núcleo?

No. lsof no es estúpido; Está haciendo lo que tiene que hacer. Si solo desea un subconjunto de su funcionalidad, puede considerar comenzar con la fuente lsof (que está disponible) y recortarla para cumplir con sus requisitos.

Por curiosidad, ¿se usa p_textvp ? Parece que está configurado para el p_textvp los padres en kern_fork (y luego se libera?) Pero no se toca en ninguna de las rutinas de kern_exec .

p_textvp no se utiliza. En Darwin, el proc no es la raíz del espacio de direcciones; la tarea es No hay un concepto de "vnode" para el espacio de direcciones de una tarea, ya que no necesariamente se rellena inicialmente al asignar uno.

Si exec rellenara p_textvp, supondría que todos los procesos están respaldados por un vnode. Entonces los programadores supondrían que era posible obtener una ruta al vnode, y desde allí es un pequeño salto al supuesto de que la ruta actual al vnode es la ruta desde la que se lanzó, y que el procesamiento de texto en la cadena podría llevar al nombre del paquete de aplicación ... todo lo cual sería imposible de garantizar sin una sanción sustancial.

- Mike Smith, lista de correo de Darwin Drivers