/* Guts of both `select' and `poll' for Hurd.
   Copyright (C) 1991-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <sys/types.h>
#include <sys/poll.h>
#include <hurd.h>
#include <hurd/fd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>

/* All user select types.  */
#define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG)

/* Used to record that a particular select rpc returned.  Must be distinct
   from SELECT_ALL (which better not have the high bit set).  */
#define SELECT_RETURNED ((SELECT_ALL << 1) & ~SELECT_ALL)

/* Check the first NFDS descriptors either in POLLFDS (if nonnnull) or in
   each of READFDS, WRITEFDS, EXCEPTFDS that is nonnull.  If TIMEOUT is not
   NULL, time out after waiting the interval specified therein.  Returns
   the number of ready descriptors, or -1 for errors.  */
int
_hurd_select (int nfds,
	      struct pollfd *pollfds,
	      fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	      const struct timespec *timeout, const sigset_t *sigmask)
{
  int i;
  mach_port_t portset;
  int got;
  error_t err;
  fd_set rfds, wfds, xfds;
  int firstfd, lastfd;
  mach_msg_timeout_t to = 0;
  struct
    {
      struct hurd_userlink ulink;
      struct hurd_fd *cell;
      mach_port_t io_port;
      int type;
      mach_port_t reply_port;
    } d[nfds];
  sigset_t oset;

  union typeword		/* Use this to avoid unkosher casts.  */
    {
      mach_msg_type_t type;
      uint32_t word;
    };
  assert (sizeof (union typeword) == sizeof (mach_msg_type_t));
  assert (sizeof (uint32_t) == sizeof (mach_msg_type_t));

  if (nfds < 0 || nfds > FD_SETSIZE)
    {
      errno = EINVAL;
      return -1;
    }

  if (timeout != NULL)
    {
      if (timeout->tv_sec < 0 || timeout->tv_nsec < 0)
	{
	  errno = EINVAL;
	  return -1;
	}

      to = (timeout->tv_sec * 1000 +
            (timeout->tv_nsec + 999999) / 1000000);
    }

  if (sigmask && __sigprocmask (SIG_SETMASK, sigmask, &oset))
    return -1;

  if (pollfds)
    {
      /* Collect interesting descriptors from the user's `pollfd' array.
	 We do a first pass that reads the user's array before taking
	 any locks.  The second pass then only touches our own stack,
	 and gets the port references.  */

      for (i = 0; i < nfds; ++i)
	if (pollfds[i].fd >= 0)
	  {
	    int type = 0;
	    if (pollfds[i].events & POLLIN)
	      type |= SELECT_READ;
	    if (pollfds[i].events & POLLOUT)
	      type |= SELECT_WRITE;
	    if (pollfds[i].events & POLLPRI)
	      type |= SELECT_URG;

	    d[i].io_port = pollfds[i].fd;
	    d[i].type = type;
	  }
	else
	  d[i].type = 0;

      HURD_CRITICAL_BEGIN;
      __mutex_lock (&_hurd_dtable_lock);

      for (i = 0; i < nfds; ++i)
	if (d[i].type != 0)
	  {
	    const int fd = (int) d[i].io_port;

	    if (fd < _hurd_dtablesize)
	      {
		d[i].cell = _hurd_dtable[fd];
		d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
		if (d[i].io_port != MACH_PORT_NULL)
		  continue;
	      }

	    /* If one descriptor is bogus, we fail completely.  */
	    while (i-- > 0)
	      if (d[i].type != 0)
		_hurd_port_free (&d[i].cell->port,
				 &d[i].ulink, d[i].io_port);
	    break;
	  }

      __mutex_unlock (&_hurd_dtable_lock);
      HURD_CRITICAL_END;

      if (i < nfds)
	{
	  if (sigmask)
	    __sigprocmask (SIG_SETMASK, &oset, NULL);
	  errno = EBADF;
	  return -1;
	}

      lastfd = i - 1;
      firstfd = i == 0 ? lastfd : 0;
    }
  else
    {
      /* Collect interested descriptors from the user's fd_set arguments.
	 Use local copies so we can't crash from user bogosity.  */

      if (readfds == NULL)
	FD_ZERO (&rfds);
      else
	rfds = *readfds;
      if (writefds == NULL)
	FD_ZERO (&wfds);
      else
	wfds = *writefds;
      if (exceptfds == NULL)
	FD_ZERO (&xfds);
      else
	xfds = *exceptfds;

      HURD_CRITICAL_BEGIN;
      __mutex_lock (&_hurd_dtable_lock);

      if (nfds > _hurd_dtablesize)
	nfds = _hurd_dtablesize;

      /* Collect the ports for interesting FDs.  */
      firstfd = lastfd = -1;
      for (i = 0; i < nfds; ++i)
	{
	  int type = 0;
	  if (readfds != NULL && FD_ISSET (i, &rfds))
	    type |= SELECT_READ;
	  if (writefds != NULL && FD_ISSET (i, &wfds))
	    type |= SELECT_WRITE;
	  if (exceptfds != NULL && FD_ISSET (i, &xfds))
	    type |= SELECT_URG;
	  d[i].type = type;
	  if (type)
	    {
	      d[i].cell = _hurd_dtable[i];
	      d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
	      if (d[i].io_port == MACH_PORT_NULL)
		{
		  /* If one descriptor is bogus, we fail completely.  */
		  while (i-- > 0)
		    if (d[i].type != 0)
		      _hurd_port_free (&d[i].cell->port, &d[i].ulink,
				       d[i].io_port);
		  break;
		}
	      lastfd = i;
	      if (firstfd == -1)
		firstfd = i;
	    }
	}

      __mutex_unlock (&_hurd_dtable_lock);
      HURD_CRITICAL_END;

      if (i < nfds)
	{
	  if (sigmask)
	    __sigprocmask (SIG_SETMASK, &oset, NULL);
	  errno = EBADF;
	  return -1;
	}
    }


  err = 0;
  got = 0;

  /* Send them all io_select request messages.  */

  if (firstfd == -1)
    /* But not if there were no ports to deal with at all.
       We are just a pure timeout.  */
    portset = __mach_reply_port ();
  else
    {
      portset = MACH_PORT_NULL;

      for (i = firstfd; i <= lastfd; ++i)
	if (d[i].type)
	  {
	    int type = d[i].type;
	    d[i].reply_port = __mach_reply_port ();
	    err = __io_select (d[i].io_port, d[i].reply_port,
			       /* Poll only if there's a single descriptor.  */
			       (firstfd == lastfd) ? to : 0,
			       &type);
	    switch (err)
	      {
	      case MACH_RCV_TIMED_OUT:
		/* No immediate response.  This is normal.  */
		err = 0;
		if (firstfd == lastfd)
		  /* When there's a single descriptor, we don't need a
		     portset, so just pretend we have one, but really
		     use the single reply port.  */
		  portset = d[i].reply_port;
		else if (got == 0)
		  /* We've got multiple reply ports, so we need a port set to
		     multiplex them.  */
		  {
		    /* We will wait again for a reply later.  */
		    if (portset == MACH_PORT_NULL)
		      /* Create the portset to receive all the replies on.  */
		      err = __mach_port_allocate (__mach_task_self (),
						  MACH_PORT_RIGHT_PORT_SET,
						  &portset);
		    if (! err)
		      /* Put this reply port in the port set.  */
		      __mach_port_move_member (__mach_task_self (),
					       d[i].reply_port, portset);
		  }
		break;

	      default:
		/* No other error should happen.  Callers of select
		   don't expect to see errors, so we simulate
		   readiness of the erring object and the next call
		   hopefully will get the error again.  */
		type = SELECT_ALL;
		/* FALLTHROUGH */

	      case 0:
		/* We got an answer.  */
		if ((type & SELECT_ALL) == 0)
		  /* Bogus answer; treat like an error, as a fake positive.  */
		  type = SELECT_ALL;

		/* This port is already ready already.  */
		d[i].type &= type;
		d[i].type |= SELECT_RETURNED;
		++got;
		break;
	      }
	    _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port);
	  }
    }

  /* Now wait for reply messages.  */
  if (!err && got == 0)
    {
      /* Now wait for io_select_reply messages on PORT,
	 timing out as appropriate.  */

      union
	{
	  mach_msg_header_t head;
#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
	  struct
	    {
	      mach_msg_header_t head;
	      NDR_record_t ndr;
	      error_t err;
	    } error;
	  struct
	    {
	      mach_msg_header_t head;
	      NDR_record_t ndr;
	      error_t err;
	      int result;
	      mach_msg_trailer_t trailer;
	    } success;
#else
	  struct
	    {
	      mach_msg_header_t head;
	      union typeword err_type;
	      error_t err;
	    } error;
	  struct
	    {
	      mach_msg_header_t head;
	      union typeword err_type;
	      error_t err;
	      union typeword result_type;
	      int result;
	    } success;
#endif
	} msg;
      mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
      error_t msgerr;
      while ((msgerr = __mach_msg (&msg.head,
				   MACH_RCV_MSG | options,
				   0, sizeof msg, portset, to,
				   MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
	{
	  /* We got a message.  Decode it.  */
#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
#ifdef MACH_MSG_TYPE_BIT
	  const union typeword inttype =
	  { type:
	    { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
	  };
#endif
	  if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
	      msg.head.msgh_size >= sizeof msg.error &&
	      !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&
#ifdef MACH_MSG_TYPE_BIT
	      msg.error.err_type.word == inttype.word
#endif
	      )
	    {
	      /* This is a properly formatted message so far.
		 See if it is a success or a failure.  */
	      if (msg.error.err == EINTR &&
		  msg.head.msgh_size == sizeof msg.error)
		{
		  /* EINTR response; poll for further responses
		     and then return quickly.  */
		  err = EINTR;
		  goto poll;
		}
	      if (msg.error.err ||
		  msg.head.msgh_size != sizeof msg.success ||
#ifdef MACH_MSG_TYPE_BIT
		  msg.success.result_type.word != inttype.word ||
#endif
		  (msg.success.result & SELECT_ALL) == 0)
		{
		  /* Error or bogus reply.  Simulate readiness.  */
		  __mach_msg_destroy (&msg.head);
		  msg.success.result = SELECT_ALL;
		}

	      /* Look up the respondent's reply port and record its
		 readiness.  */
	      {
		int had = got;
		if (firstfd != -1)
		  for (i = firstfd; i <= lastfd; ++i)
		    if (d[i].type
			&& d[i].reply_port == msg.head.msgh_local_port)
		      {
			d[i].type &= msg.success.result;
			d[i].type |= SELECT_RETURNED;
			++got;
		      }
		assert (got > had);
	      }
	    }

	  if (msg.head.msgh_remote_port != MACH_PORT_NULL)
	    __mach_port_deallocate (__mach_task_self (),
				    msg.head.msgh_remote_port);

	  if (got)
	  poll:
	    {
	      /* Poll for another message.  */
	      to = 0;
	      options |= MACH_RCV_TIMEOUT;
	    }
	}

      if (err == MACH_RCV_TIMED_OUT)
	/* This is the normal value for ERR.  We might have timed out and
	   read no messages.  Otherwise, after receiving the first message,
	   we poll for more messages.  We receive with a timeout of 0 to
	   effect a poll, so ERR is MACH_RCV_TIMED_OUT when the poll finds no
	   message waiting.  */
	err = 0;

      if (got)
	/* At least one descriptor is known to be ready now, so we will
	   return success.  */
	err = 0;
    }

  if (firstfd != -1)
    for (i = firstfd; i <= lastfd; ++i)
      if (d[i].type)
	__mach_port_destroy (__mach_task_self (), d[i].reply_port);
  if (firstfd == -1 || (firstfd != lastfd && portset != MACH_PORT_NULL))
    /* Destroy PORTSET, but only if it's not actually the reply port for a
       single descriptor (in which case it's destroyed in the previous loop;
       not doing it here is just a bit more efficient).  */
    __mach_port_destroy (__mach_task_self (), portset);

  if (err)
    {
      if (sigmask)
	__sigprocmask (SIG_SETMASK, &oset, NULL);
      return __hurd_fail (err);
    }

  if (pollfds)
    /* Fill in the `revents' members of the user's array.  */
    for (i = 0; i < nfds; ++i)
      {
	int type = d[i].type;
	int_fast16_t revents = 0;

	if (type & SELECT_RETURNED)
	  {
	    if (type & SELECT_READ)
	      revents |= POLLIN;
	    if (type & SELECT_WRITE)
	      revents |= POLLOUT;
	    if (type & SELECT_URG)
	      revents |= POLLPRI;
	  }

	pollfds[i].revents = revents;
      }
  else
    {
      /* Below we recalculate GOT to include an increment for each operation
	 allowed on each fd.  */
      got = 0;

      /* Set the user bitarrays.  We only ever have to clear bits, as all
	 desired ones are initially set.  */
      if (firstfd != -1)
	for (i = firstfd; i <= lastfd; ++i)
	  {
	    int type = d[i].type;

	    if ((type & SELECT_RETURNED) == 0)
	      type = 0;

	    if (type & SELECT_READ)
	      got++;
	    else if (readfds)
	      FD_CLR (i, readfds);
	    if (type & SELECT_WRITE)
	      got++;
	    else if (writefds)
	      FD_CLR (i, writefds);
	    if (type & SELECT_URG)
	      got++;
	    else if (exceptfds)
	      FD_CLR (i, exceptfds);
	  }
    }

  if (sigmask && __sigprocmask (SIG_SETMASK, &oset, NULL))
    return -1;

  return got;
}
