Utilisez la fonction execlp en C

Jinku Hu 12 octobre 2023
Utilisez la fonction execlp en C

Cet article présente plusieurs méthodes pour utiliser la fonction execlp en C.

Utiliser la fonction execlp pour exécuter un nouveau programme en utilisant le nom de fichier en C

Les fonctions de la famille exec sont fournies comme une API alternative à l’appel système execve de niveau inférieur pour gérer le chargement d’un nouveau programme dans la mémoire de processus. Il y a 6 fonctions séparées dans cette famille et elles diffèrent principalement par leurs paramètres plutôt que par leur résultat. La fonction execlp est celle qui donne à l’utilisateur la possibilité de spécifier le nom du fichier et le programme est recherché dans les répertoires qui sont listés dans la variable d’environnement courante PATH.

Si le nom de fichier contient toujours la barre oblique, il est traité comme un chemin d’accès relatif ou absolu. Dans l’exemple suivant, nous implémentons un programme qui se comporte de manière similaire à un shell. A savoir, il prend le nom du programme à l’utilisateur et l’exécute comme un processus enfant. Le parent attend, et une fois que le fils revient, le contrôle passe à l’itération suivante de la saisie de l’utilisateur. Le programme doit être terminé par l’utilisateur avec Ctrl+D comme une frappe de clavier (dépend du système d’exploitation). Remarquez que certaines commandes shell ne peuvent pas être exécutées, et surtout, les arguments de la ligne de commande ne sont pas passés, mais le programme affiche couldn't execute à la place.

#include <sys/wait.h>

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"

enum { MAXLINE = 256, MAXARGS = 48 };

int main(int argc, char *argv[]) {
  char buf[MAXLINE];
  pid_t pid;
  int status;

  char *str1, *token;

  printf("%% ");
  while (fgets(buf, MAXLINE, stdin) != NULL) {
    if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0;

    if ((pid = fork()) < 0) {
      perror("fork");
    } else if (pid == 0) {
      execlp(buf, buf, (char *)NULL);
      printf("couldn't execute: %s", buf);
      exit(127);
    }

    if (waitpid(pid, &status, 0) < 0) perror("waitpid");
    printf("%% ");
  }

  exit(EXIT_SUCCESS);
}

Execlp est une fonction variadique ; ainsi, elle peut prendre un nombre variable d’arguments. Le premier et le dernier argument sont cependant fixes, représentant le pointeur vers le nom du fichier et NULL vers le char*. Notez que le fait de lancer un pointeur nul est obligatoire pour que la fonction fonctionne, et cela indique également la fin du nombre variable d’arguments. En bref, les arguments de la deuxième position doivent spécifier les arguments de la ligne de commande du programme, et le premier d’entre eux doit être le nom du fichier lui-même.

Alternativement, nous pouvons implémenter l’exemple précédent pour être capable d’exécuter des commandes avec des arguments. Dans ce cas, nous avons utilisé la fonction execvp qui prend la liste d’arguments comme un tableau. Nous avons également analysé l’entrée utilisateur en utilisant strtok pour prendre chaque chaîne de caractères séparée par un espace et les passer en argument. En conséquence, nous avons obtenu une émulation plus proche d’un programme shell.

#include <sys/wait.h>

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"

enum { MAXLINE = 256, MAXARGS = 48 };

int main(int argc, char *argv[]) {
  char buf[MAXLINE];
  char *args[MAXARGS];
  pid_t pid;
  int status, args_num = 0;

  char *str1, *token;

  printf("%% ");
  while (fgets(buf, MAXLINE, stdin) != NULL) {
    if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0;

    str1 = strdup(buf);
    for (int j = 0;; j++, str1 = NULL) {
      token = strtok(str1, " ");
      if (token == NULL) break;
      args[j] = token;
      args_num += 1;
      printf("%d: %s\n", j + 1, args[j]);
    }
    free(str1);
    args[args_num] = (char *)NULL;

    if ((pid = fork()) < 0) {
      perror("fork");
    } else if (pid == 0) {
      execvp(args[0], &args[0]);
      printf("couldn't execute: %s", buf);
      exit(127);
    }

    if (waitpid(pid, &status, 0) < 0) perror("waitpid");
    printf("%% ");
  }

  exit(EXIT_SUCCESS);
}
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Article connexe - C Process