Dans l'environnement Windows, il existe une API pour obtenir le chemin qui exécute un processus. Y a-t-il quelque chose de similaire sous Unix / Linux?
Ou existe-t-il un autre moyen de le faire dans ces environnements?
Dans l'environnement Windows, il existe une API pour obtenir le chemin qui exécute un processus. Y a-t-il quelque chose de similaire sous Unix / Linux?
Ou existe-t-il un autre moyen de le faire dans ces environnements?
Un peu tard, mais toutes les réponses étaient spécifiques à Linux.
Si vous avez aussi besoin d'unix, alors vous avez besoin de ceci:
char * getExecPath (char * path,size_t dest_len, char * argv0)
{
char * baseName = NULL;
char * systemPath = NULL;
char * candidateDir = NULL;
/* the easiest case: we are in linux */
if (readlink ("/proc/self/exe", path, dest_len) != -1)
{
dirname (path);
strcat (path, "/");
return path;
}
/* Ups... not in linux, no guarantee */
/* check if we have something like execve("foobar", NULL, NULL) */
if (argv0 == NULL)
{
/* we surrender and give current path instead */
if (getcwd (path, dest_len) == NULL) return NULL;
strcat (path, "/");
return path;
}
/* argv[0] */
/* if dest_len < PATH_MAX may cause buffer overflow */
if ((realpath (argv0, path)) && (!access (path, F_OK)))
{
dirname (path);
strcat (path, "/");
return path;
}
/* Current path */
baseName = basename (argv0);
if (getcwd (path, dest_len - strlen (baseName) - 1) == NULL)
return NULL;
strcat (path, "/");
strcat (path, baseName);
if (access (path, F_OK) == 0)
{
dirname (path);
strcat (path, "/");
return path;
}
/* Try the PATH. */
systemPath = getenv ("PATH");
if (systemPath != NULL)
{
dest_len--;
systemPath = strdup (systemPath);
for (candidateDir = strtok (systemPath, ":"); candidateDir != NULL; candidateDir = strtok (NULL, ":"))
{
strncpy (path, candidateDir, dest_len);
strncat (path, "/", dest_len);
strncat (path, baseName, dest_len);
if (access(path, F_OK) == 0)
{
free (systemPath);
dirname (path);
strcat (path, "/");
return path;
}
}
free(systemPath);
dest_len++;
}
/* again someone has use execve: we dont knowe the executable name; we surrender and give instead current path */
if (getcwd (path, dest_len - 1) == NULL) return NULL;
strcat (path, "/");
return path;
}
Sous Linux, chaque processus a son propre dossier dans /proc
. Vous pouvez donc utiliser getpid()
pour obtenir le pid du processus en cours, puis le joindre avec le chemin /proc
pour obtenir le dossier dont vous avez besoin, espérons-le.
Voici un court exemple en Python:
import os
print os.path.join('/proc', str(os.getpid()))
Voici l'exemple en ANSI C:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int
main(int argc, char **argv)
{
pid_t pid = getpid();
fprintf(stdout, "Path to current process: '/proc/%d/'\n", (int)pid);
return EXIT_SUCCESS;
}
Compilez-le avec:
gcc -Wall -Werror -g -ansi -pedantic process_path.c -oprocess_path
Il n'y a pas de "garantie de travailler n'importe où" la méthode.
L'étape 1 consiste à vérifier argv[0], si le programme a commencé par son chemin d'accès complet, ce sera (normalement) avoir le chemin d'accès complet. Si il a été lancé par un chemin d'accès relatif, la situation est la même (même si cela nécessite d'avoir le répertoire de travail courant, à l'aide de getcwd().
L'étape 2, si aucune de ce qui précède vaut, est d'obtenir le nom du programme, puis obtenir le nom du programme de argv[0], puis obtenir le CHEMIN d'accès utilisateur à partir de l'environnement et de passer par là pour voir si il y a un adapté binaire exécutable avec le même nom.
Notez que argv[0] est défini par le processus de execs le programme, de sorte qu'il n'est pas fiable à 100%.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.