execvp avulla ohjelma voi käyn­nis­tää jär­jes­tel­mä­ko­men­to­ja, kuten so­vel­lus­ten käyn­nis­tä­mi­sen tai jär­jes­tel­mä­pal­ve­lui­den suo­rit­ta­mi­sen. Yh­dis­tet­ty­nä fork() koodi voidaan kutsua myös execvp jälkeen.

Miten execvp toimii?

execvp pää­asial­li­nen tarkoitus on mah­dol­lis­taa yhden ohjelman oh­jaa­mi­nen toisella ilman koko prosessin uu­del­leen­käyn­nis­tä­mis­tä. Tämä mah­dol­lis­taa sau­mat­to­man siir­ty­mi­sen eri toi­min­to­jen välillä tai ulkoisten ko­men­to­jen suo­rit­ta­mi­sen muut­tu­vil­la ar­gu­men­teil­la. execvp toimii kuin näkymätön ohjaaja, joka muuttaa maisemaa ja hyppää edes­ta­kai­sin eri ta­ri­na­lin­jo­jen välillä.

Dy­naa­mi­sen prosessin suo­ri­tuk­sen avulla voit säätää ohjelman polkua ja sen ar­gu­ment­te­ja suo­ri­tuk­sen aikana. execvp() käytetään jär­jes­tel­mä­kut­suis­sa, jotka vaativat mo­ni­mut­kai­sia tehtäviä, kuten skriptien suo­rit­ta­mis­ta, jär­jes­tel­mä­ko­men­to­ja, put­kis­toin­tia ja uu­del­lee­noh­jauk­sia. Se parantaa mer­kit­tä­väs­ti C-ohjelmien jous­ta­vuut­ta.

Mikä on execvp:n syntaksi?

execvp tarvitsee kaksi pa­ra­met­ria: suo­ri­tet­ta­van ohjelman tie­dos­to­po­lun tai nimen sekä merk­ki­jo­not, jotka si­säl­tä­vät kyseisen ohjelman ar­gu­men­tit.

#include <unistd.h>
int execvp(const char *command, char* argv[]);
c
  • const char *command: Tämä on suo­ri­tet­ta­van ohjelman tie­dos­to­pol­ku tai nimi. Se voi olla ab­so­luut­ti­nen tai suh­teel­li­nen polku. Jos käytetään suh­teel­lis­ta polkua, execvp etsii tiedostoa jär­jes­tel­män PATH-polusta.
  • char *argv[]: Merk­ki­jo­no­jen taulukko, joka sisältää suo­ri­tet­ta­van ohjelman ar­gu­men­tit. Taulukon on pää­tyt­tä­vä NULL osoittaa ar­gu­ment­ti­luet­te­lon lopun. argv en­sim­mäi­nen merkintä on yleensä ohjelman nimi, jota seuraavat ar­gu­men­tit.

execvp funktio ja muut exec funktiot ovat Unix-poh­jai­sil­le käyt­tö­jär­jes­tel­mil­le ominaisia. #include <unistd.h> lause on C-oh­jel­moin­nin ot­sik­ko­tie­dos­to, joka sisältää mää­ri­tel­mät ja il­moi­tuk­set funk­tiois­ta, jotka ovat vuo­ro­vai­ku­tuk­ses­sa Unix-pohjaisen käyt­tö­jär­jes­tel­män ja pro­ses­si­noh­jauk­sen kanssa. Törmäät tähän tie­dos­toon usein, kun opit kir­joit­ta­maan koodia C-kielellä.

Esimerkki käytöstä execvp

Alla olevassa esi­mer­kis­sä käytämme unistd.h-ot­sik­ko­tie­dos­ton execvp() käyn­nis­tääk­sem­me ulkoisen ohjelman ls ar­gu­men­teil­la -l ja /usr/bin. Taulukko args edustaa ohjelman ar­gu­ment­te­ja. Jos execvp() onnistuu, nykyinen prosessi korvataan ul­koi­sel­la oh­jel­mal­la ja seuraavat rivit ohitetaan. Vir­he­ti­lan­tees­sa vir­heil­moi­tus näytetään perror kautta ja ohjelma palauttaa ti­la­koo­din 1.

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

Käyt­tä­mäl­lä fork() voit luoda uuden prosessin. Tässä alipro­ses­sis­sa voit suorittaa toisen ohjelman käyt­tä­mäl­lä execvp. Tämä mah­dol­lis­taa sen, että vanhempi prosessi voi jatkaa oman koodinsa suo­rit­ta­mis­ta, kun uusi prosessi käyn­nis­tää ulkoisen ohjelman.

#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

Yllä olevassa esi­mer­kis­sä loimme uuden prosessin käyt­tä­mäl­lä fork(). Käyt­tä­mäl­lä execvp(), ls ottaa haltuunsa lap­sipro­ses­sin sen ar­gu­men­teil­la. waitpid:lla vanhempi prosessi odottaa lap­sipro­ses­sin päät­ty­mis­tä ja tulostaa sitten viestin.

Siirry pää­va­lik­koon