Hello guys so my code is supposed to create an unlimited amount of processes each running their own program and communicating threw pipes..
This is done in a recursive way so that the first parent creates a pipe then a child.. After this the child does the same creating a pipe2 and child2 etc....
Problem is that the parent process doesn't want to wait for all the children to be created and when I try to insert
waitpid(childpid, NULL, 0);
it kinda waits forever... So either I want the last child to send some kind of STOP WAIT signal or I would like another way to solve this problem!
Here is the code:
/* workForce.c
 * 
 * Program created by ----Secret-----
 * 
 * Input has to be the programs you wish the workForce to execute with following parameters seperated by '0's
 * 
 * example input:
 * printenv 0 grep L 0 sort
 * 
 * Will result in the command: printenv | grep L | sort | chosen PAGER
 * 
 * The program will pipe each unit of the workForce to the next unit untill it reaches the last unit where
 * it will printout the result to STDOUT.
 */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define PIPE_READ_SIDE ( 0 )
#define PIPE_WRITE_SIDE ( 1 )
pid_t childpid; /* för child-processens PID vid fork() */
/*
 * The generateWorkforce method automaticly creates it's own workforce with one process per taskset
 * Each unit in the work force will execute the parameters provided
 * As long as it's not the end of the workforce the unit will pipe its output to the next unit
 */
void generateWorkforce(int taskpointer, int totaltasks, int taskset[], char* tasks[]){
/* Create pipe then fork */
int pipe_filedesc[ 2 ];
int return_value;
return_value = pipe( pipe_filedesc );
if( -1 == return_value ) {perror( "Cannot create pipe" ); exit( 1 );}
childpid = fork();
if( 0 == childpid )
{
    /* Redirecting STDIN to now read from pipe instead and removing the pipe */
    return_value = dup2( pipe_filedesc[ PIPE_READ_SIDE], STDIN_FILENO );
    if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}     
    return_value = close( pipe_filedesc[PIPE_READ_SIDE] );
    if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
    return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
    if( -1 == return_value ){perror( "Cannot close write end" ); exit( 1 );}
    if(taskpointer < totaltasks-1){
        generateWorkforce((taskpointer+taskset[taskpointer]), totaltasks, taskset, tasks);
    }
    else {
        kill(getppid, SIGINT);
        execlp(tasks[taskpointer], tasks[taskpointer], (char *) 0);
        /* exec only returns if an error occured */
        perror( "Cannot exec execute[pointer]" );
        exit( 1 );
    }
}
else
{
    if( -1 == childpid ){   perror( "Cannot fork()" );  exit( 1 );} 
    /* Redirecting STDOUT to write to pipe instead and thereafter removes the pipe */
    return_value = dup2( pipe_filedesc[ PIPE_WRITE_SIDE], STDOUT_FILENO );
    if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}
    return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
    if( -1 == return_value ){perror( "Cannot close write end" ); exit( 1 );}
    return_value = close( pipe_filedesc[ PIPE_READ_SIDE ] );
    if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
    waitpid(childpid, NULL, 0);
    /* Will define what task to execute and how many parameters it needs */
    if(taskset[taskpointer] > 1){
        char* execute[taskset[taskpointer]+1];
        int i;
        char* executeHead = tasks[taskpointer];
        execute[0] = tasks[taskpointer];
        for(i = 1;i<taskset[taskpointer];i++){
            execute[i] = tasks[taskpointer+i];
        }
        execute[taskset[taskpointer]] = (char *) 0;
        (void) execvp( executeHead, execute );
    }
    else{
        (void) execlp( tasks[taskpointer], tasks[taskpointer], (char *) 0 );
    }
    /* exec only returns if an error occured */
    perror( "Cannot exec tasks[taskpointer]" );
    exit( 1 );
}
}
int main( int argc, char * argv[] )
{
/* The following block will determine how many tasksets was in the input */
char * separator = "0";
int i;
int j;
int tasknr = 1;
for(i = 1, j = 1;i<(argc);i++)
{
    if(!(strcmp(argv[(i)], separator ))){
        j++;
    }
    else{
        tasknr++;
    }
}
char* execute[tasknr];
int taskset[j+1];
/* Will fill the taskset array and execute array */
if(getenv("PAGER")) execute[(tasknr-1)] = getenv("PAGER");
else execute[(tasknr-1)] = "less";
taskset[j] = 1;
taskset[0] = 0;
int k = 0;
for(i = 1, j = 0;i<(argc);i++)
{
    if(!(strcmp(argv[(i)], separator ))){
        j++;
        taskset[j] = 0;
    }
    else{
        execute[k] = argv[i];
        taskset[j]++;
        k++;
    }
}
generateWorkforce(0, tasknr, taskset, execute);
exit( 0 );
}
EDIT: the kill(getppid, SIGINT); was an attempt to stop the wait!