Okay, I've split my changes into a set of patches, attached. These
patches are orthogonal and may be applied in any order:

gnulib-zos-ascii.patch: When in a non-ASCII environment, disable tests
that assume ASCII.

gnulib-zos-charset.patch: Added appropriately conditional #pragmas so
that the test strings in test-iconv-utf.c are correctly interpreted in
ASCII instead of EBCDIC (i.e. 'J' == 0x4A and not 0xD1). This issue
could be addressed in a more portable way by simply rewriting all the
ASCII literal characters as octal escapes, but then you would lose the
partial readability that the strings have now. Also, iconv_open() on
z/OS does not recognize "ISO-8859-1", but "ISO8859-1" works.

gnulib-zos-configure.patch: Changes to the Autoconf M4 code to support
z/OS. Note that fclose() is broken in a different way on z/OS than it is
on other systems, thus the special-case in fclose.m4.

gnulib-zos-cpp.patch: General preprocessor-level changes to
support z/OS.

gnulib-zos-errno.patch: Accommodate z/OS errno code preferences. (I
believe this should still be within spec; IBM is good at following the
letter if not the spirit of such things.)

gnulib-zos-pthread.patch: Rudimentary gl_thread support for z/OS.

gnulib-zos-regex-argname.patch: "__string" is not a good name to use as
an identifier on this system. A better fix would be to use a different
name (why not just "s"?), provided this can be pushed to upstream glibc.

gnulib-zos-strtod.patch: Address a couple quirks in the z/OS
implementation of strtod().


--Daniel


-- 
Daniel Richard G. || sk...@iskunk.org
My ASCII-art .sig got a bad case of Times New Roman.
diff --git a/tests/test-c-strcasecmp.c b/tests/test-c-strcasecmp.c
index f7f6b43..47feac8 100644
--- a/tests/test-c-strcasecmp.c
+++ b/tests/test-c-strcasecmp.c
@@ -19,6 +19,7 @@
 #include <config.h>
 
 #include "c-strcase.h"
+#include "c-ctype.h"
 
 #include <locale.h>
 #include <string.h>
@@ -57,9 +58,11 @@ main (int argc, char *argv[])
   ASSERT (c_strcasecmp ("\303\266zg\303\274r", "\303\226ZG\303\234R") > 0); /* özgür */
   ASSERT (c_strcasecmp ("\303\226ZG\303\234R", "\303\266zg\303\274r") < 0); /* özgür */
 
+#if C_CTYPE_ASCII
   /* This test shows how strings of different size cannot compare equal.  */
   ASSERT (c_strcasecmp ("turkish", "TURK\304\260SH") < 0);
   ASSERT (c_strcasecmp ("TURK\304\260SH", "turkish") > 0);
+#endif
 
   return 0;
 }
diff --git a/tests/test-wcwidth.c b/tests/test-wcwidth.c
index 9fad785..fdbecc3 100644
--- a/tests/test-wcwidth.c
+++ b/tests/test-wcwidth.c
@@ -26,6 +26,7 @@ SIGNATURE_CHECK (wcwidth, int, (wchar_t));
 #include <locale.h>
 #include <string.h>
 
+#include "c-ctype.h"
 #include "localcharset.h"
 #include "macros.h"
 
