Allow overriding the newline conversion for EBCDIC encodings.

Reported by Mike Fulton <mikefultonpersonal@gmail.com> in
<https://lists.gnu.org/archive/html/bug-gnu-libiconv/2023-04/msg00009.html>.

* include/iconv.h.in (ICONV_SURFACE_NONE,
ICONV_SURFACE_EBCDIC_ZOS_UNIX): New macros.
(ICONV_GET_FROM_SURFACE, ICONV_SET_FROM_SURFACE, ICONV_GET_TO_SURFACE,
ICONV_SET_TO_SURFACE): New macros.
* lib/converters.h (struct conv_struct): Add the fields isurface,
osurface.
(swap_x15_x25): New macro.
* lib/iconv.c (iconv_open, iconv_open_into): Add local variables
from_surface, to_surface.
(ALL_SURFACES): New macro.
(iconvctl): Adjust ICONV_TRIVIALP implementation. Implement the
ICONV_{GET,SET}_{FROM,TO}_SURFACE requests.
* lib/iconv_open1.h: Parse a /ZOS_UNIX surface specifier. Set
from_surface, to_surface.
* lib/iconv_open2.h: Copy the values of from_surface, to_surface into
the conversion descriptor.
* lib/ebcdic*.h (*_mbtowc): Test the isurface. If requested, call
swap_x15_x25 right after fetching an input byte.
(*_wctomb): Test the osurface. If requested, call swap_x15_x25 right
before storing an output byte.
* man/iconvctl.3 (REQUEST VALUES): Document the
ICONV_{GET,SET}_{FROM,TO}_SURFACE requests.
* src/iconv.c (main): If ICONV_EBCDIC_ZOS_UNIX is set, set the from/to
surfaces accordingly.
* man/iconv.1 (ENVIRONMENT): New section.
* tests/check-ebcdic: New file.
* tests/Makefile.in (check): Invoke it.
(SOURCE_FILES): Add it.
* NEWS: Mention the new functionality.
diff --git a/ChangeLog b/ChangeLog
index 28fecee..7d488e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2023-04-03  Bruno Haible  <bruno@clisp.org>
+
+	Allow overriding the newline conversion for EBCDIC encodings.
+	Reported by Mike Fulton <mikefultonpersonal@gmail.com> in
+	<https://lists.gnu.org/archive/html/bug-gnu-libiconv/2023-04/msg00009.html>.
+	* include/iconv.h.in (ICONV_SURFACE_NONE,
+	ICONV_SURFACE_EBCDIC_ZOS_UNIX): New macros.
+	(ICONV_GET_FROM_SURFACE, ICONV_SET_FROM_SURFACE, ICONV_GET_TO_SURFACE,
+	ICONV_SET_TO_SURFACE): New macros.
+	* lib/converters.h (struct conv_struct): Add the fields isurface,
+	osurface.
+	(swap_x15_x25): New macro.
+	* lib/iconv.c (iconv_open, iconv_open_into): Add local variables
+	from_surface, to_surface.
+	(ALL_SURFACES): New macro.
+	(iconvctl): Adjust ICONV_TRIVIALP implementation. Implement the
+	ICONV_{GET,SET}_{FROM,TO}_SURFACE requests.
+	* lib/iconv_open1.h: Parse a /ZOS_UNIX surface specifier. Set
+	from_surface, to_surface.
+	* lib/iconv_open2.h: Copy the values of from_surface, to_surface into
+	the conversion descriptor.
+	* lib/ebcdic*.h (*_mbtowc): Test the isurface. If requested, call
+	swap_x15_x25 right after fetching an input byte.
+	(*_wctomb): Test the osurface. If requested, call swap_x15_x25 right
+	before storing an output byte.
+	* man/iconvctl.3 (REQUEST VALUES): Document the
+	ICONV_{GET,SET}_{FROM,TO}_SURFACE requests.
+	* src/iconv.c (main): If ICONV_EBCDIC_ZOS_UNIX is set, set the from/to
+	surfaces accordingly.
+	* man/iconv.1 (ENVIRONMENT): New section.
+	* tests/check-ebcdic: New file.
+	* tests/Makefile.in (check): Invoke it.
+	(SOURCE_FILES): Add it.
+	* NEWS: Mention the new functionality.
+
 2023-03-31  Bruno Haible  <bruno@clisp.org>
 
 	Add some transliterations for mathematical symbols.
diff --git a/NEWS b/NEWS
index 1b815ea..7959cc9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
 New in 1.18:
 * Many more transliterations.
+* When converting from/to an EBCDIC encoding, a non-standard way of
+  converting newlines can be requested
+    - at the C level, by calling iconvctl with argument ICONV_SET_FROM_SURFACE
+      or ICONV_SET_TO_SURFACE, or
+    - from the iconv program, by setting the environment variable
+      ICONV_EBCDIC_ZOS_UNIX to a non-empty value.
 
 New in 1.17:
 * The libiconv library is now licensed under the LGPL version 2.1, instead of
diff --git a/include/iconv.h.in b/include/iconv.h.in
index 62f7b35..f9f1123 100644
--- a/include/iconv.h.in
+++ b/include/iconv.h.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2022 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2023 Free Software Foundation, Inc.
    This file is part of the GNU LIBICONV Library.
 
    The GNU LIBICONV Library is free software; you can redistribute it
@@ -201,6 +201,14 @@
   void* data;
 };
 
