Usa la funzione execlp in C

Jinku Hu 12 ottobre 2023
Usa la funzione execlp in C

Questo articolo mostrerà diversi metodi su come utilizzare la funzione execlp in C.

Usa execlp per eseguire un nuovo programma usando il nome del file in C

La famiglia di funzioni exec è fornita come un’API alternativa alla chiamata di sistema di livello inferiore execve per gestire il caricamento di un nuovo programma nella memoria del processo. Ci sono 6 funzioni separate in questa famiglia e differiscono principalmente nei loro parametri piuttosto che nel risultato. La funzione execlp è quella che offre all’utente l’opzione di specificare il nome del file e il programma viene cercato nelle directory che sono elencate nella variabile d’ambiente corrente PATH.

Se il nome del file contiene ancora la barra, viene trattato come percorso relativo o assoluto. Nell’esempio seguente, implementiamo un programma che si comporta in modo simile a una shell. Vale a dire, prende il nome del programma dall’utente e lo esegue come processo figlio. Il genitore attende e una volta che il figlio ritorna, il controllo passa all’iterazione successiva dell’input dell’utente. Il programma dovrebbe essere terminato dall’utente con Ctrl+D come la sequenza di tasti (dipende dal sistema operativo). Si noti che alcuni comandi della shell non possono essere eseguiti e, cosa più importante, gli argomenti della riga di comando non vengono passati, ma il programma visualizza invece couldn't execute.

#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 è una funzione variadica; quindi, può richiedere un numero variabile di argomenti. Tuttavia, il primo e l’ultimo argomento sono corretti, rappresentando il puntatore al nome del file e NULL cast a char* corrispondentemente. Si noti che il cast di un puntatore nullo è obbligatorio affinché la funzione funzioni e denota anche la fine del numero variabile di argomenti. In breve, gli argomenti della seconda posizione dovrebbero specificare gli argomenti della riga di comando per il programma e il primo dei quali dovrebbe essere il nome del file stesso.

In alternativa, possiamo implementare l’esempio precedente per poter eseguire comandi con argomenti. In questo caso, abbiamo utilizzato la funzione execvp che accetta l’lista degli argomenti come un array. Inoltre, abbiamo analizzato l’input dell’utente usando strtok per prendere ogni stringa separata da spazi e passarla come argomenti. Di conseguenza, otteniamo un’emulazione più ravvicinata di un programma 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);
}
Autore: 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

Articolo correlato - C Process