/******************************************************************************
*   CreateProcess
*
*   Copyright (C) 2010 Andrew Smith
*
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, version 2 of the License only, not
*   any earlier or later version.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/******************************************************************************
*  CreateProcess function: a simple way for Linux/Unix to call programs 
* without blocking and without the complications of fork()/exec() which 
* normal people shouldn't need to understand :)
*
*  Usage example:

#include "CreateProcess.h"

int main(void)
{
    // Call it like this:
    CreateProcess("ls", "-a -l --sort=size");
    
    // Or like this:
    CreateProcess("date", NULL);
    
    // Note that the second call does not wait for the first to finish
    // as system() would
    
    return 0;
}

* Enjoy!
* - Andrew Smith
*/

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

pid_t CreateProcess(const char* command, const char* parametersIn)
{
    const int maxNumArgs = 1024;
    const char* args[maxNumArgs];
    char* parameters = NULL;
    
    memset(args, 0, (sizeof(char*) * maxNumArgs));
    args[0] = command;
    
    if(parametersIn != NULL)
    {
        parameters = strdup(parametersIn);
        int strLen = strlen(parameters);
        
        int numParameters = 1;
        bool expectNextParam = true;
        int i;
        for(i = 0; i < strLen; i++)
        {
            if(parameters[i] == ' ' || parameters[i] == '\t' || 
               parameters[i] == '\n')
            {
                expectNextParam = true;
                parameters[i] = '\0';
            }
            else if(expectNextParam)
            {
                args[numParameters] = &(parameters[i]);
                numParameters++;
                expectNextParam = false;
            }
        }
    }
    
    pid_t pid = fork();
    if(pid == 0)
    {
        execvp(command, (char**)args);
        _exit(1);
    }
    
    if(parameters != NULL)
        free(parameters);
    
    return pid;
}