@@ -34,9 +35,11 @@ main ()
 {
   wchar_t wc;
 
+#ifdef C_CTYPE_ASCII
   /* Test width of ASCII characters.  */
   for (wc = 0x20; wc < 0x7F; wc++)
     ASSERT (wcwidth (wc) == 1);
+#endif
 
   /* Switch to an UTF-8 locale.  */
   if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL

diff --git a/tests/test-iconv-utf.c b/tests/test-iconv-utf.c
index c1589f6..a769bee 100644
--- a/tests/test-iconv-utf.c
+++ b/tests/test-iconv-utf.c
@@ -27,20 +27,38 @@
 
 #include "macros.h"
 
+/* If compiling on an EBCDIC system, keep the test strings in ASCII.  */
+#if defined __IBMC__ && 'A' != 0x41
+# pragma convert("ISO8859-1")
+# define CONVERT_ENABLED
+#endif
+
+/* The text is "Japanese (日本語) [\U0001D50D\U0001D51E\U0001D52D]".  */
+
+const char test_utf8_string[] = "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
+
+const char test_utf16be_string[] = "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
+
+const char test_utf16le_string[] = "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
+
+const char test_utf32be_string[] = "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
+
+const char test_utf32le_string[] = "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
+
+#ifdef CONVERT_ENABLED
+# pragma convert(pop)
+#endif
+
 int
 main ()
 {
 #if HAVE_ICONV
   /* Assume that iconv() supports at least the encoding UTF-8.  */
 
-  /* The text is "Japanese (日本語) [\U0001D50D\U0001D51E\U0001D52D]".  */
-
   /* Test conversion from UTF-8 to UTF-16BE with no errors.  */
   {
-    static const char input[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
-    static const char expected[] =
-      "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
+#define input    test_utf8_string
+#define expected test_utf16be_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -64,14 +82,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-8 to UTF-16LE with no errors.  */
   {
-    static const char input[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
-    static const char expected[] =
-      "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
+#define input    test_utf8_string
+#define expected test_utf16le_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -95,14 +114,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-8 to UTF-32BE with no errors.  */
   {
-    static const char input[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
-    static const char expected[] =
-      "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
+#define input    test_utf8_string
+#define expected test_utf32be_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -126,14 +146,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-8 to UTF-32LE with no errors.  */
   {
-    static const char input[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
-    static const char expected[] =
-      "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
+#define input    test_utf8_string
+#define expected test_utf32le_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -157,14 +178,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-16BE to UTF-8 with no errors.  */
   {
-    static const char input[] =
-      "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
-    static const char expected[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
+#define input    test_utf16be_string
+#define expected test_utf8_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -188,14 +210,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-16LE to UTF-8 with no errors.  */
   {
-    static const char input[] =
-      "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
-    static const char expected[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
+#define input    test_utf16le_string
+#define expected test_utf8_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -219,14 +242,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-32BE to UTF-8 with no errors.  */
   {
-    static const char input[] =
-      "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
-    static const char expected[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
+#define input    test_utf32be_string
+#define expected test_utf8_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -250,14 +274,15 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 
   /* Test conversion from UTF-32LE to UTF-8 with no errors.  */
   {
-    static const char input[] =
-      "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
-    static const char expected[] =
-      "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
+#define input    test_utf32le_string
+#define expected test_utf8_string
     iconv_t cd;
     char buf[100];
     const char *inptr;
@@ -281,6 +306,9 @@ main ()
     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
 
     ASSERT (iconv_close (cd) == 0);
+
+#undef input
+#undef expected
   }
 #endif
 
diff --git a/tests/test-iconv.c b/tests/test-iconv.c
index ed715bd..a64c6dd 100644
--- a/tests/test-iconv.c
+++ b/tests/test-iconv.c
@@ -44,8 +44,14 @@ main ()
 #if HAVE_ICONV
   /* Assume that iconv() supports at least the encodings ASCII, ISO-8859-1,
      and UTF-8.  */
-  iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
-  iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8");
+  iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO8859-1");
+  iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+
+#if defined __MVS__ && defined __IBMC__
+  /* String literals below are in ASCII, not EBCDIC.  */
+# pragma convert("ISO8859-1")
+# define CONVERT_ENABLED
+#endif
 
   ASSERT (cd_88591_to_utf8 != (iconv_t)(-1));
   ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
@@ -142,7 +148,12 @@ main ()
 
   iconv_close (cd_88591_to_utf8);
   iconv_close (cd_utf8_to_88591);
+
+#ifdef CONVERT_ENABLED
+# pragma convert(pop)
 #endif
 
+#endif /* HAVE_ICONV */
+
   return 0;
 }

diff --git a/m4/fclose.m4 b/m4/fclose.m4
index 6bd1ad8..e939d30 100644
--- a/m4/fclose.m4
+++ b/m4/fclose.m4
@@ -1,4 +1,4 @@
-# fclose.m4 serial 6
+# fclose.m4 serial 7
 dnl Copyright (C) 2008-2015 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -7,6 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
 AC_DEFUN([gl_FUNC_FCLOSE],
 [
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
 
   gl_FUNC_FFLUSH_STDIN
   if test $gl_cv_func_fflush_stdin != yes; then
@@ -17,4 +18,8 @@ AC_DEFUN([gl_FUNC_FCLOSE],
   if test $REPLACE_CLOSE = 1; then
     REPLACE_FCLOSE=1
   fi
+
+  case "$host_os" in
+    openedition) REPLACE_FCLOSE=1 ;;
+  esac
 ])
diff --git a/m4/strstr.m4 b/m4/strstr.m4
index 040c0b9..e3e528d 100644
--- a/m4/strstr.m4
+++ b/m4/strstr.m4
@@ -1,4 +1,4 @@
-# strstr.m4 serial 16
+# strstr.m4 serial 17
 dnl Copyright (C) 2008-2015 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -67,6 +67,12 @@ AC_DEFUN([gl_FUNC_STRSTR],
     AC_CACHE_CHECK([whether strstr works in linear time],
       [gl_cv_func_strstr_linear],
       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#ifdef __MVS__
+/* z/OS does not deliver signals while strstr() is running (thanks to
+   restrictions on its LE runtime), which prevents us from limiting the
+   running time of this test.  */
+# error "This test does not work properly on z/OS"
+#endif
 #include <signal.h> /* for signal */
 #include <string.h> /* for strstr */
 #include <stdlib.h> /* for malloc */
diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4
index 9d1b0f8..c926c4b 100644
--- a/m4/wchar_h.m4
+++ b/m4/wchar_h.m4
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
 
 dnl Written by Eric Blake.
 
-# wchar_h.m4 serial 39
+# wchar_h.m4 serial 40
 
 AC_DEFUN([gl_WCHAR_H],
 [
@@ -81,8 +81,14 @@ AC_DEFUN([gl_WCHAR_H_INLINE_OK],
 extern int zero (void);
 int main () { return zero(); }
 ]])])
+     dnl Do not rename the object file from conftest.$ac_objext to
+     dnl conftest1.$ac_objext, as this will cause the link to fail on
+     dnl z/OS when using the XPLINK object format (due to duplicate
+     dnl CSECT names). Instead, temporarily redefine $ac_compile so
+     dnl that the object file has the latter name from the start.
+     save_ac_compile="$ac_compile"
+     ac_compile=`echo "$save_ac_compile" | sed s/conftest/conftest1/`
      if AC_TRY_EVAL([ac_compile]); then
-       mv conftest.$ac_objext conftest1.$ac_objext
        AC_LANG_CONFTEST([
          AC_LANG_SOURCE([[#define wcstod renamed_wcstod
 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
@@ -95,8 +101,9 @@ int main () { return zero(); }
 #include <wchar.h>
 int zero (void) { return 0; }
 ]])])
+       dnl See note above about renaming object files.
+       ac_compile=`echo "$save_ac_compile" | sed s/conftest/conftest2/`
        if AC_TRY_EVAL([ac_compile]); then
-         mv conftest.$ac_objext conftest2.$ac_objext
          if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then
            :
          else
@@ -104,6 +111,7 @@ int zero (void) { return 0; }
          fi
        fi
      fi
+     ac_compile="$save_ac_compile"
      rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext
     ])
   if test $gl_cv_header_wchar_h_correct_inline = no; then

diff --git a/lib/alloca.in.h b/lib/alloca.in.h
index d5664b6..6606984 100644
--- a/lib/alloca.in.h
+++ b/lib/alloca.in.h
@@ -51,6 +51,8 @@ extern "C"
 void *_alloca (unsigned short);
 #  pragma intrinsic (_alloca)
 #  define alloca _alloca
+# elif defined __MVS__
+#  include <stdlib.h>
 # else
 #  include <stddef.h>
 #  ifdef  __cplusplus
diff --git a/lib/fnmatch.c b/lib/fnmatch.c
index a607672..58754fa 100644
--- a/lib/fnmatch.c
+++ b/lib/fnmatch.c
@@ -22,7 +22,7 @@
 # define _GNU_SOURCE    1
 #endif
 
-#if ! defined __builtin_expect && __GNUC__ < 3
+#if ! defined __builtin_expect && defined __GNUC__ && __GNUC__ < 3
 # define __builtin_expect(expr, expected) (expr)
 #endif
 
diff --git a/lib/get-rusage-as.c b/lib/get-rusage-as.c
index 2bad20a..4db1596 100644
--- a/lib/get-rusage-as.c
+++ b/lib/get-rusage-as.c
@@ -355,7 +355,7 @@ get_rusage_as_via_iterator (void)
 uintptr_t
 get_rusage_as (void)
 {
-#if (defined __APPLE__ && defined __MACH__) || defined _AIX || defined __CYGWIN__ /* Mac OS X, AIX, Cygwin */
+#if (defined __APPLE__ && defined __MACH__) || defined _AIX || defined __CYGWIN__ || defined __MVS__ /* Mac OS X, AIX, Cygwin, z/OS */
   /* get_rusage_as_via_setrlimit() does not work.
      Prefer get_rusage_as_via_iterator().  */
   return get_rusage_as_via_iterator ();
diff --git a/lib/glob.c b/lib/glob.c
index ed49a9d..9fd6482 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -144,7 +144,9 @@
 # define __stat64(fname, buf)   stat (fname, buf)
 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
 # define struct_stat64          struct stat
-# define __alloca               alloca
+# ifndef __MVS__
+#  define __alloca              alloca
+# endif
 # define __readdir              readdir
 # define __glob_pattern_p       glob_pattern_p
 #endif /* _LIBC */
diff --git a/lib/math.in.h b/lib/math.in.h
index 62a089a..59293fd 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -406,6 +406,7 @@ _GL_WARN_ON_USE (ceilf, "ceilf is unportable - "
 #if @GNULIB_CEIL@
 # if @REPLACE_CEIL@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef ceil
 #   define ceil rpl_ceil
 #  endif
 _GL_FUNCDECL_RPL (ceil, double, (double x));
@@ -753,6 +754,7 @@ _GL_WARN_ON_USE (floorf, "floorf is unportable - "
 #if @GNULIB_FLOOR@
 # if @REPLACE_FLOOR@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef floor
 #   define floor rpl_floor
 #  endif
 _GL_FUNCDECL_RPL (floor, double, (double x));
@@ -973,6 +975,7 @@ _GL_WARN_ON_USE (frexpf, "frexpf is unportable - "
 #if @GNULIB_FREXP@
 # if @REPLACE_FREXP@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef frexp
 #   define frexp rpl_frexp
 #  endif
 _GL_FUNCDECL_RPL (frexp, double, (double x, int *expptr) _GL_ARG_NONNULL ((2)));
@@ -1958,6 +1961,7 @@ _GL_WARN_ON_USE (tanhf, "tanhf is unportable - "
 #if @GNULIB_TRUNCF@
 # if @REPLACE_TRUNCF@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef truncf
 #   define truncf rpl_truncf
 #  endif
 _GL_FUNCDECL_RPL (truncf, float, (float x));
@@ -1980,6 +1984,7 @@ _GL_WARN_ON_USE (truncf, "truncf is unportable - "
 #if @GNULIB_TRUNC@
 # if @REPLACE_TRUNC@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef trunc
 #   define trunc rpl_trunc
 #  endif
 _GL_FUNCDECL_RPL (trunc, double, (double x));
diff --git a/lib/ptsname_r.c b/lib/ptsname_r.c
index faa33fb..809388a 100644
--- a/lib/ptsname_r.c
+++ b/lib/ptsname_r.c
@@ -34,6 +34,11 @@
 #  define _PATH_DEV "/dev/"
 # endif
 
+# undef __set_errno
+# undef __stat
+# undef __ttyname_r
+# undef __ptsname_r
+
 # define __set_errno(e) errno = (e)
 # define __isatty isatty
 # define __stat stat
diff --git a/tests/infinity.h b/tests/infinity.h
index 45c30bd..4e8a755 100644
--- a/tests/infinity.h
+++ b/tests/infinity.h
@@ -17,8 +17,9 @@
 
 /* Infinityf () returns a 'float' +Infinity.  */
 
-/* The Microsoft MSVC 9 compiler chokes on the expression 1.0f / 0.0f.  */
-#if defined _MSC_VER
+/* The Microsoft MSVC 9 compiler chokes on the expression 1.0f / 0.0f.
+   The IBM XL C compiler on z/OS complains.  */
+#if defined _MSC_VER || (defined __MVS__ && defined __IBMC__)
 static float
 Infinityf ()
 {
@@ -32,8 +33,9 @@ Infinityf ()
 
 /* Infinityd () returns a 'double' +Infinity.  */
 
-/* The Microsoft MSVC 9 compiler chokes on the expression 1.0 / 0.0.  */
-#if defined _MSC_VER
+/* The Microsoft MSVC 9 compiler chokes on the expression 1.0 / 0.0.
+   The IBM XL C compiler on z/OS complains.  */
+#if defined _MSC_VER || (defined __MVS__ && defined __IBMC__)
 static double
 Infinityd ()
 {
@@ -47,9 +49,10 @@ Infinityd ()
 
 /* Infinityl () returns a 'long double' +Infinity.  */
 
-/* The Microsoft MSVC 9 compiler chokes on the expression 1.0L / 0.0L.  */
-#if defined _MSC_VER
-static double
+/* The Microsoft MSVC 9 compiler chokes on the expression 1.0L / 0.0L.
+   The IBM XL C compiler on z/OS complains.  */
+#if defined _MSC_VER || (defined __MVS__ && defined __IBMC__)
+static long double
 Infinityl ()
 {
   static long double zero = 0.0L;
diff --git a/tests/nan.h b/tests/nan.h
index 9f6819c..10b393e 100644
--- a/tests/nan.h
+++ b/tests/nan.h
@@ -15,11 +15,18 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
+/* IBM z/OS supports both hexadecimal and IEEE floating-point formats. The
+   former does not support NaN and its isnan() implementation returns zero
+   for all values.  */
+#if defined __MVS__ && defined __IBMC__ && !defined __BFP__
+# error "NaN is not supported with IBM's hexadecimal floating-point format; please re-compile with -qfloat=ieee"
+#endif
+
 /* NaNf () returns a 'float' not-a-number.  */
 
 /* The Compaq (ex-DEC) C 6.4 compiler and the Microsoft MSVC 9 compiler choke
-   on the expression 0.0 / 0.0.  */
-#if defined __DECC || defined _MSC_VER
+   on the expression 0.0 / 0.0.  The IBM XL C compiler on z/OS complains.  */
+#if defined __DECC || defined _MSC_VER || (defined __MVS__ && defined __IBMC__)
 static float
 NaNf ()
 {
@@ -34,8 +41,8 @@ NaNf ()
 /* NaNd () returns a 'double' not-a-number.  */
 
 /* The Compaq (ex-DEC) C 6.4 compiler and the Microsoft MSVC 9 compiler choke
-   on the expression 0.0 / 0.0.  */
-#if defined __DECC || defined _MSC_VER
+   on the expression 0.0 / 0.0.  The IBM XL C compiler on z/OS complains.  */
+#if defined __DECC || defined _MSC_VER || (defined __MVS__ && defined __IBMC__)
 static double
 NaNd ()
 {
@@ -51,14 +58,15 @@ NaNd ()
 
 /* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
    runtime type conversion.
-   The Microsoft MSVC 9 compiler chokes on the expression 0.0L / 0.0L.  */
+   The Microsoft MSVC 9 compiler chokes on the expression 0.0L / 0.0L.
+   The IBM XL C compiler on z/OS complains.  */
 #ifdef __sgi
 static long double NaNl ()
 {
   double zero = 0.0;
   return zero / zero;
 }
-#elif defined _MSC_VER
+#elif defined _MSC_VER || (defined __MVS__ && defined __IBMC__)
 static long double
 NaNl ()
 {
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 12d2bb0..49c0221 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -191,12 +191,16 @@ main (void)
     ASSERT (result2);
     ASSERT (stat ("/", &st1) == 0);
     ASSERT (stat ("//", &st2) == 0);
+    /* On IBM z/OS, "/" and "//" are distinct, yet they both have
+       st_dev == st_ino == 1.  */
+#ifndef __MVS__
     if (SAME_INODE (st1, st2))
       {
         ASSERT (strcmp (result1, "/") == 0);
         ASSERT (strcmp (result2, "/") == 0);
       }
     else
+#endif
       {
         ASSERT (strcmp (result1, "//") == 0);
         ASSERT (strcmp (result2, "//") == 0);
diff --git a/tests/test-nonblocking-pipe.h b/tests/test-nonblocking-pipe.h
index 5b3646e..01c992c 100644
--- a/tests/test-nonblocking-pipe.h
+++ b/tests/test-nonblocking-pipe.h
@@ -31,10 +31,11 @@
      OSF/1                           >= 262145
      Solaris <= 7                    >= 10241
      Solaris >= 8                    >= 20481
+     z/OS                            >= 131073
      Cygwin                          >= 65537
      native Windows                  >= 4097 (depends on the _pipe argument)
  */
-#if defined __osf__ || (defined __linux__ && (defined __ia64__ || defined __mips__))
+#if defined __MVS__ || defined __osf__ || (defined __linux__ && (defined __ia64__ || defined __mips__))
 # define PIPE_DATA_BLOCK_SIZE 270000
 #elif defined __linux__ && defined __sparc__
 # define PIPE_DATA_BLOCK_SIZE 140000

diff --git a/tests/test-nonblocking-reader.h b/tests/test-nonblocking-reader.h
index 8cba131..d8eaa32 100644
--- a/tests/test-nonblocking-reader.h
+++ b/tests/test-nonblocking-reader.h
@@ -110,7 +110,7 @@ full_read_from_nonblocking_fd (size_t fd, void *buf, size_t count)
       ASSERT (spent_time < 0.5);
       if (ret < 0)
         {
-          ASSERT (saved_errno == EAGAIN);
+          ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
           usleep (SMALL_DELAY);
         }
       else
diff --git a/tests/test-nonblocking-writer.h b/tests/test-nonblocking-writer.h
index 0ecf996..ff148dc 100644
--- a/tests/test-nonblocking-writer.h
+++ b/tests/test-nonblocking-writer.h
@@ -124,7 +124,7 @@ main_writer_loop (int test, size_t data_block_size, int fd,
                         (long) ret, dbgstrerror (ret < 0, saved_errno));
             if (ret < 0 && bytes_written >= data_block_size)
               {
-                ASSERT (saved_errno == EAGAIN);
+                ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
                 ASSERT (spent_time < 0.5);
                 break;
               }
@@ -133,7 +133,7 @@ main_writer_loop (int test, size_t data_block_size, int fd,
             ASSERT (spent_time < 0.5);
             if (ret < 0)
               {
-                ASSERT (saved_errno == EAGAIN);
+                ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
                 usleep (SMALL_DELAY);
               }
             else
@@ -165,7 +165,7 @@ main_writer_loop (int test, size_t data_block_size, int fd,
             ASSERT (spent_time < 0.5);
             if (ret < 0)
               {
-                ASSERT (saved_errno == EAGAIN);
+                ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
                 usleep (SMALL_DELAY);
               }
             else

diff --git a/lib/glthread/thread.c b/lib/glthread/thread.c
index d4e2921..5923ea2 100644
--- a/lib/glthread/thread.c
+++ b/lib/glthread/thread.c
@@ -33,7 +33,7 @@
 
 #include <pthread.h>
 
-#ifdef PTW32_VERSION
+#if defined PTW32_VERSION || defined __MVS__
 
 const gl_thread_t gl_null_thread /* = { .p = NULL } */;
 
diff --git a/lib/glthread/thread.h b/lib/glthread/thread.h
index 2febe34..36a9521 100644
--- a/lib/glthread/thread.h
+++ b/lib/glthread/thread.h
@@ -172,6 +172,15 @@ typedef pthread_t gl_thread_t;
 #  define gl_thread_self_pointer() \
      (pthread_in_use () ? pthread_self ().p : NULL)
 extern const gl_thread_t gl_null_thread;
+# elif defined __MVS__
+   /* On IBM z/OS, pthread_t is a struct with an 8-byte '__' field.
+      The first three bytes of this field appear to uniquely identify a
+      pthread_t, though not necessarily representing a pointer.  */
+#  define gl_thread_self() \
+     (pthread_in_use () ? pthread_self () : gl_null_thread)
+#  define gl_thread_self_pointer() \
+     (pthread_in_use () ? *((void **) pthread_self ().__) : NULL)
+extern const gl_thread_t gl_null_thread;
 # else
 #  define gl_thread_self() \
      (pthread_in_use () ? pthread_self () : (pthread_t) NULL)

diff --git a/lib/regex.h b/lib/regex.h
index 6f3bae3..21fc00c 100644
--- a/lib/regex.h
+++ b/lib/regex.h
@@ -23,6 +23,12 @@
 
 #include <sys/types.h>
 
+/* IBM z/OS uses -D__string=1 as an inclusion guard.  */
+#if defined __MVS__ && defined(__string)
+# undef __string
+# define __string __string
+#endif
+
 /* Allow the use in C++ code.  */
 #ifdef __cplusplus
 extern "C" {
diff --git a/lib/string.in.h b/lib/string.in.h
index b3356bb..fa438a4 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -44,6 +44,12 @@
 #ifndef _@GUARD_PREFIX@_STRING_H
 #define _@GUARD_PREFIX@_STRING_H
 
+/* IBM z/OS uses -D__string=1 as an inclusion guard.  */
+#if defined __MVS__ && defined(__string)
+# undef __string
+# define __string __string
+#endif
+
 /* NetBSD 5.0 mis-defines NULL.  */
 #include <stddef.h>
 

diff --git a/lib/strtod.c b/lib/strtod.c
index 9fd0170..9dc6eeb 100644
--- a/lib/strtod.c
+++ b/lib/strtod.c
@@ -239,7 +239,12 @@ strtod (const char *nptr, char **endptr)
       if (*s == '0' && c_tolower (s[1]) == 'x')
         {
           if (! c_isxdigit (s[2 + (s[2] == '.')]))
-            end = s + 1;
+            {
+              end = s + 1;
+
+              /* strtod() on z/OS returns ERANGE for "0x".  */
+              errno = 0;
+            }
           else if (end <= s + 2)
             {
               num = parse_number (s + 2, 16, 2, 4, 'p', &endbuf);
@@ -321,7 +326,7 @@ strtod (const char *nptr, char **endptr)
          better to use the underlying implementation's result, since a
          nice implementation populates the bits of the NaN according
          to interpreting n-char-sequence as a hexadecimal number.  */
-      if (s != end)
+      if (s != end || num == num)
         num = NAN;
       errno = saved_errno;
     }

Reply via email to