+/* Surfaces.
+   The concept of surfaces is described in the 'recode' manual.  */
+#define ICONV_SURFACE_NONE             0
+/* In EBCDIC encodings, 0x15 (which encodes the "newline function", see the
+   Unicode standard, chapter 5) maps to U+000A instead of U+0085.  This is
+   for interoperability with C programs and Unix environments on z/OS.  */
+#define ICONV_SURFACE_EBCDIC_ZOS_UNIX  1
+
 /* Requests for iconvctl. */
 #define ICONV_TRIVIALP            0  /* int *argument */
 #define ICONV_GET_TRANSLITERATE   1  /* int *argument */
@@ -209,6 +217,10 @@
 #define ICONV_SET_DISCARD_ILSEQ   4  /* const int *argument */
 #define ICONV_SET_HOOKS           5  /* const struct iconv_hooks *argument */
 #define ICONV_SET_FALLBACKS       6  /* const struct iconv_fallbacks *argument */
+#define ICONV_GET_FROM_SURFACE    7  /* unsigned int *argument */
+#define ICONV_SET_FROM_SURFACE    8  /* const unsigned int *argument */
+#define ICONV_GET_TO_SURFACE      9  /* unsigned int *argument */
+#define ICONV_SET_TO_SURFACE     10  /* const unsigned int *argument */
 
 /* Listing of locale independent encodings. */
 #define iconvlist libiconvlist
diff --git a/lib/converters.h b/lib/converters.h
index e2e2227..fe5269d 100644
--- a/lib/converters.h
+++ b/lib/converters.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2002, 2004-2011, 2016, 2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2002, 2004-2011, 2016, 2022-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -98,11 +98,13 @@
   /* Input (conversion multibyte -> unicode) */
   int iindex;
   struct mbtowc_funcs ifuncs;
+  unsigned int isurface;
   state_t istate;
   /* Output (conversion unicode -> multibyte) */
   int oindex;
   struct wctomb_funcs ofuncs;
   int oflags;
+  unsigned int osurface;
   state_t ostate;
   /* Operation flags */
   int transliterate;
@@ -291,7 +293,36 @@
 #endif
 
 #ifdef USE_ZOS
+
 #define DEDUPLICATE_TABLES 1
+
+/* Swaps the values 0x15 and 0x25.
+   Both gcc and clang compile this expression to something that involves as few
+   conditional branching instructions as possible. */
+#define swap_x15_x25_a(x) ((x) == 0x15 ? 0x25 : (x) == 0x25 ? 0x15 : (x))
+#define swap_x15_x25_b(x) ((x) ^ ((x) == 0x15 || (x) == 0x25 ? 0x30 : 0))
+#define swap_x15_x25_c(x) ((x) ^ ((((x) - 0x15) & ~0x10) == 0 ? 0x30 : 0))
+/* Number of conditional branches (with "gcc -O2", as of 2023):
+                   a    b    c
+                 ---------------
+   aarch64         1    0    0
+   alpha           0    0    0
+   arm             1    0    0
+   hppa            1    1    1
+   i686            1    0    0
+   m68k            2    1    1
+   mips            2    1    0
+   mips64          2    1    0
+   powerpc         2    1    1
+   powerpc64       2    1    1
+   powerpc64le     2    1    1
+   riscv64         2    1    1
+   s390x           1    1    1
+   sh4             2    1    1
+   x86_64          1    0    0
+*/
+#define swap_x15_x25 swap_x15_x25_c
+
 #include "ebcdic037.h"
 #include "ebcdic273.h"
 #include "ebcdic277.h"
diff --git a/lib/ebcdic037.h b/lib/ebcdic037.h
index 2de9805..0777f06 100644
--- a/lib/ebcdic037.h
+++ b/lib/ebcdic037.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic037_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic037_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic037_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1025.h b/lib/ebcdic1025.h
index 28dcb2b..24acac8 100644
--- a/lib/ebcdic1025.h
+++ b/lib/ebcdic1025.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1025_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1025_2uni[c];
   return 1;
 }
@@ -134,6 +136,8 @@
   else if (wc == 0x2116)
     c = 0x58;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1026.h b/lib/ebcdic1026.h
index b4f2dc0..4bce37e 100644
--- a/lib/ebcdic1026.h
+++ b/lib/ebcdic1026.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1026_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1026_2uni[c];
   return 1;
 }
@@ -135,6 +137,8 @@
   else if (wc >= 0x0118 && wc < 0x0160)
     c = ebcdic1026_page01[wc-0x0118];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1047.h b/lib/ebcdic1047.h
index 1c9bc95..b274c0c 100644
--- a/lib/ebcdic1047.h
+++ b/lib/ebcdic1047.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1047_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1047_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic1047_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1097.h b/lib/ebcdic1097.h
index cb23176..dabdca7 100644
--- a/lib/ebcdic1097.h
+++ b/lib/ebcdic1097.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1097_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1097_2uni[c];
   return 1;
 }
@@ -179,6 +181,8 @@
   else if (wc >= 0xfe80 && wc < 0xfef0)
     c = ebcdic1097_pagefe[wc-0xfe80];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1112.h b/lib/ebcdic1112.h
index 7ee8e4a..a1459e9 100644
--- a/lib/ebcdic1112.h
+++ b/lib/ebcdic1112.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1112_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1112_2uni[c];
   return 1;
 }
