La funzione execvp in C

Jinku Hu 12 ottobre 2023
  1. Usa la funzione execvp per sostituire un’immagine di processo in C
  2. Gestire correttamente gli scenari di errore della chiamata di funzione execvp e visualizzare i messaggi corrispondenti
  3. Usa execvp con la funzione fork per creare un processo figlio ed eseguire un programma diverso in C
La funzione execvp in C

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

Usa la funzione execvp per sostituire un’immagine di processo in C

Nei sistemi basati su Unix, ci sono due chiamate di sistema separate per creare un nuovo processo e per caricare un nuovo codice di programma in un processo in esecuzione. Quest’ultimo viene fatto usando la famiglia di funzioni di libreria exec che sono solo interfacce diverse dalla chiamata di sistema execve. Ci sono 6 diversi prototipi di funzione: execlp, execle, execv, execvp e execvpe. Queste funzioni accettano un nome file o un percorso di un nuovo file di programma da caricare ed eseguire come primo argomento. execvp accetta anche un array di argomenti del programma come secondo argomento.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
  const char *args[] = {"vim", "/home/ben/tmp3.txt", NULL};

  execvp("vim", args);

  exit(EXIT_SUCCESS);
}

Gestire correttamente gli scenari di errore della chiamata di funzione execvp e visualizzare i messaggi corrispondenti

Notare che, le funzioni della famiglia exec restituiscono solo se si verifica un errore, quindi è importante implementare routine di controllo degli errori e gestire i percorsi di codice corrispondenti secondo necessità.
execvp tra questi restituisce -1 in caso di fallimento, e imposta anche la variabile errno. Ricorda però che errno dovrebbe essere impostato esplicitamente a 0 prima della chiamata alla funzione e controllare il valore solo una volta che la chiamata data ritorna. La funzione execvp può accettare il nome del file senza barre, il che implica che il file viene cercato nelle directory come specificato dalla variabile d’ambiente PATH.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
  const char *args[] = {"vim", "/home/ben/tmp3.txt", NULL};

  errno = 0;
  if (execvp("vim", args) == -1) {
    if (errno == EACCES)
      printf("[ERROR] permission is denied for a file\n");
    else
      perror("execvp");
    exit(EXIT_FAILURE);
  }

  exit(EXIT_SUCCESS);
}

Usa execvp con la funzione fork per creare un processo figlio ed eseguire un programma diverso in C

In alternativa, supponiamo che l’utente debba creare un nuovo processo ed eseguire il codice di programma specificato. In tal caso, possiamo utilizzare la chiamata alla funzione fork combinata con execvp. fork duplica il processo chiamante e ne crea uno nuovo chiamato - il processo figlio. Nell’esempio seguente, abbiamo implementato un wrapper di funzione personalizzato per creare un nuovo processo e caricare / eseguire il codice di programma specificato. Si noti che una volta creato un processo figlio, esegue un codice diverso e il processo padre attende che il processo figlio esca.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

pid_t spawnChild(const char* program, char** arg_list) {
  pid_t ch_pid = fork();
  if (ch_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (ch_pid > 0) {
    printf("spawn child with pid - %d\n", ch_pid);
    return ch_pid;
  } else {
    execvp(program, arg_list);
    perror("execve");
    exit(EXIT_FAILURE);
  }
}

int main(void) {
  const char* args[] = {"vim", "/home/ben/tmp3.txt", NULL};

  pid_t child;
  int wstatus;

  child = spawnChild("vim", args);

  if (waitpid(child, &wstatus, WUNTRACED | WCONTINUED) == -1) {
    perror("waitpid");
    exit(EXIT_FAILURE);
  }

  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