// ----------------------------------------------------------------------------
//
//  Copyright (C) 2003-2013 Fons Adriaensen <fons@linuxaudio.org>
//    
//  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; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "extproc.h"



Extproc::Extproc (const char *shmname, size_t shmsize) :
    _shmem (0)
{
    if (shmsize)
    {
	sprintf (_shmname, "/%s-%d", shmname, getpid ());
        _shmem = new Shmem (_shmname, shmsize, true);
    }
    else *_shmname = 0;
    _procid = 0;
    _procrc = 0;
}


Extproc::~Extproc (void)
{
    wait ();
    delete _shmem;
    shm_unlink (_shmname);
}


int Extproc::start (const char *prefix, const char *procfile)
{
    int p, k = 0;
  
    if (prefix) _args [k++] = (char *) prefix;
    _args [k++] = (char *) procfile;
    _args [k++] = _shmname;
    _args [k] = 0;
    _procid = 0;
    p = fork ();
    if (p == 0)
    {
	if (execvp (_args [0], _args) < 0)
	{
	    perror ("execvp");
            return -1;    
	}
    }
    if (p < 0)
    {
       perror ("fork:");
       return -2;
    }
    _procid = p;
    _procrc = 0;
    return 0;
}


int Extproc::kill (void)
{
    if (_procid && ::kill (_procid, SIGINT))
    {
       perror ("kill:");
       return -1;
    }
    return 0;
}


int Extproc::wait (void)
{
    if (_procid && waitpid (_procid, &_procrc, 0) < 0)
    {
       perror ("wait:");
       return -1;
    }
    return 0;
}