@@ -144,6 +146,8 @@
   else if (wc >= 0x2018 && wc < 0x2020)
     c = ebcdic1112_page20[wc-0x2018];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1122.h b/lib/ebcdic1122.h
index 2b97ac3..d28d897 100644
--- a/lib/ebcdic1122.h
+++ b/lib/ebcdic1122.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1122_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1122_2uni[c];
   return 1;
 }
@@ -130,6 +132,8 @@
   else if (wc >= 0x0160 && wc < 0x0180)
     c = ebcdic1122_page01[wc-0x0160];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1123.h b/lib/ebcdic1123.h
index bcd1952..4b0cc30 100644
--- a/lib/ebcdic1123.h
+++ b/lib/ebcdic1123.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1123_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1123_2uni[c];
   return 1;
 }
@@ -141,6 +143,8 @@
   else if (wc == 0x2116)
     c = 0x58;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1130.h b/lib/ebcdic1130.h
index ad9c8b4..8d77e69 100644
--- a/lib/ebcdic1130.h
+++ b/lib/ebcdic1130.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1130_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1130_2uni[c];
   return 1;
 }
@@ -157,6 +159,8 @@
   else if (wc == 0x20ab)
     c = 0x78;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1132.h b/lib/ebcdic1132.h
index 1a6e91c..7c53dbb 100644
--- a/lib/ebcdic1132.h
+++ b/lib/ebcdic1132.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1132_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic1132_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -138,6 +140,8 @@
   else if (wc == 0x20ad)
     c = 0x70;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1137.h b/lib/ebcdic1137.h
index 19b28a7..b4b7374 100644
--- a/lib/ebcdic1137.h
+++ b/lib/ebcdic1137.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1137_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic1137_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -139,6 +141,8 @@
   else if (wc >= 0x2008 && wc < 0x2010)
     c = ebcdic1137_page20[wc-0x2008];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1140.h b/lib/ebcdic1140.h
index f10c1cf..a8557cf 100644
--- a/lib/ebcdic1140.h
+++ b/lib/ebcdic1140.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1140_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1140_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1141.h b/lib/ebcdic1141.h
index 94a1bba..d7669a0 100644
--- a/lib/ebcdic1141.h
+++ b/lib/ebcdic1141.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1141_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1141_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1142.h b/lib/ebcdic1142.h
index 4676d66..4e9e1be 100644
--- a/lib/ebcdic1142.h
+++ b/lib/ebcdic1142.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1142_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1142_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x5a;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1143.h b/lib/ebcdic1143.h
index e602466..5975779 100644
--- a/lib/ebcdic1143.h
+++ b/lib/ebcdic1143.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1143_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1143_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x5a;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1144.h b/lib/ebcdic1144.h
index 5d63eb8..ee9f041 100644
--- a/lib/ebcdic1144.h
+++ b/lib/ebcdic1144.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1144_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1144_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1145.h b/lib/ebcdic1145.h
index 23788d5..15dc1e4 100644
--- a/lib/ebcdic1145.h
+++ b/lib/ebcdic1145.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1145_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1145_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1146.h b/lib/ebcdic1146.h
index 46a60b5..2deab36 100644
--- a/lib/ebcdic1146.h
+++ b/lib/ebcdic1146.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1146_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1146_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1147.h b/lib/ebcdic1147.h
index 34e3645..0eba7c2 100644
--- a/lib/ebcdic1147.h
+++ b/lib/ebcdic1147.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1147_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1147_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1148.h b/lib/ebcdic1148.h
index fc51e27..eaa4894 100644
--- a/lib/ebcdic1148.h
+++ b/lib/ebcdic1148.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1148_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1148_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1149.h b/lib/ebcdic1149.h
index 027844e..1d1ae45 100644
--- a/lib/ebcdic1149.h
+++ b/lib/ebcdic1149.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1149_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1149_2uni[c];
   return 1;
 }
@@ -124,6 +126,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1153.h b/lib/ebcdic1153.h
index 590e548..8279a18 100644
--- a/lib/ebcdic1153.h
+++ b/lib/ebcdic1153.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1153_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1153_2uni[c];
   return 1;
 }
@@ -153,6 +155,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1154.h b/lib/ebcdic1154.h
index 52095a9..f193d8a 100644
--- a/lib/ebcdic1154.h
+++ b/lib/ebcdic1154.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1154_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1154_2uni[c];
   return 1;
 }
@@ -136,6 +138,8 @@
   else if (wc == 0x2116)
     c = 0x58;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1155.h b/lib/ebcdic1155.h
index 0638a31..a7efe93 100644
--- a/lib/ebcdic1155.h
+++ b/lib/ebcdic1155.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1155_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1155_2uni[c];
   return 1;
 }
@@ -141,6 +143,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1156.h b/lib/ebcdic1156.h
index 20ca348..d0b8457 100644
--- a/lib/ebcdic1156.h
+++ b/lib/ebcdic1156.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1156_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1156_2uni[c];
   return 1;
 }
@@ -150,6 +152,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1157.h b/lib/ebcdic1157.h
index 3a79ecf..bf8778e 100644
--- a/lib/ebcdic1157.h
+++ b/lib/ebcdic1157.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1157_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1157_2uni[c];
   return 1;
 }
@@ -136,6 +138,8 @@
   else if (wc == 0x20ac)
     c = 0x5a;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1158.h b/lib/ebcdic1158.h
index 0d82b2a..39fc469 100644
--- a/lib/ebcdic1158.h
+++ b/lib/ebcdic1158.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1158_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1158_2uni[c];
   return 1;
 }
