Calling Fork for a subprocess - c

I am implementing a shell in C but when Im using fork() it creates too child process.
Here is my code :
int exec_simple_command(struct ast_node_simple_command *node)
{
if (node == NULL)
return 1;
char **args = node->words;
if (args == NULL)
return 1;
pid_t pid = fork();
int status;
/* Error handling */
if (pid < 0)
return -1;
if (pid == 0) /* Child Process */
{
return exec_builtin(args);
}
else
{
if (waitpid(pid, &status, 0) < 0)
{
return 2;
}
return 0;
}
}
i have file with simple command to test my shell :
echo 1;
echo 2;
echo 3;
echo 4;
And here is the output i get :
1
2
3
4
4
3
4
4
2
3
4
4
3
4
4
every time I execute a new builtin it duplicates the number of child.
I just want to execute on child, wait before the child process terminated and then continue the rest of the program.
Thanks for your help.

Related

Value modification inside child doesn't update

Im trying to modify an int inside a child process when fork(); but I cant get the program to update it more than once, my idea is to add a counter that displays to screen that shows how many bg where (when & is at the end of the line), but I don't know why it's not working. Now I'm trying this but it doesn't work either, maybe I should modify the value in the parent process? This it the code:
void execute(char **tokens, int token_Size, int *blk){
pid_t pid, wpid;
int status;
int result;
int flag;
int isPipe;
int output;
int input;
int isAmper;
pid = fork();
if (pid == -1)
{
perror("Fork:");
exit(1);
}
else if (pid == 0)
{
isAmper = needs_amper(tokens, token_Size);
output = needs_out_redir(tokens, token_Size);
input = needs_in_redir(tokens, token_Size);
isPipe = needs_pipe(tokens, token_Size);
static int bloq = 1;
if (isAmper != -1)
{
*blk +=1;
printf("[%d] %d \n", *blk, getppid()); //-> [blk] is the job number asigned to the job
tokens[isAmper] = NULL;
}
if (strcmp(tokens[0], "echo") == 0)
{
for (int i = 1; tokens[i]; i++)
{
printf("%s ", tokens[i]);
}
}
flag = 0;
if (output != -1)
{
redirect_output(tokens, output);
tokens[output] = NULL;
flag = 1;
}
if (input != -1)
{
redirect_input(tokens, input);
tokens[input] = NULL;
flag = 1;
}
if (isPipe != -1)
{
create_pipe(tokens, output, input, isPipe);
}
if (flag || isPipe == -1)
{
execvp(tokens[0], tokens);
perror("Unkown Command:");
exit(1);
}
// exit(0);
}
else // Main (parent) process after fork succeeds
{
while ((wpid = wait(&status)) > 0)
; // this way, the father waits for all the child processes
result = waitpid(pid, &status, 0);
if (result == 1) //If the process terminated correctly, result returns 0.
{
printf("The child process terminated with an error!.\n");
}
}}
I'm trying to modify the blk value passed to the execute function, I tried using an inside value also, but doesnt work either.
To make my self clearer. I want that when I type in my custom shell something with an '&' at the end it return something like this:
ivo#ivo-Surface-Pro-6:/home/ivo/Documents/SO1/soi-myshell-Ivoo25$ echo hola &
[1] 10853
hola
And the next time I type something with the & at the end..
[2] 10853
main.c main.o Makefile myshell myShell.c myShell.h myShell.o README.md
I think that what Im trying to do cant be done because the pid is the same in every execution, maybe is that?
I managed to get it, I added the same function
needs_amper(tokens, token_Size)
but outside the child process, before the fork inside an if function veryfing that it returns a value higher than 0

Fork() to performe different processes

