/ / chemin unix recherche fonction C [fermé] - c, unix, chemin

chemin unix recherche fonction C [fermé] - c, unix, chemin

Je programme un shell UNIX et je dois utiliser le execv() appel système pour créer un processus. Un des paramètres pour execv() est le chemin de fichier pour l'exécutable. Donc, si quelqu'un tape /bin/ls, il courra le ls exécutable. Mais ce dont j'ai besoin est une fonction telle que lorsque ls est tapé, il cherchera le chemin du fichier de ls (comme le which commander). Y at-il une fonction qui me permet de le faire?

Malheureusement, ceci est un projet d'école et je ne suis pas autorisé à utiliser execvp(). Je dois mettre en œuvre une fonction de recherche de chemin, puis addon ce chemin de fichier à la execv() paramètre.

Réponses:

4 pour la réponse № 1

Utilisation PATH = getenv("PATH") pour obtenir la chaîne de chemin d'accès de l'environnement, utilisez ensuite les appels successifs à strtok(PATH,":") puis strtok(NULL,":") pour analyser les chemins de la PATH chaîne dans un tableau de char **path, que vous devrez allouer avec malloc(). Endroit path[x] + "/" + argv[0] dans un tampon, et utiliser access(buffer, X_OK) pour voir si vous pouvez exécuter votre fichier à cet emplacement, si c'est le cas, effectuez votre execv(buffer,argv).


3 pour la réponse № 2

Si vous ne pouvez pas utiliser execvp, vous pouvez obtenir la variable PATH de char** environ de <unistd.h> ou char* getenv(const char* name) à partir de <stdlib.h> puis utilisez int access(const char* filename, int mode) pour voir si le fichier existe et est exécutable. Je vais vous laisser la mise en œuvre car il s’agit d’un projet scolaire.


2 pour la réponse № 3

Vous voulez execvp (), il recherchera le chemin spécifié dans la variable PATH sauf si le nom du fichier contient un "/".


2 pour la réponse № 4

Quelques personnes ont suggéré que vous appeliez access() ou stat() avant d'essayer d'exécuter le programme avec execv(). Vous n'avez pas besoin de faire ça. execv() retournera une erreur s'il ne peut pas exécuter le fichier demandé.


1 pour la réponse № 5

Utilisation execvp.

char *args[] = {"ls", (char *) NULL};
execvp("ls", args);

par exemple. cet exemple sera exec /bin/echo (en supposant /bin est sur votre chemin).

#include <unistd.h>

int main()
{
char *args[] = {"echo", "hello world", (char *) NULL};
execvp("echo", args);
return 0;
}

1 pour la réponse № 6

Je pense que execvp () fait ce dont vous avez besoin.

Modifier: Donc, vous demandez réellement comment faire cela manuellement? Dans ce cas ...

  1. Trouvez votre PATH dans envp (3ème argument de main ())
  2. Diviser cela en chemins individuels
  3. Vérifiez l’existence de votre programme dans chacun d’eux avec stat ()
  4. Exécuter le premier que vous trouvez exister

Ou si tu veux un vraiment mise en œuvre solide, utilisation ce. Cela pourrait bien déclencher les détecteurs de plagarisme :)


0 pour la réponse № 7

Depuis la page de manuel execvp:

   The  functions  execlp() and execvp() will duplicate the actions of the
shell in searching for an executable file  if  the  specified  filename
does  not  contain  a slash (/) character.  The search path is the path
specified in the environment by the PATH variable.   If  this  variable
isn’t specified, the default path ‘‘:/bin:/usr/bin’’ is used.  In addi-
tion, certain errors are treated specially.

Peut-être que vous êtes autorisé à utiliser execlp ()? Si vous devez utiliser execv, vous devrez obtenir la valeur de la variable d'environnement PATH, analysez-la à l'aide de strtok () pour obtenir les chemins individuels, ajoutez votre nom de fichier à chaque chemin et essayez de l'exécuter avec execv ().

Je fournirais du code, mais je ne fais pas vos devoirs pour vous.


0 pour la réponse № 8

execvp :-)

Edit: d'accord. Voici une version Perl, qui peut servir de pseudocode à votre problème.

use List::Util qw(first);

my @path = split /:/, $ENV{PATH};
my $dir = first {$_ ||= "."; -x "$_/$name"} @path
or die "Can"t find program $namen";
exec "$dir/$name", @args;

split divise une chaîne en un tableau de chaînes, en utilisant le séparateur donné. first trouve le premier élément qui correspond à un critère; ici, que la concaténation du répertoire et du nom recherché est exécutable (-x). Il exécute ensuite cela.

J'espère que cela aide!


-1 pour la réponse № 9

Oh un projet d'école ...

Eh bien, si vous voulez quelque chose comme "pourquoi pas simplement exec" qui "lui-même (/ usr / bin / qui sur linux, pas l'alias bash ni les commandes tcsh) pour obtenir le chemin d'accès à ce que vous recherchez ...

:-)