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);
}
}