#include "bbs.h"

#ifndef WCOREDUMP
#define WCOREDUMP(x) 0
#endif

static volatile PID_T execute_pid;

int execute(const char *path, char *const args[], const int loglevel,
            confrecordtyp *confrecord)
{
  int rw, sig;
  int status;
  void (*oldsigint)();

  if ( (execute_pid = fork()) < 0 ) {
    errormsg(E_LOGFILE|E_USER,confrecord,"bbs","execute","fork: %m");
    return -1;
  }
  if ( execute_pid == 0 ) {
    setsighandler(SIGINT, SIG_DFL);
    execv(path, args);
    errormsg(E_LOGFILE|E_USER,confrecord,"bbs","execute","execv %s: %m",path);
    exit(1);
  }
  else {
    oldsigint = setsighandler(SIGINT, executesighandler);
  }
  while (wait(&status) != execute_pid );
  setsighandler(SIGINT, oldsigint);
  rw = status;
  if (WIFEXITED(status)) {
    rw = WEXITSTATUS(status);
  }
  if (loglevel > 1) {
    if (WIFEXITED(status)) {
      bbslog(LOG_FILE,confrecord,"%s exited, return: %i",args[0],rw);
    }
    if (WIFSIGNALED(status)) {
      sig = WTERMSIG(status);
      bbslog(LOG_FILE,confrecord,"%s got signal %i", args[0], sig);
      if (WCOREDUMP(status)) {
        bbslog(LOG_FILE,confrecord,"%s dumped core",args[0]);
      }
    }
  }
#if 0
  if (loglevel > 1) {
    if (WIFEXITED(status)) {
      printf("%s exited, return: %i\n", args[0], rw);
    }
    if (WIFSIGNALED(status)) {
      sig = WTERMSIG(status);
      printf("%s got signal %i\n", args[0], sig);
      if (WCOREDUMP(status)) {
        printf("%s dumped core\n",args[0]);
      }
    }
  }
#endif
  return rw;
}


void executesighandler(int sig)
{
  kill(execute_pid,sig);
}
