FRI-OS
example/posix/processes-launcher.c

Shows how to execute commands in subprocesses

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
// parses a command line, forks, executes
// the command in the child process and waits
// for it to finish
bool parse_exec_and_wait(char* cmd_line)
{
// fork
pid_t pid = fork();
// if there was an error complain and quit
if(pid < 0)
{
perror("Fork failed");
return false;
}
// if we are in the child process
else if(pid == 0)
{
size_t max_args = 31;
char* args[32];
int arg = 0;
// parse the command line strings
char *p, *s;
const char *delim = " \t\r\n\0";
p = strtok_r(cmd_line, delim, &s);
while(p)
{
if(arg == max_args) break;
args[arg++] = p;
p = strtok_r(NULL, delim, &s);
}
// terminate the list of arguments
args[arg] = NULL;
// execute the command
execvp(args[0], args);
// if we're here something went wrong
// complain and exit
printf("Failed to execute '%s'\n", cmd_line);
return false;
}
// if we are in the parent process
else
{
// wait for the child to finish
int status = 0;
waitpid(pid, &status, 0);
if(WIFSIGNALED(status))
printf("Terminated by signal %d\n", WTERMSIG(status));
}
return true;
}
int main(int argc, const char* argv[])
{
// a buffer for the command line
size_t size = 1023;
char buffer[1024];
// print the prompt and read a single line
while(fputs("$>", stdout), fgets(buffer, size, stdin))
{
// terminate the string (just in case)
buffer[size] = '\0';
// if the user typed 'exit' - exit
if(strncmp(buffer, "exit", 4) == 0) break;
// otherwise parse and execute the command
else if(!parse_exec_and_wait(buffer)) return 1;
}
fputc('\n', stdout);
return 0;
}