how to you use execvp() one by one

Viewed 41

I want to use execvp twice 1 by 1 for 2 commands, the new program I want to awake is hcp with a couple of parameters and I am using this like that

int pid = 0;
char* spec_command[] = {"/usr/bin/hcp", "--enable-product","Performance", NULL};
char* spec_command2[] = {"/usr/bin/hcp", "--enable-product","Threat Prevention", NULL};
pid = fork();
if (pid == 0) 
{
    execvp("/usr/bin/hcp", spec_command);
    execvp("/usr/bin/hcp", spec_command2);
}

but just one of them is executed? how can I cause both of them work? thanks

Edit-----

didnt work :( my code

const char* spec_command[] = {"/usr/bin/hcp", "--enable-product","Performance", NULL};

const char* spec_command2[] = {"/usr/bin/hcp", "--enable-product","Threat Prevention", NULL}; 

disableThreatPrevention(spec_command); 

disableThreatPrevention(spec_command2);



void disableThreatPrevention(const char* spec_command[]) { 

int pid = 0 ;
 pid = fork(); 
if (pid == 0) 
{ 
   execvp("/usr/bin/hcp", spec_command) 
   exit(1);
}
}
1 Answers

You need to fork() twice since execvp replaces the current process completely and never returns (unless it fails).

Example:

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

void run(const char* file, char* argv[]) {
    pid_t pid = fork();
    if (pid == 0)
    {
        execvp(file, argv);
        exit(1);
    }
}

int main(void) {
    char* spec_command[] = {"/usr/bin/hcp", "--enable-product", "Performance",
                            NULL};
    char* spec_command2[] = {"/usr/bin/hcp", "--enable-product",
                             "Threat Prevention", NULL};
    run("/usr/bin/hcp", spec_command);
    run("/usr/bin/hcp", spec_command2);

    int wstatus;
    while(wait(&wstatus) != -1) {}
}

This runs both commands in parallel. If you want to wait for the first one to finish before starting the second one, put a wait after the first run too - or in the the run function. If you want to continue the program without waiting for the processes to finish, skip the wait.


If you want to run the commands in sequence - but still in the background, you could expand the above further by giving all commands to run as an array to run and loop over them and execute them one-by-one in a background process.

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

typedef struct {
    const char *filepath;
    char **argv;
} command;

pid_t run_in_sequence_in_background(command cmds[], size_t count) {
    pid_t pid = fork();
    if (pid == 0) {
        // in first child
        // loop over all the commands and run them one by one in sequence
        for(size_t i = 0; i < count; ++i) {
            pid = fork();
            if(pid == 0) {
                // in grandchild
                execvp(cmds[i].filepath, cmds[i].argv);
                fprintf(stderr, "FAILED TO START %s\n", cmds[i].filepath);
                exit(1);
            } else if(pid != -1) {
                // in first child, wait for the grandchild
                int wstatus;
                waitpid(pid, &wstatus, 0);
            }
        }
        exit(0);
    }
    return pid;
}


int main() {
    char* spec_command[] = {"/usr/bin/hcp", "--enable-product", "Performance",
                            NULL};
    char* spec_command2[] = {"/usr/bin/hcp", "--enable-product",
                             "Threat Prevention", NULL};

    command cmds[] = {
        {"/usr/bin/hcp", spec_command},
        {"/usr/bin/hcp", spec_command2}
    };

    pid_t pid = run_in_sequence_in_background(cmds, sizeof cmds / sizeof *cmds);

    // do other stuff - the hcp commands runs in the background now

    // if you want to wait for the background process:
    if(pid != -1) {
        int wstatus;
        waitpid(pid, &wstatus, 0);
    }
}

or simpler, let argv[0] in your spec_commands be the filename to execute:

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

pid_t run_in_sequence_in_background(char **cmds[], size_t count) {
    pid_t pid = fork();
    if (pid == 0) {
        // in first child
        // loop over all the commands and run them one by one in sequence
        for(size_t i = 0; i < count; ++i) {
            pid = fork();
            if(pid == 0) {
                // in grandchild
                execvp(cmds[i][0], cmds[i]);
                fprintf(stderr, "FAILED TO START %s\n", cmds[i][0]);
                exit(1);
            } else if(pid != -1) {
                // in first child, wait for the grandchild
                int wstatus;
                waitpid(pid, &wstatus, 0);
            }
        }
        exit(0);
    }
    return pid;
}


int main() {
    char* spec_command[] = {"/usr/bin/hcp", "--enable-product", "Performance",
                            NULL};
    char* spec_command2[] = {"/usr/bin/hcp", "--enable-product",
                             "Threat Prevention", NULL};

    char** cmds[] = {spec_command, spec_command2};

    pid_t pid = run_in_sequence_in_background(cmds, sizeof cmds / sizeof *cmds);

    // do other stuff - the hcp commands runs in the background now

    // if you want to wait for the background process:
    if(pid != -1) {
        int wstatus;
        waitpid(pid, &wstatus, 0);
    }
}
Related