diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/target.c
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/target.c	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,61 @@
+/* target.c provide access to miscellaneous math functions.
+
+Copyright (C) 2005-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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>
+
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+
+#if !defined(HAVE_EXP10)
+#if defined(M_LN10)
+double
+exp10 (double x)
+{
+  return exp (x * M_LN10);
+}
+#endif
+#endif
+
+#if !defined(HAVE_EXP10F)
+#if defined(M_LN10)
+float
+exp10f (float x)
+{
+  return expf (x * M_LN10);
+}
+#endif
+#endif
+
+#if !defined(HAVE_EXP10L)
+#if defined(M_LN10)
+long double
+exp10l (long double x)
+{
+  return expl (x * M_LN10);
+}
+#endif
+#endif
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/Selective.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/Selective.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,319 @@
+/* Selective.c provide access to timeval and select.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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 <m2rts.h>
+
+#if defined(HAVE_STDDEF_H)
+/* Obtain a definition for NULL.  */
+#include <stddef.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+/* Obtain a definition for NULL.  */
+#include <stdio.h>
+#endif
+
+#if defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if defined(HAVE_TIME_H)
+/* Obtain a definition for NULL.  */
+#include <time.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+/* Obtain a definition for NULL.  */
+#include <string.h>
+#endif
+
+#if defined(HAVE_WCHAR_H)
+/* Obtain a definition for NULL.  */
+#include <wchar.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+/* Obtain a prototype for free and malloc.  */
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if !defined(NULL)
+#define NULL (void *)0
+#endif
+
+#if defined(HAVE_SELECT)
+#define FDSET_T fd_set
+#else
+#define FDSET_T void
+#endif
+
+/* Select wrap a call to the C select.  */
+
+#if defined(HAVE_STRUCT_TIMEVAL)
+extern "C" 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
+extern "C" int
+Selective_Select (int nooffds, void *readfds, void *writefds, void *exceptfds,
+                  void *timeout)
+{
+  return 0;
+}
+#endif
+
+/* InitTime initializes a timeval structure and returns a pointer to it.  */
+
+#if defined(HAVE_STRUCT_TIMEVAL)
+extern "C" 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;
+}
+
+extern "C" void
+Selective_GetTime (struct timeval *t, unsigned int *sec, unsigned int *usec)
+{
+  *sec = (unsigned int)t->tv_sec;
+  *usec = (unsigned int)t->tv_usec;
+}
+
+extern "C" 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.  */
+
+extern "C" struct timeval *
+Selective_KillTime (struct timeval *t)
+{
+#if defined(HAVE_STDLIB_H)
+  free (t);
+#endif
+  return NULL;
+}
+
+/* InitSet returns a pointer to a FD_SET.  */
+
+extern "C" FDSET_T *
+Selective_InitSet (void)
+{
+#if defined(HAVE_STDLIB_H)
+  FDSET_T *s = (FDSET_T *)malloc (sizeof (FDSET_T));
+
+  return s;
+#else
+  return NULL
+#endif
+}
+
+/* KillSet frees the FD_SET and returns NULL.  */
+
+extern "C" FDSET_T *
+Selective_KillSet (FDSET_T *s)
+{
+#if defined(HAVE_STDLIB_H)
+  free (s);
+#endif
+  return NULL;
+}
+
+/* FdZero generate an empty set.  */
+
+extern "C" void
+Selective_FdZero (FDSET_T *s)
+{
+  FD_ZERO (s);
+}
+
+/* FS_Set include an element, fd, into set, s.  */
+
+extern "C" void
+Selective_FdSet (int fd, FDSET_T *s)
+{
+  FD_SET (fd, s);
+}
+
+/* FdClr exclude an element, fd, from the set, s.  */
+
+extern "C" void
+Selective_FdClr (int fd, FDSET_T *s)
+{
+  FD_CLR (fd, s);
+}
+
+/* FdIsSet return TRUE if, fd, is present in set, s.  */
+
+extern "C" int
+Selective_FdIsSet (int fd, FDSET_T *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).  */
+
+extern "C" int
+Selective_GetTimeOfDay (struct timeval *t)
+{
+  return gettimeofday (t, NULL);
+}
+#else
+
+extern "C" void *
+Selective_InitTime (unsigned int sec, unsigned int usec)
+{
+  return NULL;
+}
+
+extern "C" void *
+Selective_KillTime (void *t)
+{
+  return NULL;
+}
+
+extern "C" void
+Selective_GetTime (void *t, unsigned int *sec, unsigned int *usec)
+{
+}
+
+extern "C" void
+Selective_SetTime (void *t, unsigned int sec, unsigned int usec)
+{
+}
+
+extern "C" FDSET_T *
+Selective_InitSet (void)
+{
+  return NULL;
+}
+
+extern "C" FDSET_T *
+Selective_KillSet (void)
+{
+  return NULL;
+}
+
+extern "C" void
+Selective_FdZero (void *s)
+{
+}
+
+extern "C" void
+Selective_FdSet (int fd, void *s)
+{
+}
+
+extern "C" void
+Selective_FdClr (int fd, void *s)
+{
+}
+
+extern "C" int
+Selective_FdIsSet (int fd, void *s)
+{
+  return 0;
+}
+
+extern "C" int
+Selective_GetTimeOfDay (void *t)
+{
+  return -1;
+}
+#endif
+
+/* MaxFdsPlusOne returns max (a + 1, b + 1).  */
+
+extern "C" 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.  */
+
+extern "C" void
+Selective_WriteCharRaw (int fd, char ch)
+{
+  write (fd, &ch, 1);
+}
+
+/* ReadCharRaw read and return a single char from file descriptor, fd.  */
+
+extern "C" char
+Selective_ReadCharRaw (int fd)
+{
+  char ch;
+
+  read (fd, &ch, 1);
+  return ch;
+}
+
+extern "C" void
+_M2_Selective_init (int argc, char *argv[], char *envp[])
+{
+}
+
+extern "C" void
+_M2_Selective_fini (int argc, char *argv[], char *envp[])
+{
+}
+
+extern "C" void
+_M2_Selective_dep (void)
+{
+}
+
+struct _M2_Selective_ctor { _M2_Selective_ctor (); } _M2_Selective_ctor;
+
+_M2_Selective_ctor::_M2_Selective_ctor (void)
+{
+  M2RTS_RegisterModule ("Selective", _M2_Selective_init, _M2_Selective_fini,
+			_M2_Selective_dep);
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/dtoa.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/dtoa.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,265 @@
+/* dtoa.cc convert double to ascii and visa versa.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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/>.  */
+
+#define GM2
+
+#include <config.h>
+#include <m2rts.h>
+
+#if defined(HAVE_STRINGS)
+#include <strings.h>
+#endif
+
+#if defined(HAVE_STRING)
+#include <string.h>
+#endif
+
+#if defined(HAVE_STDDEF_H)
+/* Obtain a definition for NULL.  */
+#include <stddef.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+/* Obtain a definition for NULL.  */
+#include <stdio.h>
+#endif
+
+#if defined(HAVE_TIME_H)
+/* Obtain a definition for NULL.  */
+#include <time.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+/* Obtain a definition for NULL.  */
+#include <string.h>
+#endif
+
+#if defined(HAVE_WCHAR_H)
+/* Obtain a definition for NULL.  */
+#include <wchar.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+/* Obtain a prototype for free and malloc.  */
+#include <stdlib.h>
+#endif
+
+#if !defined(NULL)
+#define NULL (void *)0
+#endif
+
+#if !defined(TRUE)
+#define TRUE (1 == 1)
+#endif
+#if !defined(FALSE)
+#define FALSE (1 == 0)
+#endif
+
+#if defined(HAVE_STDLIB_H)
+#if !defined(_ISOC99_SOURCE)
+#define _ISOC99_SOURCE
+#endif
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+#include <errno.h>
+#endif
+
+#if defined(HAVE_SYS_ERRNO_H)
+#include <sys/errno.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+
+#define MAX_FP_DIGITS 500
+
+typedef enum Mode { maxsignicant, decimaldigits } Mode;
+
+/* maxsignicant:  return a string containing max(1,ndigits) significant
+   digits.  The return string contains the string produced by ecvt.
+
+   decimaldigits: return a string produced by fcvt.  The string will
+   contain ndigits past the decimal point (ndigits may be negative).  */
+
+extern "C" double
+dtoa_strtod (const char *s, int *error)
+{
+  char *endp;
+  double d;
+
+#if defined(HAVE_ERRNO_H)
+  errno = 0;
+#endif
+  d = strtod (s, &endp);
+  if (endp != NULL && (*endp == '\0'))
+#if defined(HAVE_ERRNO_H)
+    *error = (errno != 0);
+#else
+    *error = FALSE;
+#endif
+  else
+    *error = TRUE;
+  return d;
+}
+
+/* dtoa_calcmaxsig calculates the position of the decimal point
+   it also removes the decimal point and exponent from string, p.  */
+
+extern "C" int
+dtoa_calcmaxsig (char *p, int ndigits)
+{
+  char *e;
+  char *o;
+  int x;
+
+  e = strchr (p, 'E');
+  if (e == NULL)
+    x = 0;
+  else
+    {
+      *e = (char)0;
+      x = atoi (e + 1);
+    }
+
+  o = strchr (p, '.');
+  if (o == NULL)
+    return strlen (p) + x;
+  else
+    {
+      memmove (o, o + 1, ndigits - (o - p));
+      return o - p + x;
+    }
+}
+
+/* dtoa_calcdecimal calculates the position of the decimal point
+   it also removes the decimal point and exponent from string, p.
+   It truncates the digits in p accordingly to ndigits.
+   Ie ndigits is the number of digits after the '.'.  */
+
+extern "C" int
+dtoa_calcdecimal (char *p, int str_size, int ndigits)
+{
+  char *e;
+  char *o;
+  int x;
+  int l;
+
+  e = strchr (p, 'E');
+  if (e == NULL)
+    x = 0;
+  else
+    {
+      *e = (char)0;
+      x = atoi (e + 1);
+    }
+
+  l = strlen (p);
+  o = strchr (p, '.');
+  if (o == NULL)
+    x += strlen (p);
+  else
+    {
+      int m = strlen (o);
+      memmove (o, o + 1, l - (o - p));
+      if (m > 0)
+        o[m - 1] = '0';
+      x += o - p;
+    }
+  if ((x + ndigits >= 0) && (x + ndigits < str_size))
+    p[x + ndigits] = (char)0;
+  return x;
+}
+
+extern "C" int
+dtoa_calcsign (char *p, int str_size)
+{
+  if (p[0] == '-')
+    {
+      memmove (p, p + 1, str_size - 1);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+extern "C" char *
+dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
+{
+  char format[50];
+  char *p;
+  int r;
+  switch (mode)
+    {
+
+    case maxsignicant:
+      ndigits += 20; /* Enough for exponent.  */
+      p = (char *) malloc (ndigits);
+      snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "E");
+      snprintf (p, ndigits, format, d);
+      *sign = dtoa_calcsign (p, ndigits);
+      *decpt = dtoa_calcmaxsig (p, ndigits);
+      return p;
+    case decimaldigits:
+      p = (char *) malloc (MAX_FP_DIGITS + 20);
+      snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "E");
+      snprintf (p, MAX_FP_DIGITS + 20, format, d);
+      *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
+      *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
+      return p;
+    default:
+      abort ();
+    }
+}
+
+#endif
+
+#if defined(GM2)
+/* GNU Modula-2 linking hooks.  */
+
+extern "C" void
+_M2_dtoa_init (int, char **, char **)
+{
+}
+
+extern "C" void
+_M2_dtoa_fini (int, char **, char **)
+{
+}
+
+extern "C" void
+_M2_dtoa_dep (void)
+{
+}
+
+struct _M2_dtoa_ctor { _M2_dtoa_ctor (); } _M2_dtoa_ctor;
+
+_M2_dtoa_ctor::_M2_dtoa_ctor (void)
+{
+  M2RTS_RegisterModule ("dtoa", _M2_dtoa_init, _M2_dtoa_fini,
+			_M2_dtoa_dep);
+}
+#endif
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/wrapc.c
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/wrapc.c	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,296 @@
+/* wrapc.c provide access to miscellaneous C library functions.
+
+Copyright (C) 2005-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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>
+
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined(HAVE_SYS_STAT_H)
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_TIME_H)
+#include <time.h>
+#endif
+
+/* Define FALSE if one hasn't already been defined.  */
+
+#if !defined(FALSE)
+#define FALSE (1 == 0)
+#endif
+
+/* Define a generic NULL if one hasn't already been defined.  */
+
+#if !defined(NULL)
+#define NULL 0
+#endif
+
+/* strtime returns the address of a string which describes the
+   local time.  */
+
+char *
+wrapc_strtime (void)
+{
+#if defined(HAVE_CTIME)
+  time_t clock = time ((void *)0);
+  char *string = ctime (&clock);
+
+  string[24] = (char)0;
+
+  return string;
+#else
+  return "";
+#endif
+}
+
+int
+wrapc_filesize (int f, unsigned int *low, unsigned int *high)
+{
+#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
+  struct stat s;
+  int res = fstat (f, (struct stat *)&s);
+
+  if (res == 0)
+    {
+      *low = (unsigned int)s.st_size;
+      *high = (unsigned int)(s.st_size >> (sizeof (unsigned int) * 8));
+    }
+  return res;
+#else
+  return -1;
+#endif
+}
+
+/* filemtime returns the mtime of a file, f.  */
+
+int
+wrapc_filemtime (int f)
+{
+#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
+  struct stat s;
+
+  if (fstat (f, (struct stat *)&s) == 0)
+    return s.st_mtime;
+  else
+    return -1;
+#else
+  return -1;
+#endif
+}
+
+/* fileinode returns the inode associated with a file, f.  */
+
+#if defined(HAVE_SYS_STAT_H) && defined(HAVE_STRUCT_STAT)
+ino_t
+wrapc_fileinode (int f, unsigned int *low, unsigned int *high)
+{
+  struct stat s;
+
+  if (fstat (f, (struct stat *)&s) == 0)
+    {
+      *low = (unsigned int)s.st_ino;
+      if ((sizeof (s.st_ino) == (sizeof (unsigned int))))
+	*high = 0;
+      else
+	*high = (unsigned int)(s.st_ino >> (sizeof (unsigned int) * 8));
+      return 0;
+    }
+  else
+    return -1;
+}
+#else
+int
+wrapc_fileinode (int f, unsigned int *low, unsigned int *high)
+{
+  *low = 0;
+  *high = 0;
+  return -1;
+}
+#endif
+
+/* getrand returns a random number between 0..n-1.  */
+
+int
+wrapc_getrand (int n)
+{
+  return rand () % n;
+}
+
+#if defined(HAVE_PWD_H)
+#include <pwd.h>
+
+char *
+wrapc_getusername (void)
+{
+  return getpwuid (getuid ())->pw_gecos;
+}
+
+/* getnameuidgid fills in the, uid, and, gid, which represents
+   user, name.  */
+
+void
+wrapc_getnameuidgid (char *name, int *uid, int *gid)
+{
+  struct passwd *p = getpwnam (name);
+
+  if (p == NULL)
+    {
+      *uid = -1;
+      *gid = -1;
+    }
+  else
+    {
+      *uid = p->pw_uid;
+      *gid = p->pw_gid;
+    }
+}
+#else
+char *
+wrapc_getusername (void)
+{
+  return "unknown";
+}
+
+void
+wrapc_getnameuidgid (char *name, int *uid, int *gid)
+{
+  *uid = -1;
+  *gid = -1;
+}
+#endif
+
+int
+wrapc_signbit (double r)
+{
+#if defined(HAVE_SIGNBIT)
+
+  /* signbit is a macro which tests its argument against sizeof(float),
+     sizeof(double).  */
+  return signbit (r);
+#else
+  return FALSE;
+#endif
+}
+
+int
+wrapc_signbitl (long double r)
+{
+#if defined(HAVE_SIGNBITL)
+
+  /* signbit is a macro which tests its argument against sizeof(float),
+     sizeof(double).  */
+  return signbitl (r);
+#else
+  return FALSE;
+#endif
+}
+
+int
+wrapc_signbitf (float r)
+{
+#if defined(HAVE_SIGNBITF)
+
+  /* signbit is a macro which tests its argument against sizeof(float),
+     sizeof(double).  */
+  return signbitf (r);
+#else
+  return FALSE;
+#endif
+}
+
+/* isfinite provide non builtin alternative to the gcc builtin
+   isfinite.  Returns 1 if x is finite and 0 if it is not.  */
+
+int
+wrapc_isfinite (double x)
+{
+#if defined(FP_NAN) && defined(FP_INFINITE)
+  return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
+#else
+  return FALSE;
+#endif
+}
+
+/* isfinitel provide non builtin alternative to the gcc builtin
+   isfinite.  Returns 1 if x is finite and 0 if it is not.  */
+
+int
+wrapc_isfinitel (long double x)
+{
+#if defined(FP_NAN) && defined(FP_INFINITE)
+  return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
+#else
+  return FALSE;
+#endif
+}
+
+/* isfinitef provide non builtin alternative to the gcc builtin
+   isfinite.  Returns 1 if x is finite and 0 if it is not.  */
+
+int
+wrapc_isfinitef (float x)
+{
+#if defined(FP_NAN) && defined(FP_INFINITE)
+  return (fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE);
+#else
+  return FALSE;
+#endif
+}
+
+/* init/finish are GNU Modula-2 linking fodder.  */
+
+void
+_M2_wrapc_init ()
+{
+}
+
+void
+_M2_wrapc_fini ()
+{
+}
+
+void
+_M2_wrapc_ctor ()
+{
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/SysExceptions.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/SysExceptions.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,259 @@
+/* SysExceptions.c configure the signals to create m2 exceptions.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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>
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+#include <errno.h>
+#endif
+
+#if defined(HAVE_SYS_ERRNO_H)
+#include <sys/errno.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+#include <stdio.h>
+#endif
+
+#include "m2rts.h"
+
+#if 0
+/* Signals.  */
+#define SIGHUP 1       /* Hangup (POSIX).  */
+#define SIGINT 2       /* Interrupt (ANSI).  */
+#define SIGQUIT 3      /* Quit (POSIX).  */
+#define SIGILL 4       /* Illegal instruction (ANSI).  */
+#define SIGTRAP 5      /* Trace trap (POSIX).  */
+#define SIGABRT 6      /* Abort (ANSI).  */
+#define SIGIOT 6       /* IOT trap (4.2 BSD).  */
+#define SIGBUS 7       /* BUS error (4.2 BSD).  */
+#define SIGFPE 8       /* Floating-point exception (ANSI).  */
+#define SIGKILL 9      /* Kill, unblockable (POSIX).  */
+#define SIGUSR1 10     /* User-defined signal 1 (POSIX).  */
+#define SIGSEGV 11     /* Segmentation violation (ANSI).  */
+#define SIGUSR2 12     /* User-defined signal 2 (POSIX).  */
+#define SIGPIPE 13     /* Broken pipe (POSIX).  */
+#define SIGALRM 14     /* Alarm clock (POSIX).  */
+#define SIGTERM 15     /* Termination (ANSI).  */
+#define SIGSTKFLT 16   /* Stack fault.  */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V).  */
+#define SIGCHLD 17     /* Child status has changed (POSIX).  */
+#define SIGCONT 18     /* Continue (POSIX).  */
+#define SIGSTOP 19     /* Stop, unblockable (POSIX).  */
+#define SIGTSTP 20     /* Keyboard stop (POSIX).  */
+#define SIGTTIN 21     /* Background read from tty (POSIX).  */
+#define SIGTTOU 22     /* Background write to tty (POSIX).  */
+#define SIGURG 23      /* Urgent condition on socket (4.2 BSD).  */
+#define SIGXCPU 24     /* CPU limit exceeded (4.2 BSD).  */
+#define SIGXFSZ 25     /* File size limit exceeded (4.2 BSD).  */
+#define SIGVTALRM 26   /* Virtual alarm clock (4.2 BSD).  */
+#define SIGPROF 27     /* Profiling alarm clock (4.2 BSD).  */
+#define SIGWINCH 28    /* Window size change (4.3 BSD, Sun).  */
+#define SIGPOLL SIGIO  /* Pollable event occurred (System V).  */
+#define SIGIO 29       /* I/O now possible (4.2 BSD).  */
+#define SIGPWR 30      /* Power failure restart (System V).  */
+#define SIGSYS 31      /* Bad system call.  */
+#define SIGUNUSED 31
+
+/* The list of Modula-2 exceptions is shown below */
+
+    (indexException,     rangeException,         caseSelectException,  invalidLocation,
+     functionException,  wholeValueException,    wholeDivException,    realValueException,
+     realDivException,   complexValueException,  complexDivException,  protException,
+     sysException,       coException,            exException
+    );
+
+#endif
+
+/* Note: wholeDivException and realDivException are caught by SIGFPE
+   and depatched to the appropriate Modula-2 runtime routine upon
+   testing FPE_INTDIV or FPE_FLTDIV.  realValueException is also
+   caught by SIGFPE and dispatched by testing FFE_FLTOVF or FPE_FLTUND
+   or FPE_FLTRES or FPE_FLTINV.  indexException is caught by SIGFPE
+   and dispatched by FPE_FLTSUB.  */
+
+#if defined(HAVE_SIGNAL_H)
+static struct sigaction sigbus;
+static struct sigaction sigfpe;
+static struct sigaction sigsegv;
+
+static void (*indexProc) (void *);
+static void (*rangeProc) (void *);
+static void (*assignmentrangeProc) (void *);
+static void (*caseProc) (void *);
+static void (*invalidlocProc) (void *);
+static void (*functionProc) (void *);
+static void (*wholevalueProc) (void *);
+static void (*wholedivProc) (void *);
+static void (*realvalueProc) (void *);
+static void (*realdivProc) (void *);
+static void (*complexvalueProc) (void *);
+static void (*complexdivProc) (void *);
+static void (*protectionProc) (void *);
+static void (*systemProc) (void *);
+static void (*coroutineProc) (void *);
+static void (*exceptionProc) (void *);
+
+static void
+sigbusDespatcher (int signum, siginfo_t *info, void *ucontext)
+{
+  switch (signum)
+    {
+
+    case SIGSEGV:
+    case SIGBUS:
+      if (info)
+        (*invalidlocProc) (info->si_addr);
+      break;
+    default:
+      perror ("not expecting to arrive here with this signal");
+    }
+}
+
+static void
+sigfpeDespatcher (int signum, siginfo_t *info, void *ucontext)
+{
+  switch (signum)
+    {
+
+    case SIGFPE:
+      if (info)
+        {
+          if (info->si_code | FPE_INTDIV)
+            (*wholedivProc) (info->si_addr); /* Integer divide by zero.  */
+          if (info->si_code | FPE_INTOVF)
+            (*wholevalueProc) (info->si_addr); /* Integer overflow.  */
+          if (info->si_code | FPE_FLTDIV)
+            (*realdivProc) (info->si_addr); /* Floating-point divide by zero.  */
+          if (info->si_code | FPE_FLTOVF)
+            (*realvalueProc) (info->si_addr); /* Floating-point overflow.  */
+          if (info->si_code | FPE_FLTUND)
+            (*realvalueProc) (info->si_addr); /* Floating-point underflow.  */
+          if (info->si_code | FPE_FLTRES)
+            (*realvalueProc) (
+                info->si_addr); /* Floating-point inexact result.  */
+          if (info->si_code | FPE_FLTINV)
+            (*realvalueProc) (
+                info->si_addr); /* Floating-point invalid result.  */
+          if (info->si_code | FPE_FLTSUB)
+            (*indexProc) (info->si_addr); /* Subscript out of range.  */
+        }
+      break;
+    default:
+      perror ("not expecting to arrive here with this signal");
+    }
+}
+
+extern "C" void
+SysExceptions_InitExceptionHandlers (
+    void (*indexf) (void *), void (*range) (void *), void (*casef) (void *),
+    void (*invalidloc) (void *), void (*function) (void *),
+    void (*wholevalue) (void *), void (*wholediv) (void *),
+    void (*realvalue) (void *), void (*realdiv) (void *),
+    void (*complexvalue) (void *), void (*complexdiv) (void *),
+    void (*protection) (void *), void (*systemf) (void *),
+    void (*coroutine) (void *), void (*exception) (void *))
+{
+  struct sigaction old;
+
+  indexProc = indexf;
+  rangeProc = range;
+  caseProc = casef;
+  invalidlocProc = invalidloc;
+  functionProc = function;
+  wholevalueProc = wholevalue;
+  wholedivProc = wholediv;
+  realvalueProc = realvalue;
+  realdivProc = realdiv;
+  complexvalueProc = complexvalue;
+  complexdivProc = complexdiv;
+  protectionProc = protection;
+  systemProc = systemf;
+  coroutineProc = coroutine;
+  exceptionProc = exception;
+
+  sigbus.sa_sigaction = sigbusDespatcher;
+  sigbus.sa_flags = (SA_SIGINFO);
+  sigemptyset (&sigbus.sa_mask);
+
+  if (sigaction (SIGBUS, &sigbus, &old) != 0)
+    perror ("unable to install the sigbus signal handler");
+
+  sigsegv.sa_sigaction = sigbusDespatcher;
+  sigsegv.sa_flags = (SA_SIGINFO);
+  sigemptyset (&sigsegv.sa_mask);
+
+  if (sigaction (SIGSEGV, &sigsegv, &old) != 0)
+    perror ("unable to install the sigsegv signal handler");
+
+  sigfpe.sa_sigaction = sigfpeDespatcher;
+  sigfpe.sa_flags = (SA_SIGINFO);
+  sigemptyset (&sigfpe.sa_mask);
+
+  if (sigaction (SIGFPE, &sigfpe, &old) != 0)
+    perror ("unable to install the sigfpe signal handler");
+}
+
+#else
+extern "C" void
+SysExceptions_InitExceptionHandlers (void *indexf, void *range, void *casef,
+                                     void *invalidloc, void *function,
+                                     void *wholevalue, void *wholediv,
+                                     void *realvalue, void *realdiv,
+                                     void *complexvalue, void *complexdiv,
+                                     void *protection, void *systemf,
+                                     void *coroutine, void *exception)
+{
+}
+#endif
+
+
+extern "C" void
+_M2_SysExceptions_init (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_SysExceptions_fini (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_SysExceptions_dep (void)
+{
+}
+
+struct _M2_SysExceptions_ctor { _M2_SysExceptions_ctor (); } _M2_SysExceptions_ctor;
+
+_M2_SysExceptions_ctor::_M2_SysExceptions_ctor (void)
+{
+  M2RTS_RegisterModule ("SysExceptions", _M2_SysExceptions_init, _M2_SysExceptions_fini,
+			_M2_SysExceptions_dep);
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/Makefile.am
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/Makefile.am	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,209 @@
+# Makefile for libm2pim.
+#   Copyright 2013-2022  Free Software Foundation, Inc.
+#
+# This file 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.
+#
+# This program 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; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+SUFFIXES = .c .mod .def .o .obj .lo .a .la
+
+ACLOCAL_AMFLAGS = -I . -I .. -I ../config
+
+VPATH = . @srcdir@ @srcdir@/../../gcc/m2/gm2-libs
+
+# Multilib support.
+MAKEOVERRIDES=
+
+version := $(shell $(CC) -dumpversion)
+
+# Directory in which the compiler finds libraries etc.
+libsubdir = $(libdir)/gcc/$(target_alias)/$(version)
+# Used to install the shared libgcc.
+slibdir = @slibdir@
+
+toolexeclibdir=@toolexeclibdir@
+toolexecdir=@toolexecdir@
+GM2_FOR_TARGET=@GM2_FOR_TARGET@
+
+MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
+MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)
+
+MULTIOSSUBDIR := $(shell if test x$(MULTIOSDIR) != x.; then echo /$(MULTIOSDIR); fi)
+inst_libdir = $(libsubdir)$(MULTISUBDIR)
+inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)
+
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+        "GCC_DIR=$(GCC_DIR)" \
+        "GM2_SRC=$(GM2_SRC)" \
+	"AR_FLAGS=$(AR_FLAGS)" \
+	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+	"CC_FOR_TARGET=$(CC_FOR_TARGET)" \
+	"GM2_FOR_TARGET=$(GM2_FOR_TARGET)" \
+	"CFLAGS=$(CFLAGS)" \
+	"CXXFLAGS=$(CXXFLAGS)" \
+	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+	"INSTALL=$(INSTALL)" \
+	"INSTALL_DATA=$(INSTALL_DATA)" \
+	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+	"LDFLAGS=$(LDFLAGS)" \
+	"LIBCFLAGS=$(LIBCFLAGS)" \
+	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+	"MAKE=$(MAKE)" \
+	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+        "MULTISUBDIR=$(MULTISUBDIR)" \
+        "MULTIOSDIR=$(MULTIOSDIR)" \
+        "MULTIBUILDTOP=$(MULTIBUILDTOP)" \
+        "MULTIFLAGS=$(MULTIFLAGS)" \
+	"PICFLAG=$(PICFLAG)" \
+	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+	"SHELL=$(SHELL)" \
+	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+	"exec_prefix=$(exec_prefix)" \
+	"infodir=$(infodir)" \
+	"libdir=$(libdir)" \
+	"includedir=$(includedir)" \
+	"prefix=$(prefix)" \
+	"tooldir=$(tooldir)" \
+	"AR=$(AR)" \
+	"AS=$(AS)" \
+	"LD=$(LD)" \
+	"RANLIB=$(RANLIB)" \
+	"NM=$(NM)" \
+	"NM_FOR_BUILD=$(NM_FOR_BUILD)" \
+	"NM_FOR_TARGET=$(NM_FOR_TARGET)" \
+	"DESTDIR=$(DESTDIR)" \
+	"WERROR=$(WERROR)" \
+        "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)"
+
+# Subdir rules rely on $(FLAGS_TO_PASS)
+FLAGS_TO_PASS = $(AM_MAKEFLAGS)
+
+if BUILD_PIMLIB
+toolexeclib_LTLIBRARIES = libm2pim.la
+
+M2MODS = ASCII.mod IO.mod \
+       Args.mod M2RTS.mod \
+       M2Dependent.mod \
+       Assertion.mod NumberIO.mod \
+       Break.mod SYSTEM.mod \
+       CmdArgs.mod Scan.mod \
+       StrCase.mod FIO.mod \
+       StrIO.mod StrLib.mod \
+       TimeString.mod Environment.mod \
+       FpuIO.mod Debug.mod \
+       SysStorage.mod Storage.mod \
+       StdIO.mod SEnvironment.mod \
+       DynamicStrings.mod SFIO.mod \
+       SArgs.mod SCmdArgs.mod \
+       PushBackInput.mod \
+       StringConvert.mod FormatStrings.mod \
+       Builtins.mod MathLib0.mod \
+       M2EXCEPTION.mod RTExceptions.mod \
+       SMathLib0.mod RTint.mod \
+       Indexing.mod \
+       LMathLib0.mod LegacyReal.mod \
+       MemUtils.mod gdbif.mod \
+       GetOpt.mod OptLib.mod
+
+# COROUTINES.mod has been removed as it is implemented in ../libm2iso.
+
+M2DEFS = Args.def   ASCII.def \
+         Assertion.def  Break.def \
+         Builtins.def  cbuiltin.def \
+         CmdArgs.def COROUTINES.def \
+         cxxabi.def  Debug.def \
+         dtoa.def  DynamicStrings.def \
+         Environment.def  errno.def \
+         FIO.def  FormatStrings.def \
+         FpuIO.def  gdbif.def \
+         Indexing.def \
+         IO.def  ldtoa.def \
+         LegacyReal.def  libc.def \
+         libm.def  LMathLib0.def \
+         M2Dependent.def \
+         M2EXCEPTION.def  M2LINK.def \
+         M2RTS.def \
+         MathLib0.def  MemUtils.def \
+         NumberIO.def  PushBackInput.def \
+         RTExceptions.def  RTint.def \
+         SArgs.def  SCmdArgs.def \
+         Scan.def \
+         sckt.def  Selective.def \
+         SEnvironment.def  SFIO.def \
+         SMathLib0.def  StdIO.def \
+         Storage.def  StrCase.def \
+         StringConvert.def  StrIO.def \
+         StrLib.def  SysExceptions.def \
+         SysStorage.def  SYSTEM.def \
+         termios.def  TimeString.def \
+         UnixArgs.def  wrapc.def  \
+         GetOpt.def OptLib.def \
+         cgetopt.def
+
+libm2pim_la_SOURCES = $(M2MODS) \
+                      UnixArgs.cc \
+                      Selective.cc sckt.cc \
+                      errno.cc dtoa.cc \
+                      ldtoa.cc termios.cc \
+                      SysExceptions.cc target.c \
+                      wrapc.c cgetopt.cc
+
+libm2pimdir = libm2pim
+libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2pim_la_SOURCES)))
+libm2pim_la_CFLAGS = -I. -I.. -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -DBUILD_GM2_LIBS -I@srcdir@/../  -I@srcdir@/../libm2iso
+libm2pim_la_M2FLAGS = -I. -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -fm2-g -g
+libm2pim_la_LINK = $(LINK) -version-info $(libtool_VERSION)
+BUILT_SOURCES = SYSTEM.def
+CLEANFILES = SYSTEM.def
+
+M2LIBDIR = /m2/m2pim/
+
+SYSTEM.def: Makefile
+	bash $(GM2_SRC)/tools-src/makeSystem -fpim \
+             $(GM2_SRC)/gm2-libs/SYSTEM.def \
+             $(GM2_SRC)/gm2-libs/SYSTEM.mod \
+             -I$(GM2_SRC)/gm2-libs \
+             "$(GM2_FOR_TARGET)" $@
+
+.mod.lo: SYSTEM.def
+	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2pim_la_M2FLAGS) $< -o $@
+
+.cc.lo:
+	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) -c -I$(srcdir) $(CXXFLAGS) $(LIBCFLAGS) $(libm2pim_la_CFLAGS) $< -o $@
+
+install-data-local: force
+	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
+	$(INSTALL_DATA) .libs/libm2pim.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
+	chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2pim.la
+	$(INSTALL_DATA) .libs/libm2pim.a $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
+	$(RANLIB) $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)libm2pim.a
+	for i in $(M2DEFS) $(M2MODS) ; do \
+           if [ -f $$i ] ; then \
+              $(INSTALL_DATA) $$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
+           elif [ -f @srcdir@/../../gcc/m2/gm2-libs/$$i ] ; then \
+              $(INSTALL_DATA) @srcdir@/../../gcc/m2/gm2-libs/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
+           else \
+              echo "cannot find $$i" ; exit 1 ; \
+           fi ; \
+           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
+	done
+
+force:
+
+endif
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/ldtoa.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/ldtoa.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,190 @@
+/* ldtoa.c convert long double to ascii and visa versa.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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/>.  */
+
+#define GM2
+
+#include <config.h>
+#include <m2rts.h>
+
+#if defined(HAVE_STRINGS)
+#include <strings.h>
+#endif
+
+#if defined(HAVE_STRING)
+#include <string.h>
+#endif
+
+#if defined(HAVE_STDDEF_H)
+/* Obtain a definition for NULL.  */
+#include <stddef.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+/* Obtain a definition for NULL.  */
+#include <stdio.h>
+#endif
+
+#if defined(HAVE_TIME_H)
+/* Obtain a definition for NULL.  */
+#include <time.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+/* Obtain a definition for NULL.  */
+#include <string.h>
+#endif
+
+#if defined(HAVE_WCHAR_H)
+/* Obtain a definition for NULL.  */
+#include <wchar.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+#if !defined(_ISOC99_SOURCE)
+#define _ISOC99_SOURCE
+#endif
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+#include <errno.h>
+#endif
+
+#if defined(HAVE_SYS_ERRNO_H)
+#include <sys/errno.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+/* Obtain a prototype for free and malloc.  */
+#include <stdlib.h>
+#endif
+
+#if !defined(NULL)
+#define NULL (void *)0
+#endif
+
+#if !defined(TRUE)
+#define TRUE (1 == 1)
+#endif
+#if !defined(FALSE)
+#define FALSE (1 == 0)
+#endif
+
+#define MAX_FP_DIGITS 500
+
+typedef enum Mode { maxsignicant, decimaldigits } Mode;
+
+extern "C" int dtoa_calcmaxsig (char *p, int ndigits);
+extern "C" int dtoa_calcdecimal (char *p, int str_size, int ndigits);
+extern "C" int dtoa_calcsign (char *p, int str_size);
+
+/* maxsignicant return a string containing max(1,ndigits) significant
+   digits.  The return string contains the string produced by snprintf.
+
+   decimaldigits: return a string produced by fcvt.  The string will
+   contain ndigits past the decimal point (ndigits may be negative).  */
+
+extern "C" long double
+ldtoa_strtold (const char *s, int *error)
+{
+  char *endp;
+  long double d;
+
+#if defined(HAVE_ERRNO_H)
+  errno = 0;
+#endif
+#if defined(HAVE_STRTOLD)
+  d = strtold (s, &endp);
+#else
+  /* Fall back to using strtod.  */
+  d = (long double)strtod (s, &endp);
+#endif
+  if (endp != NULL && (*endp == '\0'))
+#if defined(HAVE_ERRNO_H)
+    *error = (errno != 0);
+#else
+    *error = FALSE;
+#endif
+  else
+    *error = TRUE;
+  return d;
+}
+
+extern "C" char *
+ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
+{
+  char format[50];
+  char *p;
+  int r;
+  switch (mode)
+    {
+
+    case maxsignicant:
+      ndigits += 20; /* Enough for exponent.  */
+      p = (char *) malloc (ndigits);
+      snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "LE");
+      snprintf (p, ndigits, format, d);
+      *sign = dtoa_calcsign (p, ndigits);
+      *decpt = dtoa_calcmaxsig (p, ndigits);
+      return p;
+    case decimaldigits:
+      p = (char *) malloc (MAX_FP_DIGITS + 20);
+      snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "LE");
+      snprintf (p, MAX_FP_DIGITS + 20, format, d);
+      *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
+      *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
+      return p;
+    default:
+      abort ();
+    }
+}
+
+#if defined(GM2)
+/* GNU Modula-2 linking hooks.  */
+
+extern "C" void
+_M2_ldtoa_init (int, char **, char **)
+{
+}
+
+extern "C" void
+_M2_ldtoa_fini (int, char **, char **)
+{
+}
+
+extern "C" void
+_M2_ldtoa_dep (void)
+{
+}
+
+struct _M2_ldtoa_ctor { _M2_ldtoa_ctor (); } _M2_ldtoa_ctor;
+
+_M2_ldtoa_ctor::_M2_ldtoa_ctor (void)
+{
+  M2RTS_RegisterModule ("ldtoa", _M2_ldtoa_init, _M2_ldtoa_fini,
+			_M2_ldtoa_dep);
+}
+#endif
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/cgetopt.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/cgetopt.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,158 @@
+/* cgetopt.cc provide access to the C getopt library.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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 <unistd.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <m2rts.h>
+
+extern "C" {char *cgetopt_optarg;}
+extern "C" {int cgetopt_optind;}
+extern "C" {int cgetopt_opterr;}
+extern "C" {int cgetopt_optopt;}
+
+extern "C" char
+cgetopt_getopt (int argc, char *argv[], char *optstring)
+{
+  char r = getopt (argc, argv, optstring);
+
+  cgetopt_optarg = optarg;
+  cgetopt_optind = optind;
+  cgetopt_opterr = opterr;
+  cgetopt_optopt = optopt;
+
+  if (r == (char)-1)
+    return (char)0;
+  return r;
+}
+
+extern "C" int
+cgetopt_getopt_long (int argc, char *argv[], char *optstring,
+                    const struct option *longopts, int *longindex)
+{
+  int r = getopt_long (argc, argv, optstring, longopts, longindex);
+
+  cgetopt_optarg = optarg;
+  cgetopt_optind = optind;
+  cgetopt_opterr = opterr;
+  cgetopt_optopt = optopt;
+
+  return r;
+}
+
+extern "C" int
+cgetopt_getopt_long_only (int argc, char *argv[], char *optstring,
+                         const struct option *longopts, int *longindex)
+{
+  int r = getopt_long_only (argc, argv, optstring, longopts, longindex);
+
+  cgetopt_optarg = optarg;
+  cgetopt_optind = optind;
+  cgetopt_opterr = opterr;
+  cgetopt_optopt = optopt;
+
+  return r;
+}
+
+typedef struct cgetopt_Options_s
+{
+  struct option *cinfo;
+  unsigned int high;
+} cgetopt_Options;
+
+/* InitOptions a constructor for Options.  */
+
+extern "C" cgetopt_Options *
+cgetopt_InitOptions (void)
+{
+  cgetopt_Options *o = (cgetopt_Options *)malloc (sizeof (cgetopt_Options));
+  o->cinfo = (struct option *)malloc (sizeof (struct option));
+  o->high = 0;
+  return o;
+}
+
+/* KillOptions a deconstructor for Options.  Returns NULL after freeing
+   up all allocated memory associated with o.  */
+
+extern "C" cgetopt_Options *
+cgetopt_KillOptions (cgetopt_Options *o)
+{
+  free (o->cinfo);
+  free (o);
+  return NULL;
+}
+
+/* SetOption set option[index] with {name, has_arg, flag, val}.  */
+
+extern "C" void
+cgetopt_SetOption (cgetopt_Options *o, unsigned int index, char *name,
+ 		   unsigned int has_arg, int *flag, int val)
+{
+  if (index > o->high)
+    {
+      o->cinfo
+          = (struct option *)malloc (sizeof (struct option) * (index + 1));
+      o->high = index + 1;
+    }
+  o->cinfo[index].name = name;
+  o->cinfo[index].has_arg = has_arg;
+  o->cinfo[index].flag = flag;
+  o->cinfo[index].val = val;
+}
+
+/* GetLongOptionArray returns a pointer to the C array containing all
+   long options.  */
+
+extern "C" struct option *
+cgetopt_GetLongOptionArray (cgetopt_Options *o)
+{
+  return o->cinfo;
+}
+
+/* GNU Modula-2 linking fodder.  */
+
+extern "C" void
+_M2_cgetopt_init (int, char *argv[], char *env[])
+{
+}
+
+extern "C" void
+_M2_cgetopt_fini (int, char *argv[], char *env[])
+{
+}
+
+extern "C" void
+_M2_cgetopt_dep (void)
+{
+}
+
+struct _M2_cgetopt_ctor { _M2_cgetopt_ctor (); } _M2_cgetopt_ctor;
+
+_M2_cgetopt_ctor::_M2_cgetopt_ctor (void)
+{
+  M2RTS_RegisterModule ("cgetopt", _M2_cgetopt_init, _M2_cgetopt_fini,
+			_M2_cgetopt_dep);
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/errno.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/errno.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,70 @@
+/* errno.c provide access to the errno value.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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>
+
+#if defined(HAVE_SYS_ERRNO_H)
+#include <sys/errno.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+#include <errno.h>
+#endif
+
+#include "m2rts.h"
+
+extern "C" int
+errno_geterrno (void)
+{
+#if defined(HAVE_ERRNO_H) || defined(HAVE_SYS_ERRNO_H)
+  return errno;
+#else
+  return -1;
+#endif
+}
+
+extern "C" void
+_M2_errno_init (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_errno_fini (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_errno_dep (void)
+{
+}
+
+struct _M2_errno_ctor { _M2_errno_ctor (); } _M2_errno_ctor;
+
+_M2_errno_ctor::_M2_errno_ctor (void)
+{
+  M2RTS_RegisterModule ("errno", _M2_errno_init, _M2_errno_fini,
+			_M2_errno_dep);
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/UnixArgs.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/UnixArgs.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,91 @@
+/* UnixArgs.cc record argc, argv as global variables.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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 <m2rts.h>
+
+
+extern "C" int UnixArgs_GetArgC (void);
+extern "C" char **UnixArgs_GetArgV (void);
+extern "C" char **UnixArgs_GetEnvV (void);
+
+static int UnixArgs_ArgC;
+static char **UnixArgs_ArgV;
+static char **UnixArgs_EnvV;
+
+
+/* GetArgC returns argc.  */
+
+extern "C" int
+UnixArgs_GetArgC (void)
+{
+  return UnixArgs_ArgC;
+}
+
+
+/* GetArgV returns argv.  */
+
+extern "C" char **
+UnixArgs_GetArgV (void)
+{
+  return UnixArgs_ArgV;
+}
+
+
+/* GetEnvV returns envv.  */
+
+extern "C" char **
+UnixArgs_GetEnvV (void)
+{
+  return UnixArgs_EnvV;
+}
+
+
+extern "C" void
+_M2_UnixArgs_init (int argc, char *argv[], char *envp[])
+{
+  UnixArgs_ArgC = argc;
+  UnixArgs_ArgV = argv;
+  UnixArgs_EnvV = envp;
+}
+
+extern "C" void
+_M2_UnixArgs_fini (int argc, char *argv[], char *envp[])
+{
+}
+
+extern "C" void
+_M2_UnixArgs_dep (void)
+{
+}
+
+struct _M2_UnixArgs_ctor { _M2_UnixArgs_ctor (); } _M2_UnixArgs_ctor;
+
+_M2_UnixArgs_ctor::_M2_UnixArgs_ctor (void)
+{
+  M2RTS_RegisterModule ("UnixArgs", _M2_UnixArgs_init, _M2_UnixArgs_fini,
+			_M2_UnixArgs_dep);
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/termios.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/termios.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,1987 @@
+/* termios.cc provide access to the terminal.
+
+Copyright (C) 2010-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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 <m2rts.h>
+
+#if defined(HAVE_STDIO_H)
+#include <stdio.h>
+#endif
+#if defined(HAVE_STDARG_H)
+#include <stdarg.h>
+#endif
+#if defined(HAVE_STDLIB_H)
+#include <stdlib.h>
+#endif
+#if defined(HAVE_STRING_H)
+#include <string.h>
+#endif
+#if defined(HAVE_STRINGS_H)
+#include <strings.h>
+#endif
+
+#ifdef TERMIOS_NEEDS_XOPEN_SOURCE
+#define _XOPEN_SOURCE
+#endif
+
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_TERMIOS_H)
+#include <termios.h>
+#endif
+
+void _M2_termios_init (void);
+void _M2_termios_finish (void);
+
+#if defined(HAVE_TERMIOS_H)
+
+#define EXPORT(X) termios##_##X
+
+typedef enum {
+  vintr,
+  vquit,
+  verase,
+  vkill,
+  veof,
+  vtime,
+  vmin,
+  vswtc,
+  vstart,
+  vstop,
+  vsusp,
+  veol,
+  vreprint,
+  vdiscard,
+  vwerase,
+  vlnext,
+  veol2
+} ControlChar;
+
+typedef enum {
+  /* Input flag bits.  */
+  ignbrk,
+  ibrkint,
+  ignpar,
+  iparmrk,
+  inpck,
+  istrip,
+  inlcr,
+  igncr,
+  icrnl,
+  iuclc,
+  ixon,
+  ixany,
+  ixoff,
+  imaxbel,
+  /* Output flag bits.  */
+  opost,
+  olcuc,
+  onlcr,
+  ocrnl,
+  onocr,
+  onlret,
+  ofill,
+  ofdel,
+  onl0,
+  onl1,
+  ocr0,
+  ocr1,
+  ocr2,
+  ocr3,
+  otab0,
+  otab1,
+  otab2,
+  otab3,
+  obs0,
+  obs1,
+  off0,
+  off1,
+  ovt0,
+  ovt1,
+  /* Baud rate.  */
+  b0,
+  b50,
+  b75,
+  b110,
+  b135,
+  b150,
+  b200,
+  b300,
+  b600,
+  b1200,
+  b1800,
+  b2400,
+  b4800,
+  b9600,
+  b19200,
+  b38400,
+  b57600,
+  b115200,
+  b240400,
+  b460800,
+  b500000,
+  b576000,
+  b921600,
+  b1000000,
+  b1152000,
+  b1500000,
+  b2000000,
+  b2500000,
+  b3000000,
+  b3500000,
+  b4000000,
+  maxbaud,
+  crtscts,
+  /* Character size.  */
+  cs5,
+  cs6,
+  cs7,
+  cs8,
+  cstopb,
+  cread,
+  parenb,
+  parodd,
+  hupcl,
+  clocal,
+  /* Local flags.  */
+  lisig,
+  licanon,
+  lxcase,
+  lecho,
+  lechoe,
+  lechok,
+  lechonl,
+  lnoflsh,
+  ltopstop,
+  lechoctl,
+  lechoprt,
+  lechoke,
+  lflusho,
+  lpendin,
+  liexten
+} Flag;
+
+/* Prototypes.  */
+extern "C" void *EXPORT (InitTermios) (void);
+extern "C" void *EXPORT (KillTermios) (struct termios *p);
+extern "C" int EXPORT (cfgetospeed) (struct termios *t);
+extern "C" int EXPORT (cfgetispeed) (struct termios *t);
+extern "C" int EXPORT (cfsetospeed) (struct termios *t, unsigned int b);
+extern "C" int EXPORT (cfsetispeed) (struct termios *t, unsigned int b);
+extern "C" int EXPORT (cfsetspeed) (struct termios *t, unsigned int b);
+extern "C" int EXPORT (tcgetattr) (int fd, struct termios *t);
+extern "C" int EXPORT (tcsetattr) (int fd, int option, struct termios *t);
+extern "C" void EXPORT (cfmakeraw) (struct termios *t);
+extern "C" int EXPORT (tcsendbreak) (int fd, int duration);
+extern "C" int EXPORT (tcdrain) (int fd);
+extern "C" int EXPORT (tcflushi) (int fd);
+extern "C" int EXPORT (tcflusho) (int fd);
+extern "C" int EXPORT (tcflushio) (int fd);
+extern "C" int EXPORT (tcflowoni) (int fd);
+extern "C" int EXPORT (tcflowoffi) (int fd);
+extern "C" int EXPORT (tcflowono) (int fd);
+extern "C" int EXPORT (tcflowoffo) (int fd);
+extern "C" int EXPORT (GetFlag) (struct termios *t, Flag f, int *b);
+extern "C" int EXPORT (SetFlag) (struct termios *t, Flag f, int b);
+extern "C" int EXPORT (GetChar) (struct termios *t, ControlChar c, char *ch);
+extern "C" int EXPORT (SetChar) (struct termios *t, ControlChar c, char ch);
+extern "C" int EXPORT (tcsnow) (void);
+extern "C" int EXPORT (tcsflush) (void);
+extern "C" int EXPORT (tcsdrain) (void);
+extern "C" int doSetUnset (tcflag_t *bitset, unsigned int mask, int value);
+
+/* InitTermios new data structure.   */
+
+extern "C" void
+*EXPORT (InitTermios) (void)
+{
+  struct termios *p = (struct termios *)malloc (sizeof (struct termios));
+
+  memset (p, 0, sizeof (struct termios));
+  return p;
+}
+
+/* KillTermios delete data structure.  */
+
+extern "C" void*
+EXPORT (KillTermios) (struct termios *p)
+{
+  free (p);
+  return NULL;
+}
+
+/* tcsnow return the value of TCSANOW.  */
+
+extern "C" int
+EXPORT (tcsnow) (void) { return TCSANOW; }
+
+/* tcsdrain return the value of TCSADRAIN.  */
+
+extern "C" int
+EXPORT (tcsdrain) (void) { return TCSADRAIN; }
+
+/* tcsflush return the value of TCSAFLUSH.  */
+
+extern "C" int
+EXPORT (tcsflush) (void) { return TCSAFLUSH; }
+
+/* cfgetospeed return output baud rate.  */
+
+extern "C" int
+EXPORT (cfgetospeed) (struct termios *t) { return cfgetospeed (t); }
+
+/* cfgetispeed return input baud rate.  */
+
+extern "C" int
+EXPORT (cfgetispeed) (struct termios *t) { return cfgetispeed (t); }
+
+/* cfsetospeed set output baud rate.  */
+
+extern "C" int
+EXPORT (cfsetospeed) (struct termios *t, unsigned int b)
+{
+  return cfsetospeed (t, b);
+}
+
+/* cfsetispeed set input baud rate.  */
+
+extern "C" int
+EXPORT (cfsetispeed) (struct termios *t, unsigned int b)
+{
+  return cfsetispeed (t, b);
+}
+
+/* cfsetspeed set input and output baud rate.  */
+
+extern "C" int
+EXPORT (cfsetspeed) (struct termios *t, unsigned int b)
+{
+  int val = cfsetispeed (t, b);
+  if (val == 0)
+    return cfsetospeed (t, b);
+  cfsetospeed (t, b);
+  return val;
+}
+
+/* tcgetattr get state of, fd, into, t.  */
+
+extern "C" int
+EXPORT (tcgetattr) (int fd, struct termios *t)
+{
+  return tcgetattr (fd, t);
+}
+
+/* tcsetattr set state of, fd, to, t, using option.  */
+
+int EXPORT (tcsetattr) (int fd, int option, struct termios *t)
+{
+  return tcsetattr (fd, option, t);
+}
+
+/* cfmakeraw sets the terminal to raw mode.  */
+
+extern "C" void
+EXPORT (cfmakeraw) (struct termios *t)
+{
+#if defined(HAVE_CFMAKERAW)
+  return cfmakeraw (t);
+#endif
+}
+
+/* tcsendbreak send zero bits for duration.  */
+
+extern "C" int
+EXPORT (tcsendbreak) (int fd, int duration)
+{
+  return tcsendbreak (fd, duration);
+}
+
+/* tcdrain waits for pending output to be written on, fd.  */
+
+extern "C" int
+EXPORT (tcdrain) (int fd) { return tcdrain (fd); }
+
+/* tcflushi flush input.  */
+
+extern "C" int
+EXPORT (tcflushi) (int fd)
+{
+#if defined(TCIFLUSH)
+  return tcflush (fd, TCIFLUSH);
+#else
+  return 1;
+#endif
+}
+
+/* tcflusho flush output.  */
+
+extern "C" int
+EXPORT (tcflusho) (int fd)
+{
+#if defined(TCOFLUSH)
+  return tcflush (fd, TCOFLUSH);
+#else
+  return 1;
+#endif
+}
+
+/* tcflushio flush input and output.  */
+
+extern "C" int
+EXPORT (tcflushio) (int fd)
+{
+#if defined(TCIOFLUSH)
+  return tcflush (fd, TCIOFLUSH);
+#else
+  return 1;
+#endif
+}
+
+/* tcflowoni restart input on, fd.  */
+
+extern "C" int
+EXPORT (tcflowoni) (int fd)
+{
+#if defined(TCION)
+  return tcflow (fd, TCION);
+#else
+  return 1;
+#endif
+}
+
+/* tcflowoffi stop input on, fd.  */
+
+extern "C" int
+EXPORT (tcflowoffi) (int fd)
+{
+#if defined(TCIOFF)
+  return tcflow (fd, TCIOFF);
+#else
+  return 1;
+#endif
+}
+
+/* tcflowono restart output on, fd.  */
+
+extern "C" int
+EXPORT (tcflowono) (int fd)
+{
+#if defined(TCOON)
+  return tcflow (fd, TCOON);
+#else
+  return 1;
+#endif
+}
+
+/* tcflowoffo stop output on, fd.  */
+
+extern "C" int
+EXPORT (tcflowoffo) (int fd)
+{
+#if defined(TCOOFF)
+  return tcflow (fd, TCOOFF);
+#else
+  return 1;
+#endif
+}
+
+/* doSetUnset applies mask or undoes mask depending upon value.  */
+
+extern "C" int
+doSetUnset (tcflag_t *bitset, unsigned int mask, int value)
+{
+  if (value)
+    (*bitset) |= mask;
+  else
+    (*bitset) &= (~mask);
+  return 1;
+}
+
+/* GetFlag sets a flag value from, t, in, b, and returns TRUE
+   if, t, supports, f.  */
+
+extern "C" int
+EXPORT (GetFlag) (struct termios *t, Flag f, int *b)
+{
+  switch (f)
+    {
+
+    case ignbrk:
+#if defined(IGNBRK)
+      *b = ((t->c_iflag & IGNBRK) == IGNBRK);
+      return 1;
+#else
+      return 0;
+#endif
+    case ibrkint:
+#if defined(BRKINT)
+      *b = ((t->c_iflag & BRKINT) == BRKINT);
+      return 1;
+#else
+      return 0;
+#endif
+    case ignpar:
+#if defined(IGNPAR)
+      *b = ((t->c_iflag & IGNPAR) == IGNPAR);
+      return 1;
+#else
+      return 0;
+#endif
+    case iparmrk:
+#if defined(PARMRK)
+      *b = ((t->c_iflag & PARMRK) == PARMRK);
+      return 1;
+#else
+      return 0;
+#endif
+    case inpck:
+#if defined(INPCK)
+      *b = ((t->c_iflag & INPCK) == INPCK);
+      return 1;
+#else
+      return 0;
+#endif
+    case istrip:
+#if defined(ISTRIP)
+      *b = ((t->c_iflag & ISTRIP) == ISTRIP);
+      return 1;
+#else
+      return 0;
+#endif
+    case inlcr:
+#if defined(INLCR)
+      *b = ((t->c_iflag & INLCR) == INLCR);
+      return 1;
+#else
+      return 0;
+#endif
+    case igncr:
+#if defined(IGNCR)
+      *b = ((t->c_iflag & IGNCR) == IGNCR);
+      return 1;
+#else
+      return 0;
+#endif
+    case icrnl:
+#if defined(ICRNL)
+      *b = ((t->c_iflag & ICRNL) == ICRNL);
+      return 1;
+#else
+      return 0;
+#endif
+    case iuclc:
+#if defined(IUCLC)
+      *b = ((t->c_iflag & IUCLC) == IUCLC);
+      return 1;
+#else
+      return 0;
+#endif
+    case ixon:
+#if defined(IXON)
+      *b = ((t->c_iflag & IXON) == IXON);
+      return 1;
+#else
+      return 0;
+#endif
+    case ixany:
+#if defined(IXANY)
+      *b = ((t->c_iflag & IXANY) == IXANY);
+      return 1;
+#else
+      return 0;
+#endif
+    case ixoff:
+#if defined(IXOFF)
+      *b = ((t->c_iflag & IXOFF) == IXOFF);
+      return 1;
+#else
+      return 0;
+#endif
+    case imaxbel:
+#if defined(IMAXBEL)
+      *b = ((t->c_iflag & IMAXBEL) == IMAXBEL);
+      return 1;
+#else
+      return 0;
+#endif
+    case opost:
+#if defined(OPOST)
+      *b = ((t->c_oflag & OPOST) == OPOST);
+      return 1;
+#else
+      return 0;
+#endif
+    case olcuc:
+#if defined(OLCUC)
+      *b = ((t->c_oflag & OLCUC) == OLCUC);
+      return 1;
+#else
+      return 0;
+#endif
+    case onlcr:
+#if defined(ONLCR)
+      *b = ((t->c_oflag & ONLCR) == ONLCR);
+      return 1;
+#else
+      return 0;
+#endif
+    case ocrnl:
+#if defined(OCRNL)
+      *b = ((t->c_oflag & OCRNL) == OCRNL);
+      return 1;
+#else
+      return 0;
+#endif
+    case onocr:
+#if defined(ONOCR)
+      *b = ((t->c_oflag & ONOCR) == ONOCR);
+      return 1;
+#else
+      return 0;
+#endif
+    case onlret:
+#if defined(ONLRET)
+      *b = ((t->c_oflag & ONLRET) == ONLRET);
+      return 1;
+#else
+      return 0;
+#endif
+    case ofill:
+#if defined(OFILL)
+      *b = ((t->c_oflag & OFILL) == OFILL);
+      return 1;
+#else
+      return 0;
+#endif
+    case ofdel:
+#if defined(OFDEL)
+      *b = ((t->c_oflag & OFDEL) == OFDEL);
+      return 1;
+#else
+      return 0;
+#endif
+    case onl0:
+#if defined(NL0)
+      *b = ((t->c_oflag & NL0) == NL0);
+      return 1;
+#else
+      return 0;
+#endif
+    case onl1:
+#if defined(NL1)
+      *b = ((t->c_oflag & NL1) == NL1);
+      return 1;
+#else
+      return 0;
+#endif
+    case ocr0:
+#if defined(CR0)
+      *b = ((t->c_oflag & CR0) == CR0);
+      return 1;
+#else
+      return 0;
+#endif
+    case ocr1:
+#if defined(CR1)
+      *b = ((t->c_oflag & CR1) == CR1);
+      return 1;
+#else
+      return 0;
+#endif
+    case ocr2:
+#if defined(CR2)
+      *b = ((t->c_oflag & CR2) == CR2);
+      return 1;
+#else
+      return 0;
+#endif
+    case ocr3:
+#if defined(CR3)
+      *b = ((t->c_oflag & CR3) == CR3);
+      return 1;
+#else
+      return 0;
+#endif
+    case otab0:
+#if defined(TAB0)
+      *b = ((t->c_oflag & TAB0) == TAB0);
+      return 1;
+#else
+      return 0;
+#endif
+    case otab1:
+#if defined(TAB1)
+      *b = ((t->c_oflag & TAB1) == TAB1);
+      return 1;
+#else
+      return 0;
+#endif
+    case otab2:
+#if defined(TAB2)
+      *b = ((t->c_oflag & TAB2) == TAB2);
+      return 1;
+#else
+      return 0;
+#endif
+    case otab3:
+#if defined(TAB3)
+      *b = ((t->c_oflag & TAB3) == TAB3);
+      return 1;
+#else
+      return 0;
+#endif
+    case obs0:
+#if defined(BS0)
+      *b = ((t->c_oflag & BS0) == BS0);
+      return 1;
+#else
+      return 0;
+#endif
+    case obs1:
+#if defined(BS1)
+      *b = ((t->c_oflag & BS1) == BS1);
+      return 1;
+#else
+      return 0;
+#endif
+    case off0:
+#if defined(FF0)
+      *b = ((t->c_oflag & FF0) == FF0);
+      return 1;
+#else
+      return 0;
+#endif
+    case off1:
+#if defined(FF1)
+      *b = ((t->c_oflag & FF1) == FF1);
+      return 1;
+#else
+      return 0;
+#endif
+    case ovt0:
+#if defined(VT0)
+      *b = ((t->c_oflag & VT0) == VT0);
+      return 1;
+#else
+      return 0;
+#endif
+    case ovt1:
+#if defined(VT1)
+      *b = ((t->c_oflag & VT1) == VT1);
+      return 1;
+#else
+      return 0;
+#endif
+    case b0:
+#if defined(B0)
+      *b = ((t->c_cflag & B0) == B0);
+      return 1;
+#else
+      return 0;
+#endif
+    case b50:
+#if defined(B50)
+      *b = ((t->c_cflag & B50) == B50);
+      return 1;
+#else
+      return 0;
+#endif
+    case b75:
+#if defined(B75)
+      *b = ((t->c_cflag & B75) == B75);
+      return 1;
+#else
+      return 0;
+#endif
+    case b110:
+#if defined(B110)
+      *b = ((t->c_cflag & B110) == B110);
+      return 1;
+#else
+      return 0;
+#endif
+    case b135:
+#if defined(B134)
+      *b = ((t->c_cflag & B134) == B134);
+      return 1;
+#else
+      return 0;
+#endif
+    case b150:
+#if defined(B150)
+      *b = ((t->c_cflag & B150) == B150);
+      return 1;
+#else
+      return 0;
+#endif
+    case b200:
+#if defined(B200)
+      *b = ((t->c_cflag & B200) == B200);
+      return 1;
+#else
+      return 0;
+#endif
+    case b300:
+#if defined(B300)
+      *b = ((t->c_cflag & B300) == B300);
+      return 1;
+#else
+      return 0;
+#endif
+    case b600:
+#if defined(B600)
+      *b = ((t->c_cflag & B600) == B600);
+      return 1;
+#else
+      return 0;
+#endif
+    case b1200:
+#if defined(B1200)
+      *b = ((t->c_cflag & B1200) == B1200);
+      return 1;
+#else
+      return 0;
+#endif
+    case b1800:
+#if defined(B1800)
+      *b = ((t->c_cflag & B1800) == B1800);
+      return 1;
+#else
+      return 0;
+#endif
+    case b2400:
+#if defined(B2400)
+      *b = ((t->c_cflag & B2400) == B2400);
+      return 1;
+#else
+      return 0;
+#endif
+    case b4800:
+#if defined(B4800)
+      *b = ((t->c_cflag & B4800) == B4800);
+      return 1;
+#else
+      return 0;
+#endif
+    case b9600:
+#if defined(B9600)
+      *b = ((t->c_cflag & B9600) == B9600);
+      return 1;
+#else
+      return 0;
+#endif
+    case b19200:
+#if defined(B19200)
+      *b = ((t->c_cflag & B19200) == B19200);
+      return 1;
+#else
+      return 0;
+#endif
+    case b38400:
+#if defined(B38400)
+      *b = ((t->c_cflag & B38400) == B38400);
+      return 1;
+#else
+      return 0;
+#endif
+    case b57600:
+#if defined(B57600)
+      *b = ((t->c_cflag & B57600) == B57600);
+      return 1;
+#else
+      return 0;
+#endif
+    case b115200:
+#if defined(B115200)
+      *b = ((t->c_cflag & B115200) == B115200);
+      return 1;
+#else
+      return 0;
+#endif
+    case b240400:
+#if defined(B230400)
+      *b = ((t->c_cflag & B230400) == B230400);
+      return 1;
+#else
+      return 0;
+#endif
+    case b460800:
+#if defined(B460800)
+      *b = ((t->c_cflag & B460800) == B460800);
+      return 1;
+#else
+      return 0;
+#endif
+    case b500000:
+#if defined(B500000)
+      *b = ((t->c_cflag & B500000) == B500000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b576000:
+#if defined(B576000)
+      *b = ((t->c_cflag & B576000) == B576000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b921600:
+#if defined(B921600)
+      *b = ((t->c_cflag & B921600) == B921600);
+      return 1;
+#else
+      return 0;
+#endif
+    case b1000000:
+#if defined(B1000000)
+      *b = ((t->c_cflag & B1000000) == B1000000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b1152000:
+#if defined(B1152000)
+      *b = ((t->c_cflag & B1152000) == B1152000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b1500000:
+#if defined(B1500000)
+      *b = ((t->c_cflag & B1500000) == B1500000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b2000000:
+#if defined(B2000000)
+      *b = ((t->c_cflag & B2000000) == B2000000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b2500000:
+#if defined(B2500000)
+      *b = ((t->c_cflag & B2500000) == B2500000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b3000000:
+#if defined(B3000000)
+      *b = ((t->c_cflag & B3000000) == B3000000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b3500000:
+#if defined(B3500000)
+      *b = ((t->c_cflag & B3500000) == B3500000);
+      return 1;
+#else
+      return 0;
+#endif
+    case b4000000:
+#if defined(B4000000)
+      *b = ((t->c_cflag & B4000000) == B4000000);
+      return 1;
+#else
+      return 0;
+#endif
+    case maxbaud:
+#if defined(MAX)
+      *b = ((t->c_cflag & __MAX_BAUD) == __MAX_BAUD);
+      return 1;
+#else
+      return 0;
+#endif
+    case crtscts:
+#if defined(CRTSCTS)
+      *b = ((t->c_cflag & CRTSCTS) == CRTSCTS);
+      return 1;
+#else
+      return 0;
+#endif
+    case cs5:
+#if defined(CS5)
+      *b = ((t->c_cflag & CS5) == CS5);
+      return 1;
+#else
+      return 0;
+#endif
+    case cs6:
+#if defined(CS6)
+      *b = ((t->c_cflag & CS6) == CS6);
+      return 1;
+#else
+      return 0;
+#endif
+    case cs7:
+#if defined(CS7)
+      *b = ((t->c_cflag & CS7) == CS7);
+      return 1;
+#else
+      return 0;
+#endif
+    case cs8:
+#if defined(CS8)
+      *b = ((t->c_cflag & CS8) == CS8);
+      return 1;
+#else
+      return 0;
+#endif
+    case cstopb:
+#if defined(CSTOPB)
+      *b = ((t->c_cflag & CSTOPB) == CSTOPB);
+      return 1;
+#else
+      return 0;
+#endif
+    case cread:
+#if defined(CREAD)
+      *b = ((t->c_cflag & CREAD) == CREAD);
+      return 1;
+#else
+      return 0;
+#endif
+    case parenb:
+#if defined(PARENB)
+      *b = ((t->c_cflag & PARENB) == PARENB);
+      return 1;
+#else
+      return 0;
+#endif
+    case parodd:
+#if defined(PARODD)
+      *b = ((t->c_cflag & PARODD) == PARODD);
+      return 1;
+#else
+      return 0;
+#endif
+    case hupcl:
+#if defined(HUPCL)
+      *b = ((t->c_cflag & HUPCL) == HUPCL);
+      return 1;
+#else
+      return 0;
+#endif
+    case clocal:
+#if defined(CLOCAL)
+      *b = ((t->c_cflag & CLOCAL) == CLOCAL);
+      return 1;
+#else
+      return 0;
+#endif
+    case lisig:
+#if defined(ISIG)
+      *b = ((t->c_lflag & ISIG) == ISIG);
+      return 1;
+#else
+      return 0;
+#endif
+    case licanon:
+#if defined(ICANON)
+      *b = ((t->c_lflag & ICANON) == ICANON);
+      return 1;
+#else
+      return 0;
+#endif
+    case lxcase:
+#if defined(XCASE)
+      *b = ((t->c_lflag & XCASE) == XCASE);
+      return 1;
+#else
+      return 0;
+#endif
+    case lecho:
+#if defined(ECHO)
+      *b = ((t->c_lflag & ECHO) == ECHO);
+      return 1;
+#else
+      return 0;
+#endif
+    case lechoe:
+#if defined(ECHOE)
+      *b = ((t->c_lflag & ECHOE) == ECHOE);
+      return 1;
+#else
+      return 0;
+#endif
+    case lechok:
+#if defined(ECHOK)
+      *b = ((t->c_lflag & ECHOK) == ECHOK);
+      return 1;
+#else
+      return 0;
+#endif
+    case lechonl:
+#if defined(ECHONL)
+      *b = ((t->c_lflag & ECHONL) == ECHONL);
+      return 1;
+#else
+      return 0;
+#endif
+    case lnoflsh:
+#if defined(NOFLSH)
+      *b = ((t->c_lflag & NOFLSH) == NOFLSH);
+      return 1;
+#else
+      return 0;
+#endif
+    case ltopstop:
+#if defined(TOSTOP)
+      *b = ((t->c_lflag & TOSTOP) == TOSTOP);
+      return 1;
+#else
+      return 0;
+#endif
+    case lechoctl:
+#if defined(ECHOCTL)
+      *b = ((t->c_lflag & ECHOCTL) == ECHOCTL);
+      return 1;
+#else
+      return 0;
+#endif
+    case lechoprt:
+#if defined(ECHOPRT)
+      *b = ((t->c_lflag & ECHOPRT) == ECHOPRT);
+      return 1;
+#else
+      return 0;
+#endif
+    case lechoke:
+#if defined(ECHOKE)
+      *b = ((t->c_lflag & ECHOKE) == ECHOKE);
+      return 1;
+#else
+      return 0;
+#endif
+    case lflusho:
+#if defined(FLUSHO)
+      *b = ((t->c_lflag & FLUSHO) == FLUSHO);
+      return 1;
+#else
+      return 0;
+#endif
+    case lpendin:
+#if defined(PENDIN)
+      *b = ((t->c_lflag & PENDIN) == PENDIN);
+      return 1;
+#else
+      return 0;
+#endif
+    case liexten:
+#if defined(IEXTEN)
+      *b = ((t->c_lflag & IEXTEN) == IEXTEN);
+      return 1;
+#else
+      return 0;
+#endif
+    }
+  return 0;
+}
+
+/* SetFlag sets a flag value in, t, to, b, and returns TRUE if
+   this flag value is supported.  */
+
+extern "C" int
+EXPORT (SetFlag) (struct termios *t, Flag f, int b)
+{
+  switch (f)
+    {
+
+    case ignbrk:
+#if defined(IGNBRK)
+      return doSetUnset (&t->c_iflag, IGNBRK, b);
+#else
+      return 0;
+#endif
+    case ibrkint:
+#if defined(BRKINT)
+      return doSetUnset (&t->c_iflag, BRKINT, b);
+#else
+      return 0;
+#endif
+    case ignpar:
+#if defined(IGNPAR)
+      return doSetUnset (&t->c_iflag, IGNPAR, b);
+#else
+      return 0;
+#endif
+    case iparmrk:
+#if defined(PARMRK)
+      return doSetUnset (&t->c_iflag, PARMRK, b);
+#else
+      return 0;
+#endif
+    case inpck:
+#if defined(INPCK)
+      return doSetUnset (&t->c_iflag, INPCK, b);
+#else
+      return 0;
+#endif
+    case istrip:
+#if defined(ISTRIP)
+      return doSetUnset (&t->c_iflag, ISTRIP, b);
+#else
+      return 0;
+#endif
+    case inlcr:
+#if defined(INLCR)
+      return doSetUnset (&t->c_iflag, INLCR, b);
+#else
+      return 0;
+#endif
+    case igncr:
+#if defined(IGNCR)
+      return doSetUnset (&t->c_iflag, IGNCR, b);
+#else
+      return 0;
+#endif
+    case icrnl:
+#if defined(ICRNL)
+      return doSetUnset (&t->c_iflag, ICRNL, b);
+#else
+      return 0;
+#endif
+    case iuclc:
+#if defined(IUCLC)
+      return doSetUnset (&t->c_iflag, IUCLC, b);
+#else
+      return 0;
+#endif
+    case ixon:
+#if defined(IXON)
+      return doSetUnset (&t->c_iflag, IXON, b);
+#else
+      return 0;
+#endif
+    case ixany:
+#if defined(IXANY)
+      return doSetUnset (&t->c_iflag, IXANY, b);
+#else
+      return 0;
+#endif
+    case ixoff:
+#if defined(IXOFF)
+      return doSetUnset (&t->c_iflag, IXOFF, b);
+#else
+      return 0;
+#endif
+    case imaxbel:
+#if defined(IMAXBEL)
+      return doSetUnset (&t->c_iflag, IMAXBEL, b);
+#else
+      return 0;
+#endif
+    case opost:
+#if defined(OPOST)
+      return doSetUnset (&t->c_oflag, OPOST, b);
+#else
+      return 0;
+#endif
+    case olcuc:
+#if defined(OLCUC)
+      return doSetUnset (&t->c_oflag, OLCUC, b);
+#else
+      return 0;
+#endif
+    case onlcr:
+#if defined(ONLCR)
+      return doSetUnset (&t->c_oflag, ONLCR, b);
+#else
+      return 0;
+#endif
+    case ocrnl:
+#if defined(OCRNL)
+      return doSetUnset (&t->c_oflag, OCRNL, b);
+#else
+      return 0;
+#endif
+    case onocr:
+#if defined(ONOCR)
+      return doSetUnset (&t->c_oflag, ONOCR, b);
+#else
+      return 0;
+#endif
+    case onlret:
+#if defined(ONLRET)
+      return doSetUnset (&t->c_oflag, ONLRET, b);
+#else
+      return 0;
+#endif
+    case ofill:
+#if defined(OFILL)
+      return doSetUnset (&t->c_oflag, OFILL, b);
+#else
+      return 0;
+#endif
+    case ofdel:
+#if defined(OFDEL)
+      return doSetUnset (&t->c_oflag, OFDEL, b);
+#else
+      return 0;
+#endif
+    case onl0:
+#if defined(NL0)
+      return doSetUnset (&t->c_oflag, NL0, b);
+#else
+      return 0;
+#endif
+    case onl1:
+#if defined(NL1)
+      return doSetUnset (&t->c_oflag, NL1, b);
+#else
+      return 0;
+#endif
+    case ocr0:
+#if defined(CR0)
+      return doSetUnset (&t->c_oflag, CR0, b);
+#else
+      return 0;
+#endif
+    case ocr1:
+#if defined(CR1)
+      return doSetUnset (&t->c_oflag, CR1, b);
+#else
+      return 0;
+#endif
+    case ocr2:
+#if defined(CR2)
+      return doSetUnset (&t->c_oflag, CR2, b);
+#else
+      return 0;
+#endif
+    case ocr3:
+#if defined(CR3)
+      return doSetUnset (&t->c_oflag, CR3, b);
+#else
+      return 0;
+#endif
+    case otab0:
+#if defined(TAB0)
+      return doSetUnset (&t->c_oflag, TAB0, b);
+#else
+      return 0;
+#endif
+    case otab1:
+#if defined(TAB1)
+      return doSetUnset (&t->c_oflag, TAB1, b);
+#else
+      return 0;
+#endif
+    case otab2:
+#if defined(TAB2)
+      return doSetUnset (&t->c_oflag, TAB2, b);
+#else
+      return 0;
+#endif
+    case otab3:
+#if defined(TAB3)
+      return doSetUnset (&t->c_oflag, TAB3, b);
+#else
+      return 0;
+#endif
+    case obs0:
+#if defined(BS0)
+      return doSetUnset (&t->c_oflag, BS0, b);
+#else
+      return 0;
+#endif
+    case obs1:
+#if defined(BS1)
+      return doSetUnset (&t->c_oflag, BS1, b);
+#else
+      return 0;
+#endif
+    case off0:
+#if defined(FF0)
+      return doSetUnset (&t->c_oflag, FF0, b);
+#else
+      return 0;
+#endif
+    case off1:
+#if defined(FF1)
+      return doSetUnset (&t->c_oflag, FF1, b);
+#else
+      return 0;
+#endif
+    case ovt0:
+#if defined(VT0)
+      return doSetUnset (&t->c_oflag, VT0, b);
+#else
+      return 0;
+#endif
+    case ovt1:
+#if defined(VT1)
+      return doSetUnset (&t->c_oflag, VT1, b);
+#else
+      return 0;
+#endif
+    case b0:
+#if defined(B0)
+      return doSetUnset (&t->c_cflag, B0, b);
+#else
+      return 0;
+#endif
+    case b50:
+#if defined(B50)
+      return doSetUnset (&t->c_cflag, B50, b);
+#else
+      return 0;
+#endif
+    case b75:
+#if defined(B75)
+      return doSetUnset (&t->c_cflag, B75, b);
+#else
+      return 0;
+#endif
+    case b110:
+#if defined(B110)
+      return doSetUnset (&t->c_cflag, B110, b);
+#else
+      return 0;
+#endif
+    case b135:
+#if defined(B134)
+      return doSetUnset (&t->c_cflag, B134, b);
+#else
+      return 0;
+#endif
+    case b150:
+#if defined(B150)
+      return doSetUnset (&t->c_cflag, B150, b);
+#else
+      return 0;
+#endif
+    case b200:
+#if defined(B200)
+      return doSetUnset (&t->c_cflag, B200, b);
+#else
+      return 0;
+#endif
+    case b300:
+#if defined(B300)
+      return doSetUnset (&t->c_cflag, B300, b);
+#else
+      return 0;
+#endif
+    case b600:
+#if defined(B600)
+      return doSetUnset (&t->c_cflag, B600, b);
+#else
+      return 0;
+#endif
+    case b1200:
+#if defined(B1200)
+      return doSetUnset (&t->c_cflag, B1200, b);
+#else
+      return 0;
+#endif
+    case b1800:
+#if defined(B1800)
+      return doSetUnset (&t->c_cflag, B1800, b);
+#else
+      return 0;
+#endif
+    case b2400:
+#if defined(B2400)
+      return doSetUnset (&t->c_cflag, B2400, b);
+#else
+      return 0;
+#endif
+    case b4800:
+#if defined(B4800)
+      return doSetUnset (&t->c_cflag, B4800, b);
+#else
+      return 0;
+#endif
+    case b9600:
+#if defined(B9600)
+      return doSetUnset (&t->c_cflag, B9600, b);
+#else
+      return 0;
+#endif
+    case b19200:
+#if defined(B19200)
+      return doSetUnset (&t->c_cflag, B19200, b);
+#else
+      return 0;
+#endif
+    case b38400:
+#if defined(B38400)
+      return doSetUnset (&t->c_cflag, B38400, b);
+#else
+      return 0;
+#endif
+    case b57600:
+#if defined(B57600)
+      return doSetUnset (&t->c_cflag, B57600, b);
+#else
+      return 0;
+#endif
+    case b115200:
+#if defined(B115200)
+      return doSetUnset (&t->c_cflag, B115200, b);
+#else
+      return 0;
+#endif
+    case b240400:
+#if defined(B230400)
+      return doSetUnset (&t->c_cflag, B230400, b);
+#else
+      return 0;
+#endif
+    case b460800:
+#if defined(B460800)
+      return doSetUnset (&t->c_cflag, B460800, b);
+#else
+      return 0;
+#endif
+    case b500000:
+#if defined(B500000)
+      return doSetUnset (&t->c_cflag, B500000, b);
+#else
+      return 0;
+#endif
+    case b576000:
+#if defined(B576000)
+      return doSetUnset (&t->c_cflag, B576000, b);
+#else
+      return 0;
+#endif
+    case b921600:
+#if defined(B921600)
+      return doSetUnset (&t->c_cflag, B921600, b);
+#else
+      return 0;
+#endif
+    case b1000000:
+#if defined(B1000000)
+      return doSetUnset (&t->c_cflag, B1000000, b);
+#else
+      return 0;
+#endif
+    case b1152000:
+#if defined(B1152000)
+      return doSetUnset (&t->c_cflag, B1152000, b);
+#else
+      return 0;
+#endif
+    case b1500000:
+#if defined(B1500000)
+      return doSetUnset (&t->c_cflag, B1500000, b);
+#else
+      return 0;
+#endif
+    case b2000000:
+#if defined(B2000000)
+      return doSetUnset (&t->c_cflag, B2000000, b);
+#else
+      return 0;
+#endif
+    case b2500000:
+#if defined(B2500000)
+      return doSetUnset (&t->c_cflag, B2500000, b);
+#else
+      return 0;
+#endif
+    case b3000000:
+#if defined(B3000000)
+      return doSetUnset (&t->c_cflag, B3000000, b);
+#else
+      return 0;
+#endif
+    case b3500000:
+#if defined(B3500000)
+      return doSetUnset (&t->c_cflag, B3500000, b);
+#else
+      return 0;
+#endif
+    case b4000000:
+#if defined(B4000000)
+      return doSetUnset (&t->c_cflag, B4000000, b);
+#else
+      return 0;
+#endif
+    case maxbaud:
+#if defined(__MAX_BAUD)
+      return doSetUnset (&t->c_cflag, __MAX_BAUD, b);
+#else
+      return 0;
+#endif
+    case crtscts:
+#if defined(CRTSCTS)
+      return doSetUnset (&t->c_cflag, CRTSCTS, b);
+#else
+      return 0;
+#endif
+    case cs5:
+#if defined(CS5)
+      return doSetUnset (&t->c_cflag, CS5, b);
+#else
+      return 0;
+#endif
+    case cs6:
+#if defined(CS6)
+      return doSetUnset (&t->c_cflag, CS6, b);
+#else
+      return 0;
+#endif
+    case cs7:
+#if defined(CS7)
+      return doSetUnset (&t->c_cflag, CS7, b);
+#else
+      return 0;
+#endif
+    case cs8:
+#if defined(CS8)
+      return doSetUnset (&t->c_cflag, CS8, b);
+#else
+      return 0;
+#endif
+    case cstopb:
+#if defined(CSTOPB)
+      return doSetUnset (&t->c_cflag, CSTOPB, b);
+#else
+      return 0;
+#endif
+    case cread:
+#if defined(CREAD)
+      return doSetUnset (&t->c_cflag, CREAD, b);
+#else
+      return 0;
+#endif
+    case parenb:
+#if defined(PARENB)
+      return doSetUnset (&t->c_cflag, PARENB, b);
+#else
+      return 0;
+#endif
+    case parodd:
+#if defined(PARODD)
+      return doSetUnset (&t->c_cflag, PARODD, b);
+#else
+      return 0;
+#endif
+    case hupcl:
+#if defined(HUPCL)
+      return doSetUnset (&t->c_cflag, HUPCL, b);
+#else
+      return 0;
+#endif
+    case clocal:
+#if defined(CLOCAL)
+      return doSetUnset (&t->c_cflag, CLOCAL, b);
+#else
+      return 0;
+#endif
+    case lisig:
+#if defined(ISIG)
+      return doSetUnset (&t->c_lflag, ISIG, b);
+#else
+      return 0;
+#endif
+    case licanon:
+#if defined(ICANON)
+      return doSetUnset (&t->c_lflag, ICANON, b);
+#else
+      return 0;
+#endif
+    case lxcase:
+#if defined(XCASE)
+      return doSetUnset (&t->c_lflag, XCASE, b);
+#else
+      return 0;
+#endif
+    case lecho:
+#if defined(ECHO)
+      return doSetUnset (&t->c_lflag, ECHO, b);
+#else
+      return 0;
+#endif
+    case lechoe:
+#if defined(ECHOE)
+      return doSetUnset (&t->c_lflag, ECHOE, b);
+#else
+      return 0;
+#endif
+    case lechok:
+#if defined(ECHOK)
+      return doSetUnset (&t->c_lflag, ECHOK, b);
+#else
+      return 0;
+#endif
+    case lechonl:
+#if defined(ECHONL)
+      return doSetUnset (&t->c_lflag, ECHONL, b);
+#else
+      return 0;
+#endif
+    case lnoflsh:
+#if defined(NOFLSH)
+      return doSetUnset (&t->c_lflag, NOFLSH, b);
+#else
+      return 0;
+#endif
+    case ltopstop:
+#if defined(TOSTOP)
+      return doSetUnset (&t->c_lflag, TOSTOP, b);
+#else
+      return 0;
+#endif
+    case lechoctl:
+#if defined(ECHOCTL)
+      return doSetUnset (&t->c_lflag, ECHOCTL, b);
+#else
+      return 0;
+#endif
+    case lechoprt:
+#if defined(ECHOPRT)
+      return doSetUnset (&t->c_lflag, ECHOPRT, b);
+#else
+      return 0;
+#endif
+    case lechoke:
+#if defined(ECHOKE)
+      return doSetUnset (&t->c_lflag, ECHOKE, b);
+#else
+      return 0;
+#endif
+    case lflusho:
+#if defined(FLUSHO)
+      return doSetUnset (&t->c_lflag, FLUSHO, b);
+#else
+      return 0;
+#endif
+    case lpendin:
+#if defined(PENDIN)
+      return doSetUnset (&t->c_lflag, PENDIN, b);
+#else
+      return 0;
+#endif
+    case liexten:
+#if defined(IEXTEN)
+      return doSetUnset (&t->c_lflag, IEXTEN, b);
+#else
+      return 0;
+#endif
+    }
+  return 0;
+}
+
+/* GetChar sets a CHAR, ch, value from, t, and returns TRUE if
+   this value is supported.  */
+
+extern "C" int
+EXPORT (GetChar) (struct termios *t, ControlChar c, char *ch)
+{
+  switch (c)
+    {
+
+    case vintr:
+#if defined(VINTR)
+      *ch = t->c_cc[VINTR];
+      return 1;
+#else
+      return 0;
+#endif
+    case vquit:
+#if defined(VQUIT)
+      *ch = t->c_cc[VQUIT];
+      return 1;
+#else
+      return 0;
+#endif
+    case verase:
+#if defined(VERASE)
+      *ch = t->c_cc[VERASE];
+      return 1;
+#else
+      return 0;
+#endif
+    case vkill:
+#if defined(VKILL)
+      *ch = t->c_cc[VKILL];
+      return 1;
+#else
+      return 0;
+#endif
+    case veof:
+#if defined(VEOF)
+      *ch = t->c_cc[VEOF];
+      return 1;
+#else
+      return 0;
+#endif
+    case vtime:
+#if defined(VTIME)
+      *ch = t->c_cc[VTIME];
+      return 1;
+#else
+      return 0;
+#endif
+    case vmin:
+#if defined(VMIN)
+      *ch = t->c_cc[VMIN];
+      return 1;
+#else
+      return 0;
+#endif
+    case vswtc:
+#if defined(VSWTC)
+      *ch = t->c_cc[VSWTC];
+      return 1;
+#else
+      return 0;
+#endif
+    case vstart:
+#if defined(VSTART)
+      *ch = t->c_cc[VSTART];
+      return 1;
+#else
+      return 0;
+#endif
+    case vstop:
+#if defined(VSTOP)
+      *ch = t->c_cc[VSTOP];
+      return 1;
+#else
+      return 0;
+#endif
+    case vsusp:
+#if defined(VSUSP)
+      *ch = t->c_cc[VSUSP];
+      return 1;
+#else
+      return 0;
+#endif
+    case veol:
+#if defined(VEOL)
+      *ch = t->c_cc[VEOL];
+      return 1;
+#else
+      return 0;
+#endif
+    case vreprint:
+#if defined(VREPRINT)
+      *ch = t->c_cc[VREPRINT];
+      return 1;
+#else
+      return 0;
+#endif
+    case vdiscard:
+#if defined(VDISCARD)
+      *ch = t->c_cc[VDISCARD];
+      return 1;
+#else
+      return 0;
+#endif
+    case vwerase:
+#if defined(VWERASE)
+      *ch = t->c_cc[VWERASE];
+      return 1;
+#else
+      return 0;
+#endif
+    case vlnext:
+#if defined(VLNEXT)
+      *ch = t->c_cc[VLNEXT];
+      return 1;
+#else
+      return 0;
+#endif
+    case veol2:
+#if defined(VEOL2)
+      *ch = t->c_cc[VEOL2];
+      return 1;
+#else
+      return 0;
+#endif
+    default:
+      return 0;
+    }
+}
+
+/* SetChar sets a CHAR value in, t, and returns TRUE if, c,
+   is supported.  */
+
+extern "C" int
+EXPORT (SetChar) (struct termios *t, ControlChar c, char ch)
+{
+  switch (c)
+    {
+
+    case vintr:
+#if defined(VINTR)
+      t->c_cc[VINTR] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vquit:
+#if defined(VQUIT)
+      t->c_cc[VQUIT] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case verase:
+#if defined(VERASE)
+      t->c_cc[VERASE] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vkill:
+#if defined(VKILL)
+      t->c_cc[VKILL] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case veof:
+#if defined(VEOF)
+      t->c_cc[VEOF] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vtime:
+#if defined(VTIME)
+      t->c_cc[VTIME] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vmin:
+#if defined(VMIN)
+      t->c_cc[VMIN] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vswtc:
+#if defined(VSWTC)
+      t->c_cc[VSWTC] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vstart:
+#if defined(VSTART)
+      t->c_cc[VSTART] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vstop:
+#if defined(VSTOP)
+      t->c_cc[VSTOP] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vsusp:
+#if defined(VSUSP)
+      t->c_cc[VSUSP] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case veol:
+#if defined(VEOL)
+      t->c_cc[VEOL] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vreprint:
+#if defined(VREPRINT)
+      t->c_cc[VREPRINT] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vdiscard:
+#if defined(VDISCARD)
+      t->c_cc[VDISCARD] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vwerase:
+#if defined(VWERASE)
+      t->c_cc[VWERASE] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case vlnext:
+#if defined(VLNEXT)
+      t->c_cc[VLNEXT] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    case veol2:
+#if defined(VEOL2)
+      t->c_cc[VEOL2] = ch;
+      return 1;
+#else
+      return 0;
+#endif
+    default:
+      return 0;
+    }
+}
+#endif
+
+extern "C" void
+_M2_termios_init (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_termios_fini (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_termios_dep (void)
+{
+}
+
+struct _M2_termios_ctor { _M2_termios_ctor (); } _M2_termios_ctor;
+
+_M2_termios_ctor::_M2_termios_ctor (void)
+{
+  M2RTS_RegisterModule ("termios", _M2_termios_init, _M2_termios_fini,
+			_M2_termios_dep);
+}
diff -ruw /dev/null gcc-git-devel-modula2/libgm2/libm2pim/sckt.cc
--- /dev/null	2022-08-24 16:22:16.888000070 +0100
+++ gcc-git-devel-modula2/libgm2/libm2pim/sckt.cc	2022-12-06 02:56:51.432775922 +0000
@@ -0,0 +1,430 @@
+/* sckt.c provide access to the socket layer.
+
+Copyright (C) 2005-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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 <m2rts.h>
+
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_SYS_SOCKET_H)
+#include <sys/socket.h>
+#endif
+
+#if defined(HAVE_NETINET_IN_H)
+#include <netinet/in.h>
+#endif
+
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#endif
+
+#if defined(HAVE_SYS_ERRNO_H)
+#include <sys/errno.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+#include <errno.h>
+#endif
+
+#if defined(HAVE_MALLOC_H)
+#include <malloc.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+#include <string.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+#include <stdio.h>
+#endif
+
+#define PORTSTART 7000
+#define NOOFTRIES 100
+#define MAXHOSTNAME 256
+
+#undef DEBUGGING
+
+#if !defined(TRUE)
+#define TRUE (1 == 1)
+#endif
+#if !defined(FALSE)
+#define FALSE (1 == 0)
+#endif
+
+#if defined(HAVE_SYS_SOCKET_H)
+
+#define ERROR(X)                                                              \
+  {                                                                           \
+    printf ("%s:%d:%s\n", __FILE__, __LINE__, X);                             \
+    localExit (1);                                                            \
+  }
+
+#define ASSERT(X)                                                             \
+  {                                                                           \
+    if (!(X))                                                                 \
+      {                                                                       \
+        printf ("%s:%d: assert(%s) failed\n", __FILE__, __LINE__, #X);        \
+        exit (1);                                                             \
+      }                                                                       \
+  }
+
+typedef struct
+{
+  char hostname[MAXHOSTNAME];
+  struct hostent *hp;
+  struct sockaddr_in sa, isa;
+  int sockFd;
+  int portNo;
+} tcpServerState;
+
+int
+localExit (int i)
+{
+  exit (1);
+}
+
+/* tcpServerEstablishPort returns a tcpState containing the relevant
+   information about a socket declared to receive tcp connections.
+   This method attempts to use the port specified by the parameter.  */
+
+extern "C" tcpServerState *
+tcpServerEstablishPort (int portNo)
+{
+  tcpServerState *s = (tcpServerState *)malloc (sizeof (tcpServerState));
+  int b, p, n;
+
+  if (s == NULL)
+    ERROR ("no more memory");
+
+  /* Remove SIGPIPE which is raised on the server if the client is killed.  */
+  signal (SIGPIPE, SIG_IGN);
+
+  if (gethostname (s->hostname, MAXHOSTNAME) < 0)
+    ERROR ("cannot find our hostname");
+
+  s->hp = gethostbyname (s->hostname);
+  if (s->hp == NULL)
+    ERROR ("cannot get host name");
+
+  p = -1;
+  n = 0;
+  do
+    {
+      p++;
+       /* Open a TCP socket (an Internet stream socket).  */
+
+      s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
+      if (s->sockFd < 0)
+        ERROR ("socket");
+
+      memset ((void *)&s->sa, 0, sizeof (s->sa));
+      ASSERT ((s->hp->h_addrtype == AF_INET));
+      s->sa.sin_family = s->hp->h_addrtype;
+      s->sa.sin_addr.s_addr = htonl (INADDR_ANY);
+      s->sa.sin_port = htons (portNo + p);
+
+      b = bind (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa));
+    }
+  while ((b < 0) && (n < NOOFTRIES));
+
+  if (b < 0)
+    ERROR ("bind");
+
+  s->portNo = portNo + p;
+#if defined(DEBUGGING)
+  printf ("the receiving host is: %s, the port is %d\n", s->hostname,
+          s->portNo);
+#endif
+  listen (s->sockFd, 1);
+  return s;
+}
+
+/* tcpServerEstablish returns a tcpServerState containing the relevant
+   information about a socket declared to receive tcp connections.  */
+
+extern "C" tcpServerState *
+tcpServerEstablish (void)
+{
+  return tcpServerEstablishPort (PORTSTART);
+}
+
+/* tcpServerAccept returns a file descriptor once a client has connected and
+   been accepted.  */
+
+extern "C" int
+tcpServerAccept (tcpServerState *s)
+{
+  socklen_t i = sizeof (s->isa);
+  int t;
+
+#if defined(DEBUGGING)
+  printf ("before accept %d\n", s->sockFd);
+#endif
+  t = accept (s->sockFd, (struct sockaddr *)&s->isa, &i);
+  return t;
+}
+
+/* tcpServerPortNo returns the portNo from structure, s.  */
+
+extern "C" int
+tcpServerPortNo (tcpServerState *s)
+{
+  return s->portNo;
+}
+
+/* tcpServerSocketFd returns the sockFd from structure, s.  */
+
+extern "C" int
+tcpServerSocketFd (tcpServerState *s)
+{
+  return s->sockFd;
+}
+
+/* getLocalIP returns the IP address of this machine.  */
+
+extern "C" unsigned int
+getLocalIP (tcpServerState *s)
+{
+  char hostname[1024];
+  struct hostent *hp;
+  struct sockaddr_in sa;
+  unsigned int ip;
+  int ret = gethostname (hostname, sizeof (hostname));
+
+  if (ret == -1)
+    {
+      ERROR ("gethostname");
+      return 0;
+    }
+
+  hp = gethostbyname (hostname);
+  if (hp == NULL)
+    {
+      ERROR ("gethostbyname");
+      return 0;
+    }
+
+  if (sizeof (unsigned int) != sizeof (in_addr_t))
+    {
+      ERROR ("bad ip length");
+      return 0;
+    }
+
+  memset (&sa, sizeof (struct sockaddr_in), 0);
+  sa.sin_family = AF_INET;
+  sa.sin_port = htons (80);
+  if (hp->h_length == sizeof (unsigned int))
+    {
+      memcpy (&ip, hp->h_addr_list[0], hp->h_length);
+      return ip;
+    }
+
+  return 0;
+}
+
+/* tcpServerIP returns the IP address from structure s.  */
+
+extern "C" int
+tcpServerIP (tcpServerState *s)
+{
+  return *((int *)s->hp->h_addr_list[0]);
+}
+
+/* tcpServerClientIP returns the IP address of the client who
+   has connected to server s.  */
+
+extern "C" unsigned int
+tcpServerClientIP (tcpServerState *s)
+{
+  unsigned int ip;
+
+  ASSERT (s->isa.sin_family == AF_INET);
+  ASSERT (sizeof (ip) == 4);
+  memcpy (&ip, &s->isa.sin_addr, sizeof (ip));
+  return ip;
+}
+
+/* tcpServerClientPortNo returns the port number of the client who
+   has connected to server s.  */
+
+extern "C" unsigned int
+tcpServerClientPortNo (tcpServerState *s)
+{
+  return s->isa.sin_port;
+}
+
+/*
+****************************************************************
+***             C L I E N T     R O U T I N E S
+****************************************************************
+ */
+
+typedef struct
+{
+  char hostname[MAXHOSTNAME];
+  struct hostent *hp;
+  struct sockaddr_in sa;
+  int sockFd;
+  int portNo;
+} tcpClientState;
+
+/* tcpClientSocket returns a file descriptor (socket) which has
+   connected to, serverName:portNo.  */
+
+extern "C" tcpClientState *
+tcpClientSocket (char *serverName, int portNo)
+{
+  tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
+
+  if (s == NULL)
+    ERROR ("no more memory");
+
+  /* Remove SIGPIPE which is raised on the server if the client is killed.  */
+  signal (SIGPIPE, SIG_IGN);
+
+  s->hp = gethostbyname (serverName);
+  if (s->hp == NULL)
+    {
+      fprintf (stderr, "cannot find host: %s\n", serverName);
+      exit (1);
+    }
+
+  memset ((void *)&s->sa, 0, sizeof (s->sa));
+  s->sa.sin_family = AF_INET;
+  memcpy ((void *)&s->sa.sin_addr, (void *)s->hp->h_addr, s->hp->h_length);
+  s->portNo = portNo;
+  s->sa.sin_port = htons (portNo);
+
+  /* Open a TCP socket (an Internet stream socket).  */
+
+  s->sockFd = socket (s->hp->h_addrtype, SOCK_STREAM, 0);
+  return s;
+}
+
+/* tcpClientSocketIP returns a file descriptor (socket) which has
+   connected to, ip:portNo.  */
+
+extern "C" tcpClientState *
+tcpClientSocketIP (unsigned int ip, int portNo)
+{
+  tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
+
+  if (s == NULL)
+    ERROR ("no more memory");
+
+  /* Remove SIGPIPE which is raised on the server if the client is killed.  */
+  signal (SIGPIPE, SIG_IGN);
+
+  memset ((void *)&s->sa, 0, sizeof (s->sa));
+  s->sa.sin_family = AF_INET;
+  memcpy ((void *)&s->sa.sin_addr, (void *)&ip, sizeof (ip));
+  s->portNo = portNo;
+  s->sa.sin_port = htons (portNo);
+
+  /* Open a TCP socket (an Internet stream socket).  */
+
+  s->sockFd = socket (PF_INET, SOCK_STREAM, 0);
+  return s;
+}
+
+/* tcpClientConnect returns the file descriptor associated with s,
+   once a connect has been performed.  */
+
+extern "C" int
+tcpClientConnect (tcpClientState *s)
+{
+  if (connect (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa)) < 0)
+    ERROR ("failed to connect to the TCP server");
+
+  return s->sockFd;
+}
+
+/* tcpClientPortNo returns the portNo from structure s.  */
+
+extern "C" int
+tcpClientPortNo (tcpClientState *s)
+{
+  return s->portNo;
+}
+
+/* tcpClientSocketFd returns the sockFd from structure s.  */
+
+extern "C" int
+tcpClientSocketFd (tcpClientState *s)
+{
+  return s->sockFd;
+}
+
+/* tcpClientIP returns the sockFd from structure s.  */
+
+extern "C" int
+tcpClientIP (tcpClientState *s)
+{
+#if defined(DEBUGGING)
+  printf ("client ip = %s\n", inet_ntoa (s->sa.sin_addr.s_addr));
+#endif
+  return s->sa.sin_addr.s_addr;
+}
+#endif
+
+/* GNU Modula-2 link fodder.  */
+
+extern "C" void
+_M2_sckt_init (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_sckt_finish (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_sckt_dep (void)
+{
+}
+
+struct _M2_sckt_ctor { _M2_sckt_ctor (); } _M2_sckt_ctor;
+
+_M2_sckt_ctor::_M2_sckt_ctor (void)
+{
+  M2RTS_RegisterModule ("sckt", _M2_sckt_init, _M2_sckt_finish,
+			_M2_sckt_dep);
+}
