/* POSIX-based operating system interface for GNU Make.
Copyright (C) 2016 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make 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.

GNU Make 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 "makeint.h"

#include <stdio.h>

#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif

#include "debug.h"
#include "job.h"
#include "os.h"

#ifdef MAKE_JOBSERVER

/* This section provides OS-specific functions to support the jobserver.  */

/* These track the state of the jobserver pipe.  Passed to child instances.  */
static int job_fds[2] = { -1, -1 };

/* Used to signal read() that a SIGCHLD happened.  Always CLOEXEC.  */
static int job_rfd = -1;

/* Token written to the pipe (could be any character...)  */
static char token = '+';

static int
make_job_rfd ()
{
  EINTRLOOP (job_rfd, dup (job_fds[0]));
  if (job_rfd >= 0)
    CLOSE_ON_EXEC (job_rfd);

  return job_rfd;
}

void
jobserver_setup (int slots)
{
  int r;

  EINTRLOOP (r, pipe (job_fds));
  if (r < 0)
    pfatal_with_name (_("creating jobs pipe"));

  if (make_job_rfd () < 0)
    pfatal_with_name (_("duping jobs pipe"));

  while (slots--)
    {
      EINTRLOOP (r, write (job_fds[1], &token, 1));
      if (r != 1)
        pfatal_with_name (_("init jobserver pipe"));
    }
}

