GNU/Linux >> Tutoriels Linux >  >> Linux

Comment trouver l'emplacement de l'exécutable en C ?

Pas une réponse en fait, mais juste une note à garder à l'esprit.

Comme nous avons pu le voir, le problème de trouver l'emplacement de l'exécutable en cours d'exécution est assez délicat et spécifique à la plate-forme sous Linux et Unix. Il faut réfléchir à deux fois avant de faire ça.

Si vous avez besoin de votre emplacement exécutable pour découvrir certains fichiers de configuration ou de ressources, vous devriez peut-être suivre la méthode Unix pour placer les fichiers dans le système :placez les configurations sur /etc ou /usr/local/etc ou dans le répertoire personnel de l'utilisateur actuel, et /usr/share est un bon endroit pour mettre vos fichiers de ressources.


Utilisez la fonction GetModuleFileName() si vous utilisez Windows.


Veuillez noter que les commentaires suivants sont uniquement UNIX.

La réponse pédante à cette question est qu'il n'y a pas de général façon de répondre correctement à cette question dans tous les cas. Comme vous l'avez découvert, argv[0] peut être défini sur n'importe quoi par le processus parent, et n'a donc aucun rapport avec le nom réel du programme ou son emplacement dans le système de fichiers.

Cependant, l'heuristique suivante fonctionne souvent :

  1. Si argv[0] est un chemin absolu, supposez qu'il s'agit du chemin complet vers l'exécutable.
  2. Si argv[0] est un chemin relatif, c'est-à-dire qu'il contient un / , déterminez le répertoire de travail actuel avec getcwd(), puis ajoutez-y argv[0].
  3. Si argv[0] est un mot simple, recherchez $PATH à la recherche de argv[0] et ajoutez argv[0] au répertoire dans lequel vous le trouvez.

Notez que tous ces éléments peuvent être contournés par le processus qui a invoqué le programme en question. Enfin, vous pouvez utiliser des techniques spécifiques à Linux, telles que celles mentionnées par emg-2. Il existe probablement des techniques équivalentes sur d'autres systèmes d'exploitation.

Même en supposant que les étapes ci-dessus vous donnent un nom de chemin valide, vous n'avez peut-être toujours pas le nom de chemin que vous voulez réellement (car je soupçonne que ce que vous voulez réellement faire est de trouver un fichier de configuration quelque part). La présence de liens physiques signifie que vous pouvez avoir la situation suivante :

-- assume /app/bin/foo is the actual program
$ mkdir /some/where/else
$ ln /app/bin/foo /some/where/else/foo     # create a hard link to foo
$ /some/where/else/foo

Maintenant, l'approche ci-dessus (y compris, je suppose, /proc/$pid/exe) donnera /some/where/else/foo comme véritable chemin d'accès au programme. Et, en fait, c'est un vrai chemin vers le programme, mais pas celui que vous vouliez. Notez que ce problème ne se produit pas avec les liens symboliques qui sont beaucoup plus courants en pratique que les liens physiques.

Malgré le fait que cette approche n'est en principe pas fiable, elle fonctionne assez bien dans la pratique pour la plupart des objectifs.


Pour résumer :

  • Sur Unix avec /proc façon vraiment simple et fiable est de :

    • readlink("/proc/self/exe", buf, bufsize) (Linux)

    • readlink("/proc/curproc/file", buf, bufsize) (FreeBSD)

    • readlink("/proc/self/path/a.out", buf, bufsize) (Solaris)

  • Sur les Unix sans /proc (c'est-à-dire si ci-dessus échoue):

    • Si argv[0] commence par "/" (chemin absolu), il s'agit du chemin.

    • Sinon, si argv[0] contient "/" (chemin relatif), ajoutez-le à cwd (en supposant qu'il n'a pas encore été modifié).

    • Sinon rechercher les répertoires en $PATH pour l'exécutable argv[0] .

    Ensuite, il peut être raisonnable de vérifier si l'exécutable n'est pas réellement un lien symbolique. Si c'est le cas, résolvez-le par rapport au répertoire du lien symbolique.

    Cette étape n'est pas nécessaire dans la méthode /proc (au moins pour Linux). Là, le lien symbolique proc pointe directement vers l'exécutable.

    Notez qu'il appartient au processus appelant de définir argv[0] correctement. C'est vrai la plupart du temps, mais il y a des occasions où le processus appelant n'est pas fiable (ex. setuid executable).

  • Sous Windows :utilisez GetModuleFileName(NULL, buf, bufsize)


Linux
  1. Comment auditer les autorisations avec la commande find

  2. Trouver l'URL d'un fichier

  3. comment trouver le propriétaire d'un fichier ou d'un répertoire en python

  4. Comment diriger les résultats de 'find' vers mv sous Linux

  5. comment trouver le chemin HADOOP_HOME sous Linux ?

Comment trouver l'adresse IP d'une machine virtuelle KVM

Comment trouver la taille totale d'un répertoire sous Linux

Comment rechercher des fichiers avec la commande fd sous Linux

Comment trouver la liste des référentiels installés sous Linux

Comment trouver l'emplacement de vos serveurs avec Traceroute et WHOIS

Comment puis-je trouver l'emplacement MySQL my.cnf