@@ -147,6 +149,8 @@
   else if (wc == 0x2116)
     c = 0x58;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1160.h b/lib/ebcdic1160.h
index 480bd8c..ce8e028 100644
--- a/lib/ebcdic1160.h
+++ b/lib/ebcdic1160.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1160_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1160_2uni[c];
   return 1;
 }
@@ -138,6 +140,8 @@
   else if (wc == 0x20ac)
     c = 0xfe;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1164.h b/lib/ebcdic1164.h
index d7f38fb..bd87156 100644
--- a/lib/ebcdic1164.h
+++ b/lib/ebcdic1164.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1164_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1164_2uni[c];
   return 1;
 }
@@ -164,6 +166,8 @@
   else if (wc >= 0x20a8 && wc < 0x20b0)
     c = ebcdic1164_page20[wc-0x20a8];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1165.h b/lib/ebcdic1165.h
index 79e99b7..c70687e 100644
--- a/lib/ebcdic1165.h
+++ b/lib/ebcdic1165.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1165_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1165_2uni[c];
   return 1;
 }
@@ -153,6 +155,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic1166.h b/lib/ebcdic1166.h
index e7aa22d..b90d6e6 100644
--- a/lib/ebcdic1166.h
+++ b/lib/ebcdic1166.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic1166_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic1166_2uni[c];
   return 1;
 }
@@ -154,6 +156,8 @@
   else if (wc == 0x2116)
     c = 0x58;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic12712.h b/lib/ebcdic12712.h
index 42d9d33..e7a5650 100644
--- a/lib/ebcdic12712.h
+++ b/lib/ebcdic12712.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic12712_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic12712_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -157,6 +159,8 @@
   else if (wc >= 0x20a8 && wc < 0x20b0)
     c = ebcdic12712_page20_1[wc-0x20a8];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic16804.h b/lib/ebcdic16804.h
index fd7af59..57a2031 100644
--- a/lib/ebcdic16804.h
+++ b/lib/ebcdic16804.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic16804_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic16804_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -171,6 +173,8 @@
   else if (wc >= 0xfe78 && wc < 0xff00)
     c = ebcdic16804_pagefe[wc-0xfe78];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic273.h b/lib/ebcdic273.h
index 6dc48f4..587d9cc 100644
--- a/lib/ebcdic273.h
+++ b/lib/ebcdic273.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic273_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic273_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic273_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic277.h b/lib/ebcdic277.h
index c21cfe2..a0b8137 100644
--- a/lib/ebcdic277.h
+++ b/lib/ebcdic277.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic277_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic277_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic277_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic278.h b/lib/ebcdic278.h
index 37b06d4..beafa30 100644
--- a/lib/ebcdic278.h
+++ b/lib/ebcdic278.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic278_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic278_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic278_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic280.h b/lib/ebcdic280.h
index 2102f15..2fa5a2b 100644
--- a/lib/ebcdic280.h
+++ b/lib/ebcdic280.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic280_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic280_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic280_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic282.h b/lib/ebcdic282.h
index 3779bc1..07faf9e 100644
--- a/lib/ebcdic282.h
+++ b/lib/ebcdic282.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic282_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic282_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic282_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic284.h b/lib/ebcdic284.h
index 368a7de..8a9cceb 100644
--- a/lib/ebcdic284.h
+++ b/lib/ebcdic284.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic284_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic284_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic284_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic285.h b/lib/ebcdic285.h
index feb65a8..f566bc4 100644
--- a/lib/ebcdic285.h
+++ b/lib/ebcdic285.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic285_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic285_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic285_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic297.h b/lib/ebcdic297.h
index 391dff3..b0c96cd 100644
--- a/lib/ebcdic297.h
+++ b/lib/ebcdic297.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic297_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic297_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic297_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic423.h b/lib/ebcdic423.h
index 6dd6388..7782148 100644
--- a/lib/ebcdic423.h
+++ b/lib/ebcdic423.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic423_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic423_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -140,6 +142,8 @@
   else if (wc >= 0x0380 && wc < 0x03d0)
     c = ebcdic423_page03[wc-0x0380];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic424.h b/lib/ebcdic424.h
index f426e89..afcbba9 100644
--- a/lib/ebcdic424.h
+++ b/lib/ebcdic424.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic424_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic424_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -143,6 +145,8 @@
   else if (wc >= 0x2010 && wc < 0x2040)
     c = ebcdic424_page20[wc-0x2010];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic425.h b/lib/ebcdic425.h
index d2f04b1..de7440b 100644
--- a/lib/ebcdic425.h
+++ b/lib/ebcdic425.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic425_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic425_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -157,6 +159,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic4971.h b/lib/ebcdic4971.h
index 63e23d9..cfef3bb 100644
--- a/lib/ebcdic4971.h
+++ b/lib/ebcdic4971.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic4971_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic4971_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -152,6 +154,8 @@
   else if (wc == 0x20ac)
     c = 0xfc;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic500.h b/lib/ebcdic500.h
index 4270513..f3935c9 100644
--- a/lib/ebcdic500.h
+++ b/lib/ebcdic500.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic500_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic500_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic500_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic838.h b/lib/ebcdic838.h
index 99911bd..01bded8 100644
--- a/lib/ebcdic838.h
+++ b/lib/ebcdic838.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic838_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic838_2uni[c];
   return 1;
 }