void
jobserver_parse_arg (const char* arg)
{
  /* Given the command-line parameter, parse it.  */
  if (sscanf (arg, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
    OS (fatal, NILF,
        _("internal error: invalid --jobserver-fds string '%s'"), arg);

  DB (DB_JOBS,
      (_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));

#ifdef HAVE_FCNTL
# define FD_OK(_f) ((fcntl ((_f), F_GETFD) != -1) || (errno != EBADF))
#else
# define FD_OK(_f) 1
#endif

  /* Create a duplicate pipe, that will be closed in the SIGCHLD handler.  If
     this fails with EBADF, the parent has closed the pipe on us because it
     didn't think we were a submake.  If so, warn then default to -j1.  */
  if (!FD_OK (job_fds[0]) || !FD_OK (job_fds[1]) || make_job_rfd () < 0)
    {
      if (errno != EBADF)
        pfatal_with_name (_("dup jobserver"));

      O (error, NILF,
         _("warning: jobserver unavailable: using -j1.  Add '+' to parent make rule."));

      job_slots = 1;
      job_fds[0] = job_fds[1] = -1;
    }
}

char *
jobserver_get_arg ()
{
  char *fds = xmalloc ((INTSTR_LENGTH * 2) + 2);
  sprintf (fds, "%d,%d", job_fds[0], job_fds[1]);
  return fds;
}

unsigned int
jobserver_enabled ()
{
  return job_fds[0] >= 0;
}

void
jobserver_clear ()
{
  if (job_fds[0] >= 0)
    close (job_fds[0]);
  if (job_fds[1] >= 0)
    close (job_fds[1]);
  if (job_rfd >= 0)
    close (job_rfd);

  job_fds[0] = job_fds[1] = job_rfd = -1;
}

void
jobserver_release (int is_fatal)
{
  int r;
  EINTRLOOP (r, write (job_fds[1], &token, 1));
  if (r != 1)
    {
      if (is_fatal)
        pfatal_with_name (_("write jobserver"));
      perror_with_name ("write", "");
    }
}

unsigned int
jobserver_acquire_all ()
{
  unsigned int tokens = 0;

  /* Close the write side, so the read() won't hang.  */
  close (job_fds[1]);
  job_fds[1] = -1;

  while (1)
    {
      char intake;
      int r;
      EINTRLOOP (r, read (job_fds[0], &intake, 1));
      if (r != 1)
        return tokens;
      ++tokens;
    }
}

/* This is really only invoked on OS/2.
   On POSIX we just call jobserver_clear() in the child process.  */
void jobserver_pre_child ()
{
  CLOSE_ON_EXEC (job_fds[0]);
  CLOSE_ON_EXEC (job_fds[1]);
}

void jobserver_post_child ()
{
#if defined(F_GETFD) && defined(F_SETFD)
  for (int i = 0; i < 2; ++i)
    {
      int flags;
      EINTRLOOP (flags, fcntl (job_fds[i], F_GETFD));
      if (flags >= 0)
        {
          int r;
          EINTRLOOP (r, fcntl (job_fds[i], F_SETFD, flags & ~FD_CLOEXEC));
        }
    }
#endif
}

/* The acquire algorithm goes like this (from job.c):

   Read a token.  As long as there's no token available we'll block.  We
   enable interruptible system calls before the read(2) so that if we get a
   SIGCHLD while we're waiting, we'll return with EINTR and we can process the
   death(s) and return tokens to the free pool.

   Once we return from the read, we immediately reinstate restartable system
   calls.  This allows us to not worry about checking for EINTR on all the
   other system calls in the program.

   There is one other twist: there is a span between the time reap_children()
   does its last check for dead children and the time the read(2) call is
   entered, below, where if a child dies we won't notice.  This is extremely
   serious as it could cause us to deadlock, given the right set of events.

   To avoid this, we do the following: before we reap_children(), we dup(2)
   the read FD on the jobserver pipe.  The read(2) call below uses that new
   FD.  In the signal handler, we close that FD.  That way, if a child dies
   during the section mentioned above, the read(2) will be invoked with an
   invalid FD and will return immediately with EBADF.  */

static RETSIGTYPE
job_noop (int sig UNUSED)
{
}

/* Set the child handler action flags to FLAGS.  */
static void
set_child_handler_action_flags (int set_handler, int set_alarm)
{
  struct sigaction sa;

#ifdef __EMX__
  /* The child handler must be turned off here.  */
  signal (SIGCHLD, SIG_DFL);
#endif

  memset (&sa, '\0', sizeof sa);
  sa.sa_handler = child_handler;
  sa.sa_flags = set_handler ? 0 : SA_RESTART;

#if defined SIGCHLD
  if (sigaction (SIGCHLD, &sa, NULL) < 0)
    pfatal_with_name ("sigaction: SIGCHLD");
#endif

#if defined SIGCLD && SIGCLD != SIGCHLD
  if (sigaction (SIGCLD, &sa, NULL) < 0)
    pfatal_with_name ("sigaction: SIGCLD");
#endif

#if defined SIGALRM
  if (set_alarm)
    {
      /* If we're about to enter the read(), set an alarm to wake up in a
         second so we can check if the load has dropped and we can start more
         work.  On the way out, turn off the alarm and set SIG_DFL.  */
      if (set_handler)
        {
          sa.sa_handler = job_noop;
          sa.sa_flags = 0;
          if (sigaction (SIGALRM, &sa, NULL) < 0)
            pfatal_with_name ("sigaction: SIGALRM");
          alarm (1);
        }
      else
        {
          alarm (0);
          sa.sa_handler = SIG_DFL;
          sa.sa_flags = 0;
          if (sigaction (SIGALRM, &sa, NULL) < 0)
            pfatal_with_name ("sigaction: SIGALRM");
        }
    }
#endif
}

void
jobserver_signal ()
{
  if (job_rfd >= 0)
    {
      close (job_rfd);
      job_rfd = -1;
    }
}

void
jobserver_pre_acquire ()
{
  /* Make sure we have a dup'd FD.  */
  if (job_rfd < 0 && job_fds[0] >= 0)
    {
      DB (DB_JOBS, ("Duplicate the job FD\n"));
      if (make_job_rfd () < 0)
        pfatal_with_name (_("duping jobs pipe"));
    }
}

int
jobserver_acquire (int timeout)
{
  char intake;
  int got_token;
  int saved_errno;

  /* Set interruptible system calls, and read() for a job token.  */
  set_child_handler_action_flags (1, timeout);

  EINTRLOOP (got_token, read (job_rfd, &intake, 1));
  saved_errno = errno;

  set_child_handler_action_flags (0, timeout);

  if (got_token == 1)
    return 1;

  /* If the error _wasn't_ expected (EINTR or EBADF), fatal.  Otherwise,
     go back and reap_children(), and try again.  */
  errno = saved_errno;

  if (errno != EINTR && errno != EBADF)
    pfatal_with_name (_("read jobs pipe"));

  if (errno == EBADF)
    DB (DB_JOBS, ("Read returned EBADF.\n"));

  return 0;
}

#endif /* MAKE_JOBSERVER */
