# Kuinka käyttää execvp()-funktiota C- ja C++-kielissä

`execvp` avulla ohjelma voi käynnistää järjestelmäkomentoja, kuten sovellusten käynnistämisen tai järjestelmäpalveluiden suorittamisen. Yhdistettynä `fork()` koodi voidaan kutsua myös `execvp` jälkeen.

## Miten `execvp` toimii?

`execvp` pääasiallinen tarkoitus on mahdollistaa yhden ohjelman ohjaaminen toisella ilman koko prosessin uudelleenkäynnistämistä. Tämä mahdollistaa saumattoman siirtymisen eri toimintojen välillä tai ulkoisten komentojen suorittamisen muuttuvilla argumenteilla. `execvp` toimii kuin näkymätön ohjaaja, joka muuttaa maisemaa ja hyppää edestakaisin eri tarinalinjojen välillä.

Dynaamisen prosessin suorituksen avulla voit säätää ohjelman polkua ja sen argumentteja suorituksen aikana. `execvp()` käytetään järjestelmäkutsuissa, jotka vaativat monimutkaisia tehtäviä, kuten skriptien suorittamista, järjestelmäkomentoja, putkistointia ja uudelleenohjauksia. Se parantaa merkittävästi C-ohjelmien joustavuutta.

## Mikä on `execvp`:n syntaksi?

`execvp` tarvitsee kaksi parametria: suoritettavan ohjelman tiedostopolun tai nimen sekä merkkijonot, jotka sisältävät kyseisen ohjelman argumentit.

```c
#include <unistd.h>
int execvp(const char *command, char* argv[]);
```

- **`const char *command`**: Tämä on suoritettavan ohjelman tiedostopolku tai nimi. Se voi olla absoluuttinen tai suhteellinen polku. Jos käytetään suhteellista polkua, `execvp` etsii tiedostoa järjestelmän PATH-polusta.
- **`char *argv[]`**: Merkkijonojen taulukko, joka sisältää suoritettavan ohjelman argumentit. Taulukon on päätyttävä `NULL` osoittaa argumenttiluettelon lopun. `argv` ensimmäinen merkintä on yleensä ohjelman nimi, jota seuraavat argumentit.

`execvp` funktio ja muut `exec` funktiot ovat **Unix-pohjaisille käyttöjärjestelmille** ominaisia. `#include <unistd.h>` lause on C-ohjelmoinnin otsikkotiedosto, joka sisältää määritelmät ja ilmoitukset funktioista, jotka ovat vuorovaikutuksessa Unix-pohjaisen käyttöjärjestelmän ja prosessinohjauksen kanssa. Törmäät tähän tiedostoon usein, kun opit kirjoittamaan koodia C-kielellä.

## Esimerkki käytöstä `execvp`

Alla olevassa esimerkissä käytämme unistd.h-otsikkotiedoston `execvp()` käynnistääksemme ulkoisen ohjelman `ls` argumenteilla `-l` ja `/usr/bin`. Taulukko `args` edustaa ohjelman argumentteja. Jos `execvp()` onnistuu, nykyinen prosessi korvataan ulkoisella ohjelmalla ja seuraavat rivit ohitetaan. Virhetilanteessa virheilmoitus näytetään `perror` kautta ja ohjelma palauttaa tilakoodin 1.

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

Käyttämällä `fork()` voit luoda uuden prosessin. Tässä aliprosessissa voit suorittaa toisen ohjelman käyttämällä `execvp`. Tämä mahdollistaa sen, että vanhempi prosessi voi jatkaa oman koodinsa suorittamista, kun uusi prosessi käynnistää ulkoisen ohjelman.

```c
#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;
}
```

Yllä olevassa esimerkissä loimme uuden prosessin käyttämällä `fork()`. Käyttämällä `execvp()`, `ls` ottaa haltuunsa lapsiprosessin sen argumenteilla. `waitpid`:lla vanhempi prosessi odottaa lapsiprosessin päättymistä ja tulostaa sitten viestin.


This is a markdown version of: [https://www.ionos.com/fi-fi/digitalguide/verkkosivustot/verkkosivujen-kehittaeminen/execvp/](https://www.ionos.com/fi-fi/digitalguide/verkkosivustot/verkkosivujen-kehittaeminen/execvp/) for AI/LLM consumption.