@@ -128,6 +130,8 @@
   else if (wc >= 0x0e00 && wc < 0x0e60)
     c = ebcdic838_page0e[wc-0x0e00];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic870.h b/lib/ebcdic870.h
index 8b14f83..7111d5e 100644
--- a/lib/ebcdic870.h
+++ b/lib/ebcdic870.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic870_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic870_2uni[c];
   return 1;
 }
@@ -147,6 +149,8 @@
   else if (wc >= 0x02c0 && wc < 0x02e0)
     c = ebcdic870_page02[wc-0x02c0];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic871.h b/lib/ebcdic871.h
index 0e091cd..27f5705 100644
--- a/lib/ebcdic871.h
+++ b/lib/ebcdic871.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic871_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic871_2uni[c];
   return 1;
 }
@@ -122,6 +124,8 @@
   if (wc < 0x0100)
     c = ebcdic871_page00[wc];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic875.h b/lib/ebcdic875.h
index dee3f46..759c14e 100644
--- a/lib/ebcdic875.h
+++ b/lib/ebcdic875.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic875_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic875_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -138,6 +140,8 @@
   else if (wc >= 0x2010 && wc < 0x2020)
     c = ebcdic875_page20[wc-0x2010];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic880.h b/lib/ebcdic880.h
index bcadc52..bd40720 100644
--- a/lib/ebcdic880.h
+++ b/lib/ebcdic880.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic880_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic880_2uni[c];
   return 1;
 }
@@ -130,6 +132,8 @@
   else if (wc == 0x2116)
     c = 0x58;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic905.h b/lib/ebcdic905.h
