
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>

#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif

#ifndef _WIN32

int open_read(const char *fname) {
  return open(fname, O_RDONLY);
}

int open_write(const char *fname) {
  return open(fname, O_WRONLY | O_TRUNC | O_CREAT,
              S_IWUSR | S_IRUSR | S_IROTH | S_IRGRP);
}

#include <sys/wait.h>
#include <signal.h>

/* This waits and then returns the exit status of the process that was
   waited for. */
int smart_wait(int pid) {
  int stat;
  pid_t rc;

  do {
      rc = waitpid(pid, &stat, 0);
  } while(rc < 0 && errno == EINTR);

  if(rc < 0) {
    perror("waitpid");
    return -138;
  } else if (WIFEXITED(stat)) {
    return WEXITSTATUS(stat);
  } else if (WIFSIGNALED(stat)) {
    psignal(WTERMSIG(stat), "Error in subprocess");
    return - WTERMSIG(stat);
  } else {
    return -137;
  }
}

#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>

int execvp_no_vtalarm(const char *file, char *const argv[]) {
  /* Reset the itimers in the child, so it doesn't get plagued
   * by SIGVTALRM interrupts.
   */
  struct timeval tv_null = { 0, 0 };
  struct itimerval itv;
  itv.it_interval = tv_null;
  itv.it_value = tv_null;
  setitimer(ITIMER_REAL, &itv, NULL);
  setitimer(ITIMER_VIRTUAL, &itv, NULL);
  setitimer(ITIMER_PROF, &itv, NULL);
  execvp(file, argv);
  perror("Error in execvp");
  return errno;
}

#include <sys/types.h>
#include <sys/stat.h>
#endif