I'm trying to use the multiple fork() calls to create several children with different task
I found a code on
Multiple child process
Which is really close for what I want , yet I couldn't fully understand it
pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild != 0)
{
// In parent
secondChild = fork();
if(secondChild != 0)
{
// In parent
}
else
{
// In secondChild
}
}
else
{
// In firstChild
}
My questions are:
How many process have been created (I assume that we have 4 since it's 2 forks!)?
In this part of the code
firstChild = fork();
if(firstChild != 0)
{
// In parent
secondChild = fork();
if(secondChild != 0)
{
// In parent
}
Does "//in parent" mean both of them are the same process (they have the same PID when I tried to test it).
How can I create 3 children using 2 forks?( I can draw the tree that ends with 4 leaves 3 of them are children and 1 parent)
Thank you (please feel free to tell me if I'm not totally getting the Fork concept)
How many process have been created (I assume that we have 4 since it's 2 forks!)?
Depending on the result of your forks it should be 0 to 2. Probably 2 if nothing goes wrong. There's a parent process that forks 2 children processes.
Does "//in parent" mean both of them are the same process (they have the same PID when I tried to test it).
Yes. In your case the code is checking for a return value of fork being non zero. That's not a very good idea since it covers 2 distinct cases:
It could be less than zero indicating an error, or ...
It could be greater than zero indicating to the parent the pid of the newly spawned process
Anyway ... considering all goes well and both the forks succeed, you will end up with a parent process having 2 different children.
How can I create 3 children using 2 forks?( I can draw the tree that ends with 4 leaves 3 of them are children and 1 parent
Something like this should do the trick:
firstChild = fork();
if (firstChild < 0) {
exit(EXIT_FAILURE);
perror("fork");
}
secondChild = fork();
Notice that by not checking the return value of fork() any more I'm getting a child process continuing execution at the same place as the parent. So the next fork will actually be executed by both the parent and the children each spawning a new process. So I'll get something like this ...
parent─┬─child1───(child1's child)
└─child2
I can't think of any way you can get this with only 2 forks though:
parent─┬─child1
├─child3
└─child2
Note: It's customary on stackoverflow to only limit yourself to one question per topic.
The following code shows how to create 4 process (1 parent 3 children) with only 2 forks
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int *list;
void calculate_average(int );
void calculate_maximum(int);
void calculate_minimum(int);
void calculate_average(int count)
{
int i, total = 0;
for (i = 0; i < count; i++)
total += list[i];
double average = total / count;
printf("average is %f\n",average);
}
void calculate_maximum(int count)
{
int i;
int maximum = list[0];
for (i = 1; i < count; i++)
if (list[i] > maximum)
maximum = list[i];
printf("maximum is %d\n",maximum);
}
void calculate_minimum(int count)
{
int i;
int minimum = list[0];
for (i = 1; i < count; i++)
if (list[i] < minimum)
minimum = list[i];
printf("minimum is %d\n",minimum);
}
int main(int argc, char *argv[])
{
pid_t pid, pid1;
int num_of_args = argc-1;
int i;
/* allocate memory to hold array of integers */
list = malloc(sizeof(int)*num_of_args);
for (i = 0; i < num_of_args; i++)
list[i] = atoi(argv[i+1]);
printf("The %d number of input ingeters are\n",num_of_args);
for (i = 0; i < num_of_args; i++)
printf("%d\n",list[i]);
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0) { /* P2 */
pid1=getppid();
calculate_average(num_of_args);
}
else { /* P1 */
pid1=getpid();
wait(NULL);
}
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0) { /* could be either P3 or P4 */
if (getppid() == pid1) { /* P3 */
calculate_minimum(num_of_args);
}
else { /* P4 */
calculate_maximum(num_of_args);
}
}
else {
wait(NULL);
}
return 0;
}
Note that one of the children will be a parent for a grandchild

fork 3 child processes for 3 functions

I want to fork 3 child processes and have each process execute a function and busy wait until they are complete. The 3rd process is a countdown timer so once the runtime reaches 0 I will use an IPC to tell the other processes to exit. I have written the functions besides the IPC part and they run individually but I can't get fork() to create the 3 child processes to each execute a specific function.
int main(int argc, char *argv[]) {
pid_t child_onepid, child_twopid, child_threepid, pid;
for (i = 0; i < 3; ++i) {
pid = fork();
if (pid) {
continue;
} else if (pid == 0 && i == 0) {
show_time();
} else if (pid == 0 && i == 1) {
show_uptime();
} else if (pid == 0 && i == 2) {
show_timer(runtime);
} else {
printf("fork error\n");
exit(1);
}
}
return EXIT_SUCCESS;
}
This is my output
Time: 06/28/2014 18:55:57PM
Timer: 00:09
>Timer: 00:09
6:55pm up 171 day(s), 10:49, 17 users, load average: 0.34, 0.38, 0.43
6:55pm up 171 day(s), 10:49, 17 users, load average: 0.34, 0.38, 0.43
Your code looks fine to me, except your error test will never hit because the if(pid) will trigger on -1.
Besides that, are you supper sure that your functions are not returning and then going around their own copy of the for loop, that would explain the output... so I added some break to make sure of that.
But I've not tested the code.
int main(int argc, char *argv[]) {
pid_t pid;
for (int i = 0; i < 3; ++i) {
pid = fork();
if (pid == -1) {
perror("fork error\n");
exit(EXIT_FAILURE);
} else if (pid > 0)
continue;
} else if (i == 0) {
show_time();
break;
} else if (i == 1) {
show_uptime();
break;
} else if (i == 2) {
show_timer(runtime);
break;
}
}
return EXIT_SUCCESS;
}

Why isn't my piped grep working?

I've written my own shell in C, and when I run ls | grep .c, I get nothing. Although unpiped commands are working fine, like ls. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include "shell.h"
#include "builtins.h"
#include "makeargv.h"
void shell()
{
pid_t shell_pid;
int i;
int flag = 1;
int argc0;
int argc1;
int fdl[2];
int fdr[2];
size_t input_size;
char cwd[128]; //this is being toggled
char *delim0;
char *delim1;
char *lastarg;
char *input;
char *debugdescriptor;
char **argvp;
char **firstargs;
shell_pid = getpid();
do
{
// Retrieve PID & CWD of the parent process.
getcwd(cwd, (128 * sizeof(char)));
printf("{%i}%s$ ", shell_pid, cwd);
// Retrieve input from stdin.
input = NULL;
input_size = 0;
getline(&input, &input_size, stdin);
//seperates the input into pipe-delimited arguments("tokens")
delim1 = "|\n";
argc1 = makeargv(input, delim1, &argvp);
//got some debugging tools here
//debugdescriptor = "PIPE-SEPERATED";
//debug_args(&argvp, &argc1, debugdescriptor);
//check for quit and cd first
delim0 = " ";
argc0 = makeargv(argvp[0], delim0, &firstargs);
//more debugging tools here
//debugdescriptor = "FIRST ARGS";
//debug_args(&firstargs, &argc0, debugdescriptor);
//exit
if((i = strcmp(firstargs[0],"exit")) == 0 || (i = strcmp(firstargs[0],"quit")) == 0)
{
printf("===========SHELL TERMINATED==============\n\n");
flag = 0;
}
//cd
else if((i = strcmp(firstargs[0],"cd")) == 0)
{
chdir(firstargs[1]);
}
else // Create a child process to handle user input.
{
char **thisarg;
int childlayer = 0;
pid_t pid = fork();
wait(0);
if(pid == 0)
childlayer++;
int tokens = argc1 - 1;
if(argc1 == 1 && pid == 0)
{
makeargv(argvp[tokens], delim0, &thisarg);
execvp(thisarg[0], thisarg);
}
else //more than 1 arguement, (has pipes)
{
while(pid == 0 && childlayer < argc1){
if(childlayer == 1){ //rightmost
pipe(fdl);
pid = fork();
wait(0);
if(pid == 0)
childlayer++;
if(pid > 0){
close(fdl[1]);
dup2(fdl[0], STDIN_FILENO); //sets the final output to write to STDIN
execute(childlayer, argc1, &argvp);
}
}
else if(childlayer > 1 && childlayer < argc1-1){ //middle args
pipe(fdr);
fdr[1] = fdl[1];
fdr[0] = fdl[0];
dup2(fdr[1], STDOUT_FILENO);
pipe(fdl);
pid = fork();
wait(0);
if(pid == 0)
childlayer++;
if(pid > 0){
close(fdl[1]);
dup2(fdl[0], STDIN_FILENO);
execute(childlayer, argc1, &argvp);
}
}
else{ //leftmost
pipe(fdr);
fdr[0] = fdl[0];
fdr[1] = fdl[1];
close(fdr[0]);
dup2(fdr[1], STDOUT_FILENO);
execute(childlayer, argc1, &argvp);
}
}
}
}
}while(flag == 1);
}
I think I may be getting stuck in a child process when I use the pipes, but I haven't been able to see where. Thanks.
You are almost certainly failing to close all your file descriptors. One source of such an error is your dup2 calls.
After:
dup2(fdr[1], STDOUT_FILENO);
you should call
close(fdr[1]);
Why do you wait(0) immediately after fork()? In the child, this will return immediately with an error, but in the parent, it will block until the child exits. I'm having a hard time following how the pipeline is established because each child is forking off the next child in the pipeline. I'm guessing the wait(0) is creating a chicken-and-egg problem; the parent can't start until the child exits, but the child can't exit because it needs input from the parent. Wouldn't it be simpler if the shell process just looped over the pipeline components and forked each one itself, and then waited for them all to finish?

Implementation of multiple pipes in C

I'm trying to implement multiple pipes in my shell in C. I found a tutorial on this website and the function I made is based on this example. Here's the function
void executePipes(cmdLine* command, char* userInput) {
int numPipes = 2 * countPipes(userInput);
int status;
int i = 0, j = 0;
int pipefds[numPipes];
for(i = 0; i < (numPipes); i += 2)
pipe(pipefds + i);
while(command != NULL) {
if(fork() == 0){
if(j != 0){
dup2(pipefds[j - 2], 0);
}
if(command->next != NULL){
dup2(pipefds[j + 1], 1);
}
for(i = 0; i < (numPipes); i++){
close(pipefds[i]);
}
if( execvp(*command->arguments, command->arguments) < 0 ){
perror(*command->arguments);
exit(EXIT_FAILURE);
}
}
else{
if(command != NULL)
command = command->next;
j += 2;
for(i = 0; i < (numPipes ); i++){
close(pipefds[i]);
}
while(waitpid(0,0,0) < 0);
}
}
}
After executing it and typing a command like for example ls | grep bin, the shell just hangs there and doesn't output any result. I made sure I closed all pipes. But it just hangs there. I thought that it was the waitpid that's was the problem. I removed the waitpid and after executing I get no results. What did I do wrong? Thanks.
Added code:
void runPipedCommands(cmdLine* command, char* userInput) {
int numPipes = countPipes(userInput);
int status;
int i = 0, j = 0;
pid_t pid;
int pipefds[2*numPipes];
for(i = 0; i < 2*(numPipes); i++){
if(pipe(pipefds + i*2) < 0) {
perror("pipe");
exit(EXIT_FAILURE);
}
}
while(command) {
pid = fork();
if(pid == 0) {
//if not first command
if(j != 0){
if(dup2(pipefds[(j-1) * 2], 0) < 0){
perror(" dup2");///j-2 0 j+1 1
exit(EXIT_FAILURE);
//printf("j != 0 dup(pipefd[%d], 0])\n", j-2);
}
//if not last command
if(command->next){
if(dup2(pipefds[j * 2 + 1], 1) < 0){
perror("dup2");
exit(EXIT_FAILURE);
}
}
for(i = 0; i < 2*numPipes; i++){
close(pipefds[i]);
}
if( execvp(*command->arguments, command->arguments) < 0 ){
perror(*command->arguments);
exit(EXIT_FAILURE);
}
} else if(pid < 0){
perror("error");
exit(EXIT_FAILURE);
}
command = command->next;
j++;
}
for(i = 0; i < 2 * numPipes; i++){
close(pipefds[i]);
puts("closed pipe in parent");
}
while(waitpid(0,0,0) <= 0);
}
}
I believe the issue here is that your waiting and closing inside the same loop that's creating children. On the first iteration, the child will exec (which will destroy the child program, overwriting it with your first command) and then the parent closes all of its file descriptors and waits for the child to finish before it iterates on to creating the next child. At that point, since the parent has closed all of its pipes, any further children will have nothing to write to or read from. Since you are not checking for the success of your dup2 calls, this is going un-noticed.
If you want to keep the same loop structure, you'll need to make sure the parent only closes the file descriptors that have already been used, but leaves those that haven't alone. Then, after all children have been created, your parent can wait.
EDIT: I mixed up the parent/child in my answer, but the reasoning still holds: the process that goes on to fork again closes all of its copies of the pipes, so any process after the first fork will not have valid file descriptors to read to/write from.
pseudo code, using an array of pipes created up-front:
/* parent creates all needed pipes at the start */
for( i = 0; i < num-pipes; i++ ){
if( pipe(pipefds + i*2) < 0 ){
perror and exit
}
}
commandc = 0
while( command ){
pid = fork()
if( pid == 0 ){
/* child gets input from the previous command,
if it's not the first command */
if( not first command ){
if( dup2(pipefds[(commandc-1)*2], 0) < ){
perror and exit
}
}
/* child outputs to next command, if it's not
the last command */
if( not last command ){
if( dup2(pipefds[commandc*2+1], 1) < 0 ){
perror and exit
}
}
close all pipe-fds
execvp
perror and exit
} else if( pid < 0 ){
perror and exit
}
cmd = cmd->next
commandc++
}
/* parent closes all of its copies at the end */
for( i = 0; i < 2 * num-pipes; i++ ){
close( pipefds[i] );
}
In this code, the original parent process creates a child for each command and therefore survives the entire ordeal. The children check to see if they should get their input from the previous command and if they should send their output to the next command. Then they close all of their copies of the pipe file descriptors and then exec. The parent doesn't do anything but fork until it's created a child for each command. It then closes all of its copies of the descriptors and can go on to wait.
Creating all of the pipes you need first, and then managing them in the loop, is tricky and requires some array arithmetic. The goal, though, looks like this:
cmd0 cmd1 cmd2 cmd3 cmd4
pipe0 pipe1 pipe2 pipe3
[0,1] [2,3] [4,5] [6,7]
Realizing that, at any given time, you only need two sets of pipes (the pipe to the previous command and the pipe to the next command) will simplify your code and make it a little more robust. Ephemient gives pseudo-code for this here. His code is cleaner, because the parent and child do not have to do unnecessary looping to close un-needed file descriptors and because the parent can easily close its copies of the file descriptors immediately after the fork.
As a side note: you should always check the return values of pipe, dup2, fork, and exec.
EDIT 2: typo in pseudo code. OP: num-pipes would be the number of pipes. E.g., "ls | grep foo | sort -r" would have 2 pipes.
Here's the correct functioning code
void runPipedCommands(cmdLine* command, char* userInput) {
int numPipes = countPipes(userInput);
int status;
int i = 0;
pid_t pid;
int pipefds[2*numPipes];
for(i = 0; i < (numPipes); i++){
if(pipe(pipefds + i*2) < 0) {
perror("couldn't pipe");
exit(EXIT_FAILURE);
}
}
int j = 0;
while(command) {
pid = fork();
if(pid == 0) {
//if not last command
if(command->next){
if(dup2(pipefds[j + 1], 1) < 0){
perror("dup2");
exit(EXIT_FAILURE);
}
}
//if not first command&& j!= 2*numPipes
if(j != 0 ){
if(dup2(pipefds[j-2], 0) < 0){
perror(" dup2");///j-2 0 j+1 1
exit(EXIT_FAILURE);
}
}
for(i = 0; i < 2*numPipes; i++){
close(pipefds[i]);
}
if( execvp(*command->arguments, command->arguments) < 0 ){
perror(*command->arguments);
exit(EXIT_FAILURE);
}
} else if(pid < 0){
perror("error");
exit(EXIT_FAILURE);
}
command = command->next;
j+=2;
}
/**Parent closes the pipes and wait for children*/
for(i = 0; i < 2 * numPipes; i++){
close(pipefds[i]);
}
for(i = 0; i < numPipes + 1; i++)
wait(&status);
}
The (shortened) relevant code is:
if(fork() == 0){
// do child stuff here
....
}
else{
// do parent stuff here
if(command != NULL)
command = command->next;
j += 2;
for(i = 0; i < (numPipes ); i++){
close(pipefds[i]);
}
while(waitpid(0,0,0) < 0);
}
Which means the parent (controlling) process does this:
fork
close all pipes
wait for child process
next loop / child
But it should be something like this:
fork
fork
fork
close all pipes (everything should have been duped now)
wait for childs
You only need two pipes alternating like below:
typedef int io[2];
extern int I; //piped command current index
extern int pipe_count; //count of '|'
#define CURRENT 0
#define PREVIOUS 1
#define READ 0
#define WRITE 1
#define is_last_command (I == pipe_count)
bool connect(io pipes[2])
{
if (pipe_count)
{
if (is_last_command || I != 0)
dup2(pipes[PREVIOUS][READ], STDIN_FILENO);
if (I == 0 || !is_last_command)
dup2(pipes[CURRENT][WRITE], STDOUT_FILENO);
}
return (true);
}
void close_(io pipes[2])
{
if (pipe_count)
{
if (is_last_command || I != 0)
close(pipes[PREVIOUS][READ]);
if (I == 0 || !is_last_command)
close(pipes[CURRENT][WRITE]);
}
}
void alternate(int **pipes)
{
int *pipe_current;
pipe_current = pipes[CURRENT];
pipes[CURRENT] = pipes[PREVIOUS];
pipes[PREVIOUS] = pipe_current;
}
Example usage:
#define ERROR -1
#define CHILD 0
void execute(char **command)
{
static io pipes[2];
if (pipe_count && pipe(pipes[CURRENT]) == ERROR)
exit_error("pipe");
if (fork()==CHILD && connect(pipes))
{
execvp(command[0], command);
_exit(EXIT_FAILURE);
}
while (wait(NULL) >= 0);
close_(pipes);
alternate((int **)pipes);
}
static void run(char ***commands)
{
for (I = 0; commands[I]; I++)
if (*commands[I])
execute(commands[I]);
}
I'll leave a link to a full working code for someone who needs it.
Building upon the idea of using a maximum of two pipes at a given time mentioned by Christopher Neylan, I put together pseudocode for n-pipes. args is an array of character pointers of size 'args_size' which is a global variable.
// MULTIPLE PIPES
// Test case: char *args[] = {"ls", "-l", "|", "head", "|", "tail", "-4",
0};// "|", "grep", "Txt", 0};
enum fileEnd{READ, WRITE};
void multiple pipes( char** args){
pid_t cpid;
// declare pipes
int pipeA[2]
int pipeB[2]
// I have done getNumberofpipes
int numPipes = getNumberOfPipes;
int command_num = numPipes+1;
// holds sub array of args
// which is a statement to execute
// for example: cmd = {"ls", "-l", NULL}
char** cmd
// iterate over args
for(i = 0; i < args_size; i++){
//
// strip subarray from main array
// cmd 1 | cmd 2 | cmd3 => cmd
// cmd = {"ls", "-l", NULL}
//Open/reopen one pipe
//if i is even open pipeB
if(i % 2) pipe(pipeB);
//if i is odd open pipeA
else pipe(pipeA);
switch(cpid = fork(){
case -1: error forking
case 0: // child process
childprocess(i);
default: // parent process
parentprocess(i, cpid);
}
}
}
// parent pipes must be closed in parent
void parentprocess(int i, pid_t cpid){
// if first command
if(i == 0)
close(pipeB[WRITE]);
// if last command close WRITE
else if (i == numPipes){
// if i is even close pipeB[WRITE]
// if i is odd close pipeA[WRITE]
}
// otherwise if in middle close READ and WRITE
// for appropriate pipes
// if i is even
close(pipeA[READ])
close(pipeB[WRITE])
// if i is odd
close(pipeB[READ])
close(pipeA[WRITE])
}
int returnvalue, status;
waitpid(cpid, returnvalue, status);
}
void childprocess(int i){
// if in first command
if(i == 0)
dup2(pipeB[WRITE], STDOUT_FILENO);
//if in last command change stdin for
// the necessary pipe. Don't touch stdout -
// stdout goes to shell
else if( numPipes == i){
// if i is even
dup2(pipeB[READ], STDIN_FILENO)
//if i is odd
dup2(pipeA[READ], STDIN_FILENO);
}
// otherwise, we are in middle command where
// both pipes are used.
else{
// if i is even
dup2(pipeA[READ], STDIN_FILENO)
dupe(pipeB[WRITE], STDOUT_FILENO)
// if i is odd
dup2(pipeB[READ], STDIN_FILENO)
dup2(pipeA[WRITE], STDOUT_FILENO)
}
// execute command for this iteration
// check for errors!!
// The exec() functions only return if an error has occurred. The return value is -1, and errno is set to indicate the error.
if(exec(cmd, cmd) < 0)
printf("Oh dear, something went wrong with read()! %s\n", strerror(errno));
}
}
Basically what you wanna do is a recursive function where the child executes the first command and the parent executes the second one if no other commands are left or calls the function again.

Resources