/* Selective.c provide access to timeval and select.

Copyright (C) 2005-2023 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius@glam.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 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, or (at your option)
any later version.

GNU Modula-2 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.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "ansidecl.h"

#include "gm2-libs-host.h"

#ifdef __cplusplus
extern "C" {
#endif

#if defined(HAVE_SELECT)
# define FDSET_T fd_set
#else
# define FDSET_T void
#endif


#if defined(HAVE_SELECT)
int Selective_Select (int nooffds,
		      fd_set *readfds,
		      fd_set *writefds,
		      fd_set *exceptfds,
		      struct timeval *timeout)
{
  return select (nooffds, readfds, writefds, exceptfds, timeout);
}
#else
int Selective_Select (int nooffds,
		      void *readfds,
		      void *writefds,
		      void *exceptfds,
		      void *timeout)
{
  return 0;
}
#endif

/* InitTime initialises a timeval structure and returns a pointer to it.  */

#if defined(HAVE_SELECT)
struct timeval *Selective_InitTime (unsigned int sec, unsigned int usec)
{
  struct timeval *t = (struct timeval *) malloc (sizeof (struct timeval));

  t->tv_sec = (long int) sec;
  t->tv_usec = (long int) usec;
  return t;
}

void Selective_GetTime (struct timeval *t,
			unsigned int *sec, unsigned int *usec)
{
  *sec = (unsigned int) t->tv_sec;
  *usec = (unsigned int) t->tv_usec;
}

void Selective_SetTime (struct timeval *t,
			unsigned int sec, unsigned int usec)
{
  t->tv_sec = sec;
  t->tv_usec = usec;
}

/* KillTime frees the timeval structure and returns NULL.  */

struct timeval *Selective_KillTime (struct timeval *t)
{
  free (t);
  return NULL;
}

/* InitSet returns a pointer to a FD_SET.  */

fd_set *Selective_InitSet (void)
{
  fd_set *s = (fd_set *) malloc (sizeof (fd_set));

  return s;
}

/* KillSet frees the FD_SET and returns NULL.  */

fd_set *Selective_KillSet (fd_set *s)
{
  free (s);
  return NULL;
}

/* FdZero generate an empty set.  */

void Selective_FdZero (fd_set *s)
{
  FD_ZERO (s);
}

/* FS_Set include an element, fd, into set, s.  */

void Selective_FdSet (int fd, fd_set *s)
{
  FD_SET (fd, s);
}


/* FdClr exclude an element, fd, from the set, s.  */

void Selective_FdClr (int fd, fd_set *s)
{
  FD_CLR (fd, s);
}


/* FdIsSet return TRUE if, fd, is present in set, s.  */

int Selective_FdIsSet (int fd, fd_set *s)
{
  return FD_ISSET (fd, s);
}

/* GetTimeOfDay fills in a record, Timeval, filled in with the
   current system time in seconds and microseconds.
   It returns zero (see man 3p gettimeofday).  */

int Selective_GetTimeOfDay (struct timeval *t)
{
  return gettimeofday (t, NULL);
}
#else

void *Selective_InitTime (unsigned int sec, unsigned int usec)
{
  return NULL;
}

void *Selective_KillTime (void *t)
{
  return NULL;
}

void Selective_GetTime (struct timeval *t,
			unsigned int *sec, unsigned int *usec)
{
}

void Selective_SetTime (struct timeval *t,
			unsigned int sec, unsigned int usec)
{
}

fd_set *Selective_InitSet (void)
{
  return NULL;
}

void Selective_FdZero (void *s)
{
}

void Selective_FdSet (int fd, void *s)
{
}

void Selective_FdClr (int fd, void *s)
{
}

int Selective_FdIsSet (int fd, void *s)
{
  return 0;
}

int Selective_GetTimeOfDay (struct timeval *t)
{
    return -1;
}
#endif


/* MaxFdsPlusOne returns max (a + 1, b + 1).  */

int Selective_MaxFdsPlusOne (int a, int b)
{
  if (a > b)
    return a+1;
  else
    return b+1;
}


/* WriteCharRaw writes a single character to the file descriptor.  */

void Selective_WriteCharRaw (int fd, char ch)
{
  write (fd, &ch, 1);
}


/* ReadCharRaw read and return a single char from file descriptor, fd.  */

char Selective_ReadCharRaw (int fd)
{
  char ch;

  read (fd, &ch, 1);
  return ch;
}


void
_M2_Selective_init ()
{
}

void
_M2_Selective_finish ()
{
}

#ifdef __cplusplus
}
#endif