index 6041c99..c3cef74 100644
--- a/lib/ebcdic905.h
+++ b/lib/ebcdic905.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic905_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   unsigned short wc = ebcdic905_2uni[c];
   if (wc != 0xfffd) {
     *pwc = (ucs4_t) wc;
@@ -150,6 +152,8 @@
   else if (wc >= 0x02d8 && wc < 0x02e0)
     c = ebcdic905_page02[wc-0x02d8];
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/ebcdic924.h b/lib/ebcdic924.h
index cc7cd7c..c3cba1f 100644
--- a/lib/ebcdic924.h
+++ b/lib/ebcdic924.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -76,6 +76,8 @@
 ebcdic924_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
 {
   unsigned char c = *s;
+  if (conv->isurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+    c = swap_x15_x25 (c);
   *pwc = (ucs4_t) ebcdic924_2uni[c];
   return 1;
 }
@@ -134,6 +136,8 @@
   else if (wc == 0x20ac)
     c = 0x9f;
   if (c != 0 || wc == 0) {
+    if (conv->osurface & ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+      c = swap_x15_x25 (c);
     *r = c;
     return 1;
   }
diff --git a/lib/iconv.c b/lib/iconv.c
index 673457e..178193e 100644
--- a/lib/iconv.c
+++ b/lib/iconv.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2008, 2011, 2016, 2018, 2020, 2022 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2008, 2011, 2016, 2018, 2020, 2022-2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -236,8 +236,10 @@
   struct conv_struct * cd;
   unsigned int from_index;
   int from_wchar;
+  unsigned int from_surface;
   unsigned int to_index;
   int to_wchar;
+  unsigned int to_surface;
   int transliterate;
   int discard_ilseq;
 
@@ -286,7 +288,7 @@
  * fit in an iconv_allocation_t.
  * If this verification fails, iconv_allocation_t must be made larger and
  * the major version in LIBICONV_VERSION_INFO must be bumped.
- * Currently 'struct conv_struct' has 21 integer/pointer fields, and
+ * Currently 'struct conv_struct' has 23 integer/pointer fields, and
  * 'struct wchar_conv_struct' additionally has an 'mbstate_t' field.
  */
 typedef int verify_size_1[2 * (sizeof (struct conv_struct) <= sizeof (iconv_allocation_t)) - 1];
@@ -298,8 +300,10 @@
   struct conv_struct * cd;
   unsigned int from_index;
   int from_wchar;
+  unsigned int from_surface;
   unsigned int to_index;
   int to_wchar;
+  unsigned int to_surface;
   int transliterate;
   int discard_ilseq;
 
@@ -315,6 +319,9 @@
   return -1;
 }
 
+/* Bit mask of all valid surfaces. */
+#define ALL_SURFACES (ICONV_SURFACE_EBCDIC_ZOS_UNIX)
+
 int iconvctl (iconv_t icd, int request, void* argument)
 {
   conv_t cd = (conv_t) icd;
@@ -322,7 +329,8 @@
     case ICONV_TRIVIALP:
       *(int *)argument =
         ((cd->lfuncs.loop_convert == unicode_loop_convert
-          && cd->iindex == cd->oindex)
+          && cd->iindex == cd->oindex
+          && cd->isurface == cd->osurface)
          || cd->lfuncs.loop_convert == wchar_id_loop_convert
          ? 1 : 0);
       return 0;
@@ -358,6 +366,28 @@
         cd->fallbacks.data = NULL;
       }
       return 0;
+    case ICONV_GET_FROM_SURFACE:
+      *(unsigned int *)argument = cd->isurface;
+      return 0;
+    case ICONV_SET_FROM_SURFACE:
+      if ((*(const unsigned int *)argument & ~ALL_SURFACES) == 0) {
+        cd->isurface = *(const unsigned int *)argument;
+        return 0;
+      } else {
+        errno = EINVAL;
+        return -1;
+      }
+    case ICONV_GET_TO_SURFACE:
+      *(unsigned int *)argument = cd->osurface;
+      return 0;
+    case ICONV_SET_TO_SURFACE:
+      if ((*(const unsigned int *)argument & ~ALL_SURFACES) == 0) {
+        cd->osurface = *(const unsigned int *)argument;
+        return 0;
+      } else {
+        errno = EINVAL;
+        return -1;
+      }
     default:
       errno = EINVAL;
       return -1;
diff --git a/lib/iconv_open1.h b/lib/iconv_open1.h
index c6b24ef..a7288a4 100644
--- a/lib/iconv_open1.h
+++ b/lib/iconv_open1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2008, 2011, 2018, 2020 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2008, 2011, 2018, 2020, 2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -22,19 +22,23 @@
    Output:
      unsigned int from_index;
      int from_wchar;
+     unsigned int from_surface;
      unsigned int to_index;
      int to_wchar;
+     unsigned int to_surface;
      int transliterate;
      int discard_ilseq;
    Jumps to 'invalid' in case of errror.
  */
 {
-  char buf[MAX_WORD_LENGTH+10+1];
+  char buf[MAX_WORD_LENGTH+9+9+1];
   const char* cp;
   char* bp;
   const struct alias * ap;
   unsigned int count;
 
+  from_surface = ICONV_SURFACE_NONE;
+  to_surface = ICONV_SURFACE_NONE;
   transliterate = 0;
   discard_ilseq = 0;
 
@@ -45,7 +49,7 @@
    */
   for (to_wchar = 0;;) {
     /* Search tocode in the table. */
-    for (cp = tocode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++, bp++) {
+    for (cp = tocode, bp = buf, count = MAX_WORD_LENGTH+9+9+1; ; cp++, bp++) {
       unsigned char c = (unsigned char) *cp;
       if (c >= 0x80)
         goto invalid;
@@ -58,18 +62,28 @@
         goto invalid;
     }
     for (;;) {
-      if (bp-buf >= 10 && memcmp(bp-10,"//TRANSLIT",10)==0) {
-        bp -= 10;
-        *bp = '\0';
+      char *sp = bp;
+      int parsed_translit = 0;
+      int parsed_ignore = 0;
+      if (sp-buf > 9 && memcmp(sp-9,"/TRANSLIT",9)==0) {
+        sp = sp - 9;
+        parsed_translit = 1;
+      } else if (sp-buf > 7 && memcmp(sp-7,"/IGNORE",7)==0) {
+        sp = sp - 7;
+        parsed_ignore = 1;
+      }
+      if (sp > buf && memcmp(sp-1,"/",1) == 0) {
+        bp = sp - 1;
+      } else if (sp-buf >= 9 && memcmp(sp-9,"/ZOS_UNIX",9)==0) {
+        bp = sp - 9;
+        to_surface = ICONV_SURFACE_EBCDIC_ZOS_UNIX;
+      } else
+        break;
+      *bp = '\0';
+      if (parsed_translit)
         transliterate = 1;
-        continue;
-      }
-      if (bp-buf >= 8 && memcmp(bp-8,"//IGNORE",8)==0) {
-        bp -= 8;
-        *bp = '\0';
+      if (parsed_ignore)
         discard_ilseq = 1;
-        continue;
-      }
       break;
     }
     if (buf[0] == '\0') {
@@ -137,7 +151,7 @@
   }
   for (from_wchar = 0;;) {
     /* Search fromcode in the table. */
-    for (cp = fromcode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++, bp++) {
+    for (cp = fromcode, bp = buf, count = MAX_WORD_LENGTH+9+9+1; ; cp++, bp++) {
       unsigned char c = (unsigned char) *cp;
       if (c >= 0x80)
         goto invalid;
@@ -150,16 +164,28 @@
         goto invalid;
     }
     for (;;) {
-      if (bp-buf >= 10 && memcmp(bp-10,"//TRANSLIT",10)==0) {
-        bp -= 10;
-        *bp = '\0';
-        continue;
+      char *sp = bp;
+      int parsed_translit = 0;
+      int parsed_ignore = 0;
+      if (sp-buf > 9 && memcmp(sp-9,"/TRANSLIT",9)==0) {
+        sp = sp - 9;
+        parsed_translit = 1;
+      } else if (sp-buf > 7 && memcmp(sp-7,"/IGNORE",7)==0) {
+        sp = sp - 7;
+        parsed_ignore = 1;
       }
-      if (bp-buf >= 8 && memcmp(bp-8,"//IGNORE",8)==0) {
-        bp -= 8;
-        *bp = '\0';
-        continue;
-      }
+      if (sp > buf && memcmp(sp-1,"/",1) == 0) {
+        bp = sp - 1;
+      } else if (sp-buf >= 9 && memcmp(sp-9,"/ZOS_UNIX",9)==0) {
+        bp = sp - 9;
+        from_surface = ICONV_SURFACE_EBCDIC_ZOS_UNIX;
+      } else
+        break;
+      *bp = '\0';
+      if (parsed_translit)
+        transliterate = 1;
+      if (parsed_ignore)
+        discard_ilseq = 1;
       break;
     }
     if (buf[0] == '\0') {
diff --git a/lib/iconv_open2.h b/lib/iconv_open2.h
index aaac547..3882803 100644
--- a/lib/iconv_open2.h
+++ b/lib/iconv_open2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2009 Free Software Foundation, Inc.
+ * Copyright (C) 1999-2009, 2023 Free Software Foundation, Inc.
  * This file is part of the GNU LIBICONV Library.
  *
  * The GNU LIBICONV Library is free software; you can redistribute it
@@ -22,8 +22,10 @@
      struct conv_struct * cd;
      unsigned int from_index;
      int from_wchar;
+     unsigned int from_surface;
      unsigned int to_index;
      int to_wchar;
+     unsigned int to_surface;
      int transliterate;
      int discard_ilseq;
    Output: none.
@@ -62,6 +64,9 @@
       cd->lfuncs.loop_reset = unicode_loop_reset;
     }
   }
+  /* Initialize the surfaces. */
+  cd->isurface = from_surface;
+  cd->osurface = to_surface;
   /* Initialize the states. */
   memset(&cd->istate,'\0',sizeof(state_t));
   memset(&cd->ostate,'\0',sizeof(state_t));
diff --git a/man/iconv.1 b/man/iconv.1
index 9c6af5a..bc065cf 100644
--- a/man/iconv.1
+++ b/man/iconv.1
@@ -9,7 +9,7 @@
 .\"   OpenGroup's Single Unix specification http://www.UNIX-systems.org/online.html
 .\"   POSIX 2001 draft6
 .\"
-.TH ICONV 1  "March 31, 2007" "GNU" "Linux Programmer's Manual"
+.TH ICONV 1  "April 3, 2023" "GNU" "Linux Programmer's Manual"
 .SH NAME
 iconv \- character set conversion
 .SH SYNOPSIS
@@ -84,6 +84,10 @@
 implementation, the names are printed in upper case, separated by whitespace,
 and alias names of an encoding are listed on the same line as the encoding
 itself.
+.SH ENVIRONMENT
+Conversion from/to EBCDIC encodings can be modified in a specific way:
+If the environment variable \fBICONV_EBCDIC_ZOS_UNIX\fP is set to a non-empty
+value, the EBCDIC newline 0x15 will get mapped to LF instead of NEL.
 .SH EXAMPLES
 .TP
 \fBiconv \-f ISO\-8859\-1 \-t UTF\-8\fP
diff --git a/man/iconvctl.3 b/man/iconvctl.3
index b460d87..6a4a2d6 100644
--- a/man/iconvctl.3
+++ b/man/iconvctl.3
@@ -9,7 +9,7 @@
 .\" References consulted:
 .\"   iconv.h
 .\"
-.TH ICONVCTL 3  "March 31, 2007" "GNU" "Linux Programmer's Manual"
+.TH ICONVCTL 3  "April 3, 2023" "GNU" "Linux Programmer's Manual"
 .SH NAME
 iconvctl \- control iconv behavior
 .SH SYNOPSIS
@@ -50,6 +50,30 @@
 \fIargument\fP should be a \fBconst int *\fP, pointing to an \fBint\fP value.
 A non-zero value is used to enable "illegal sequence discard and continue"
 in the conversion. A zero value disables it.
+.TP
+.B ICONV_GET_FROM_SURFACE
+\fIargument\fP should be an \fBunsigned int *\fP which will receive the
+from-side (input side) surface of the conversion.
+.TP
+.B ICONV_SET_FROM_SURFACE
+\fIargument\fP should be a \fBconst unsigned int *\fP, pointing to an
+\fBunsigned int\fP value.  This value is installed as the from-side
+(input side) surface of the conversion.  The value is a bit mask.  Zero
+denotes no surface.  The value \fBICONV_SURFACE_EBCDIC_ZOS_UNIX\fP has
+an effect on EBCDIC encodings: The EBCDIC newline 0x15 will get mapped
+to LF instead of NEL.
+.TP
+.B ICONV_GET_TO_SURFACE
+\fIargument\fP should be an \fBunsigned int *\fP which will receive the
+to-side (output side) surface of the conversion.
+.TP
+.B ICONV_SET_TO_SURFACE
+\fIargument\fP should be a \fBconst unsigned int *\fP, pointing to an
+\fBunsigned int\fP value.  This value is installed as the to-side
+(output side) surface of the conversion.  The value is a bit mask.  Zero
+denotes no surface.  The value \fBICONV_SURFACE_EBCDIC_ZOS_UNIX\fP has
+an effect on EBCDIC encodings: LF, instead of NEL, will get mapped to
+the EBCDIC newline 0x15.
 .SH "RETURN VALUE"
 The \fBiconvctl\fP function returns 0 if it succeeds. In case of error, it sets
 \fBerrno\fP and returns \-1.
diff --git a/src/iconv.c b/src/iconv.c
index e3932e5..ec4caa1 100644
--- a/src/iconv.c
+++ b/src/iconv.c
@@ -1047,6 +1047,18 @@
             _("try '%s -l' to get the list of supported encodings"),
             program_name);
     }
+    /* For EBCDIC encodings, determine how to map 0x15 (which encodes the
+       "newline function", see the Unicode standard, chapter 5).  */
+    const char *envvar_value = getenv("ICONV_EBCDIC_ZOS_UNIX");
+    if (envvar_value != NULL && envvar_value[0] != '\0') {
+      unsigned int surface;
+      iconvctl(cd, ICONV_GET_FROM_SURFACE, &surface);
+      surface |= ICONV_SURFACE_EBCDIC_ZOS_UNIX;
+      iconvctl(cd, ICONV_SET_FROM_SURFACE, &surface);
+      iconvctl(cd, ICONV_GET_TO_SURFACE, &surface);
+      surface |= ICONV_SURFACE_EBCDIC_ZOS_UNIX;
+      iconvctl(cd, ICONV_SET_TO_SURFACE, &surface);
+    }
     /* Look at fromcode and tocode, to determine whether character widths
        should be determined according to legacy CJK conventions. */
     cjkcode = iconv_canonicalize(tocode);
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 5d5875f..794a379 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -160,6 +160,8 @@
 	$(SHELL) $(srcdir)/check-translitfailure $(srcdir) TranslitFail1 ISO-8859-1 ASCII
 #	/* substitution */
 	$(SHELL) $(srcdir)/check-subst
+#	/* EBCDIC specific functionality */
+	$(SHELL) $(srcdir)/check-ebcdic
 #	/* shift sequence before invalid multibyte character */
 	./test-shiftseq
 #	/* conversion to wchar_t */
@@ -425,6 +427,7 @@
   TranslitFail1.ISO-8859-1 \
   is-native.c \
   check-subst \
+  check-ebcdic \
   test-shiftseq.c \
   test-to-wchar.c \
   CP856.TXT \
diff --git a/tests/check-ebcdic b/tests/check-ebcdic
new file mode 100755
index 0000000..62dfd61
--- /dev/null
+++ b/tests/check-ebcdic
@@ -0,0 +1,67 @@
+#!/bin/sh
+# Check of ICONV_EBCDIC_ZOS_UNIX environment variable.
+set -e
+iconv=../src/iconv_no_i18n
+
+# This test is only meaningful when the EBCDIC encodings are included.
+if $iconv -l | grep IBM-1047 > /dev/null; then
+
+  printf 'hello\n' > tmp-ok-lf
+  printf 'hello\302\205' > tmp-ok-nel
+
+  printf '\210\205\223\223\226\025' > tmp-ok-x15
+  printf '\210\205\223\223\226\045' > tmp-ok-x25
+
+  # Check that by default, EBCDIC 0x15 maps to U+0085.
+  unset ICONV_EBCDIC_ZOS_UNIX
+
+  $iconv -f UTF-8 -t IBM-1047 < tmp-ok-nel > tmp-out1
+  $iconv -f ASCII -t IBM-1047 < tmp-ok-lf > tmp-out2
+  cmp tmp-out1 tmp-ok-x15
+  cmp tmp-out2 tmp-ok-x25
+
+  $iconv -f IBM-1047 -t UTF-8 < tmp-ok-x15 > tmp-out1
+  $iconv -f IBM-1047 -t ASCII < tmp-ok-x25 > tmp-out2
+  cmp tmp-out1 tmp-ok-nel
+  cmp tmp-out2 tmp-ok-lf
+
+  # Check that with the ZOS_UNIX surface, EBCDIC 0x15 maps to U+000A.
+
+  $iconv -f ASCII -t IBM-1047/ZOS_UNIX < tmp-ok-lf > tmp-out1
+  $iconv -f UTF-8 -t IBM-1047/ZOS_UNIX < tmp-ok-nel > tmp-out2
+  cmp tmp-out1 tmp-ok-x15
+  cmp tmp-out2 tmp-ok-x25
+
+  $iconv -f IBM-1047/ZOS_UNIX -t ASCII < tmp-ok-x15 > tmp-out1
+  $iconv -f IBM-1047/ZOS_UNIX -t UTF-8 < tmp-ok-x25 > tmp-out2
+  cmp tmp-out1 tmp-ok-lf
+  cmp tmp-out2 tmp-ok-nel
+
+  # Check that the ZOS_UNIX surface can be used with //TRANSLIT and //IGNORE.
+
+  printf '\357\275\210\342\204\257\360\235\232\225\360\235\232\225\342\200\242\n' \
+    | $iconv -f UTF-8 -t IBM-1047/ZOS_UNIX/TRANSLIT > tmp-out1
+  cmp tmp-out1 tmp-ok-x15
+
+  printf 'hello\342\202\254\n' \
+    | $iconv -f UTF-8 -t IBM-1047/ZOS_UNIX/IGNORE > tmp-out1
+  cmp tmp-out1 tmp-ok-x15
+
+  # Check that with a specific environment variable, EBCDIC 0x15 maps to U+000A.
+  ICONV_EBCDIC_ZOS_UNIX=1
+  export ICONV_EBCDIC_ZOS_UNIX
+
+  $iconv -f ASCII -t IBM-1047 < tmp-ok-lf > tmp-out1
+  $iconv -f UTF-8 -t IBM-1047 < tmp-ok-nel > tmp-out2
+  cmp tmp-out1 tmp-ok-x15
+  cmp tmp-out2 tmp-ok-x25
+
+  $iconv -f IBM-1047 -t ASCII < tmp-ok-x15 > tmp-out1
+  $iconv -f IBM-1047 -t UTF-8 < tmp-ok-x25 > tmp-out2
+  cmp tmp-out1 tmp-ok-lf
+  cmp tmp-out2 tmp-ok-nel
+
+  rm -f tmp-in* tmp-out* tmp-ok*
+fi
+
+exit 0