// KreateCD - CD recording software for the K desktop environment
//
// 1998 by Alexander Feigl <Alexander.Feigl@gmx.de>
//
// This file is subject to the terms and conditions of the GNU General
// Public License.  See the file COPYING in the main directory of the
// KreateCD distribution for more details.

#include "Fork.h"
#include <stdlib.h>

Fork::Fork(int (*fx)(int argc,char **argv)):KProcess()
 {
  function=fx;
  fmode=0;
 }

Fork::Fork(int (*fx)(AudioFile *afi,const char *fn),AudioFile *afil,const char *snx):KProcess()
 {
  function_af1=fx;
  AFile=afil;
  fmode=1;
  strcpy(strarg,snx);
 }

bool Fork::start(RunMode runmode, Communication comm)
{
  unsigned int i;
  unsigned int n = arguments.count();
  char **arglist;

  if (runs || ( (n == 0) && (fmode==0)) ) return (FALSE);

  run_mode = runmode;
  status = 0;
  arglist=0;


  switch (fmode)
   {
    case 0: // setup an arglist
     {
      arglist=(char **) malloc(sizeof(char **)*n);
      if (arglist==0) return (FALSE);

      for (i=0; i < n; i++)
       {
        arglist[i]= arguments.at(i);
       }
      }
   }


  if (!setupCommunication(comm))
    debug("Could not setup Communication!");

  runs = TRUE;
  pid = fork();

  if (pid==0)
   {
	// child

	if(!commSetupDoneC())
	  debug("Could not finish comm setup in child!");
	if (run_mode == DontCare)
          setpgid(0,0);
        switch (fmode)
         {
          case 0:   // run as virtual shell command
             exit(function(n,arglist));
          case 1:
             exit(function_af1(AFile,strarg));

         }
   }
   else if (pid == -1)
          {
	   // forking failure
	   runs = FALSE;
	   free(arglist);
           return FALSE;

          } else {
	          // parent

	          if (!commSetupDoneP())
	          debug("Could not finish comm setup in parent!");

	          input_data = 0;

	          if (run_mode == Block)
                   {
	            waitpid(pid, &status, 0);
	            processHasExited(status);
	           }
                 }
 free(arglist);
 return TRUE;
}

bool Fork::writeStdIn(char *buffer,int bufflen)
 {
  if (write(in[1],buffer,bufflen)!=bufflen) return(FALSE);
  return(TRUE);
 }

