La funzione execvp() permette a un programma di eseguire comandi di sistema come l’avvio di ap­pli­ca­zio­ni o l’ese­cu­zio­ne di servizi di sistema. In com­bi­na­zio­ne con la funzione fork(), è possibile eseguire del codice anche dopo execvp().

Come funziona execvp()?

Il compito prin­ci­pa­le di execvp() è quello di dare a un programma il controllo su un altro senza dover riavviare l’intero processo. In questo modo si ha la pos­si­bi­li­tà di passare fa­cil­men­te da una funzione all’altra o di eseguire comandi esterni con argomenti variabili. execvp() è come un regista in­vi­si­bi­le che cambia lo scenario e salta avanti e indietro tra le diverse trame.

L’ese­cu­zio­ne dinamica dei processi permette di mo­di­fi­ca­re il percorso del programma e persino i suoi argomenti durante l’ese­cu­zio­ne. La funzione execvp() viene uti­liz­za­ta nelle chiamate di sistema che ri­chie­do­no compiti complessi come l’ese­cu­zio­ne di script, comandi di sistema, pi­pe­li­ning e rein­di­riz­za­men­ti. Con­tri­bui­sce in modo si­gni­fi­ca­ti­vo ad aumentare la fles­si­bi­li­tà dei programmi di C.

La sintassi di base di execvp()

La sintassi di execvp() richiede il percorso del file o il nome del programma da eseguire e un array di stringhe con­te­nen­ti gli argomenti di questo programma.

#include <unistd.h>
int execvp()(const char *command, char* argv[]);
c
  • const char *command: si tratta del percorso del file o del nome del ri­spet­ti­vo programma, che può essere sia assoluto che relativo. Se viene uti­liz­za­to un percorso relativo, execvp() cerca il file nel percorso (PATH) del sistema.
  • char *argv[]: questo è l’array di stringhe con­te­nen­ti gli argomenti del programma da eseguire; l’array deve terminare con un puntatore NULL per indicare la fine dell’elenco degli argomenti. La prima voce di argv è so­li­ta­men­te il nome del programma stesso, seguito dagli argomenti.

La funzione execvp() e le altre della famiglia exec sono spe­ci­fi­che dei sistemi operativi Unix. L’istru­zio­ne #include <unistd.h> è un file di in­te­sta­zio­ne nella pro­gram­ma­zio­ne di C con­te­nen­te de­fi­ni­zio­ni e di­chia­ra­zio­ni di funzioni che in­te­ra­gi­sco­no con il sistema operativo basato su Unix e con il controllo dei processi. Chi per un motivo o per l’altro si ritrova a imparare C, ha spesso a che fare con questo tipo di file.

Consiglio

Vuoi saperne di più sul lin­guag­gio di pro­gram­ma­zio­ne C? Leggi il nostro articolo al riguardo e scopri come funziona la pro­gram­ma­zio­ne orientata agli oggetti (OOP) in C.

execvp(): un esempio pratico

Nel programma C pre­sen­ta­to qui di seguito, uti­liz­zia­mo la funzione execvp() del file di in­te­sta­zio­ne unistd.h per avviare il programma esterno ls con gli argomenti -l e /usr/bin. L’array args rap­pre­sen­ta gli argomenti del programma. Se la funzione execvp() viene portata a termine con successo, il processo corrente viene so­sti­tui­to dal programma esterno e le righe suc­ces­si­ve vengono ignorate. In caso di errore, compare un messaggio di errore tramite perror e il programma re­sti­tui­sce il codice di stato 1.

#include <unistd.h>
int main() {
    char *args[] = {"ls", "-l", "/usr/bin", NULL};
    execvp()("ls", args);
    perror("execvp()");
    return 1;
}
c

La funzione fork() consente di eseguire istru­zio­ni anche dopo execvp() at­tra­ver­so la creazione di un nuovo processo. Di con­se­guen­za, nel processo padre, il codice continua a essere eseguito, mentre il processo figlio avvia il programma esterno.

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
    char* command = "ls";
    char *args[] = {"ls", "-l", "/usr/bin", NULL};
    printf("Before calling execvp()\n");
    pid_t child_pid = fork();
    if (child_pid == -1) {
        // Error creating the process
        perror("fork");
        return 1;
    }
    if (child_pid == 0) {
        // Code executed in the child process
        // Call execvp() in the child process to execute "ls" with the specified arguments
        int status_code = execvp()(command, args);
        // This line is reached if execvp() encounters an error
        perror("execvp()");
        // Print statement after execvp()
        printf("ls -l /usr/bin has taken control of this child process. If this is printed, execvp() encountered
       an error.\n");
        // Error handling in the child process
        return 1;
    } else {
        // Code executed in the parent process
        // Wait for the completion of the child process
        waitpid(child_pid, NULL, 0);
        printf("The child process has completed its execution.\n");
    }
    return 0;
}
c

Prima di tutto occorre creare un nuovo processo uti­liz­zan­do fork(). At­tra­ver­so la funzione execvp(), ls, uni­ta­men­te ai suoi argomenti, prende il controllo del processo figlio. Il processo padre attende il com­ple­ta­men­to del processo figlio con waitpid, dopodiché emette il messaggio.

Web Hosting
Diventa il n°1 della rete con il provider di hosting n°1 in Europa
  • Di­spo­ni­bi­li­tà garantita al 99,99%
  • Dominio, SSL ed e-mail inclusi
  • As­si­sten­za 24/7 in lingua italiana
Vai al menu prin­ci­pa­le