Hi,

I've pushed this patch + tests adding htonl, htons, ntohl, ntohs to
arpa/inet.h. I've just named the module 'htonl' since POSIX documents
these functions under that page [1]. Doing a separate for each seems
excessive. It's all just reusing endian.h anyways.

Collin

[1] https://pubs.opengroup.org/onlinepubs/9799919799/functions/htonl.html

>From e289cd10123c4069c4cb695a7f7bf28e545b791f Mon Sep 17 00:00:00 2001
From: Collin Funk <[email protected]>
Date: Sat, 10 Aug 2024 17:15:07 -0700
Subject: [PATCH 1/2] htonl: New module.

* modules/htonl: New file.
* lib/arpa_inet.c: New file.
* m4/htonl.m4: New file.
* modules/arpa_inet (Files): Add lib/arpa_inet.c.
(Depends-on): Add extern-inline.
* lib/arpa_inet.in.h (htons, htonl, ntohs, ntohl): New declarations.
* m4/arpa_inet_h.m4 (gl_ARPA_INET_H_DEFAULTS): Define REPLACE_HTONL.
* doc/posix-functions/htons.texi (htons): Mention the module.
* doc/posix-functions/htonl.texi (htonl): Likewise.
* doc/posix-functions/ntohs.texi (ntohs): Likewise.
* doc/posix-functions/ntohl.texi (ntohl): Likewise.
---
 ChangeLog                      | 15 ++++++++++
 doc/posix-functions/htonl.texi |  8 ++---
 doc/posix-functions/htons.texi |  8 ++---
 doc/posix-functions/ntohl.texi |  8 ++---
 doc/posix-functions/ntohs.texi |  8 ++---
 lib/arpa_inet.c                | 21 +++++++++++++
 lib/arpa_inet.in.h             | 55 ++++++++++++++++++++++++++++++++++
 m4/arpa_inet_h.m4              |  1 +
 m4/htonl.m4                    | 42 ++++++++++++++++++++++++++
 modules/arpa_inet              |  4 +++
 modules/htonl                  | 26 ++++++++++++++++
 11 files changed, 180 insertions(+), 16 deletions(-)
 create mode 100644 lib/arpa_inet.c
 create mode 100644 m4/htonl.m4
 create mode 100644 modules/htonl

diff --git a/ChangeLog b/ChangeLog
index e31657d97c..111c08d415 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2024-08-10  Collin Funk  <[email protected]>
+
+	htonl: New module.
+	* modules/htonl: New file.
+	* lib/arpa_inet.c: New file.
+	* m4/htonl.m4: New file.
+	* modules/arpa_inet (Files): Add lib/arpa_inet.c.
+	(Depends-on): Add extern-inline.
+	* lib/arpa_inet.in.h (htons, htonl, ntohs, ntohl): New declarations.
+	* m4/arpa_inet_h.m4 (gl_ARPA_INET_H_DEFAULTS): Define REPLACE_HTONL.
+	* doc/posix-functions/htons.texi (htons): Mention the module.
+	* doc/posix-functions/htonl.texi (htonl): Likewise.
+	* doc/posix-functions/ntohs.texi (ntohs): Likewise.
+	* doc/posix-functions/ntohl.texi (ntohl): Likewise.
+
 2024-08-10  Bruno Haible  <[email protected]>
 
 	Make sure gperf-generated files are the same in VPATH builds.
diff --git a/doc/posix-functions/htonl.texi b/doc/posix-functions/htonl.texi
index c3248e6ef0..a4411b4206 100644
--- a/doc/posix-functions/htonl.texi
+++ b/doc/posix-functions/htonl.texi
@@ -4,15 +4,15 @@ @node htonl
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/htonl.html}
 
-Gnulib module: ---
+Gnulib module: htonl
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
diff --git a/doc/posix-functions/htons.texi b/doc/posix-functions/htons.texi
index 3111dee25a..ee413f223f 100644
--- a/doc/posix-functions/htons.texi
+++ b/doc/posix-functions/htons.texi
@@ -4,15 +4,15 @@ @node htons
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/htons.html}
 
-Gnulib module: ---
+Gnulib module: htonl
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
diff --git a/doc/posix-functions/ntohl.texi b/doc/posix-functions/ntohl.texi
index ba5b9560a2..17b6163325 100644
--- a/doc/posix-functions/ntohl.texi
+++ b/doc/posix-functions/ntohl.texi
@@ -4,15 +4,15 @@ @node ntohl
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/ntohl.html}
 
-Gnulib module: ---
+Gnulib module: htonl
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
diff --git a/doc/posix-functions/ntohs.texi b/doc/posix-functions/ntohs.texi
index 4f11eb1856..2fe65fdb6b 100644
--- a/doc/posix-functions/ntohs.texi
+++ b/doc/posix-functions/ntohs.texi
@@ -4,15 +4,15 @@ @node ntohs
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/ntohs.html}
 
-Gnulib module: ---
+Gnulib module: htonl
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-HP-UX 11, mingw, MSVC 14, Android 4.4.
 @end itemize
diff --git a/lib/arpa_inet.c b/lib/arpa_inet.c
new file mode 100644
index 0000000000..589ee9c00f
--- /dev/null
+++ b/lib/arpa_inet.c
@@ -0,0 +1,21 @@
+/* Inline functions for <arpa/inet.h>.
+
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#define _GL_ARPA_INET_INLINE _GL_EXTERN_INLINE
+#include <arpa/inet.h>
diff --git a/lib/arpa_inet.in.h b/lib/arpa_inet.in.h
index b04ff7212b..faaf958443 100644
--- a/lib/arpa_inet.in.h
+++ b/lib/arpa_inet.in.h
@@ -60,6 +60,60 @@
 # include <ws2tcpip.h>
 #endif
 
+#if @REPLACE_HTONL@
+# include <endian.h>
+#endif
+
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GL_ARPA_INET_INLINE
+# define _GL_ARPA_INET_INLINE _GL_INLINE
+#endif
+
+
+#if @REPLACE_HTONL@
+
+/* Make sure we don't have any system definitions.  */
+# undef htons
+# undef htonl
+# undef ntohs
+# undef ntohl
+
+/* Define our own.  */
+# define htons rpl_htons
+# define htonl rpl_htonl
+# define ntohs rpl_ntohs
+# define ntohl rpl_ntohl
+
+/* Host to network byte order. */
+
+_GL_ARPA_INET_INLINE uint16_t
+htons (uint16_t value)
+{
+  return htobe16 (value);
+}
+
+_GL_ARPA_INET_INLINE uint32_t
+htonl (uint32_t value)
+{
+  return htobe32 (value);
+}
+
+/* Network to host byte order.  */
+
+_GL_ARPA_INET_INLINE uint16_t
+ntohs (uint16_t value)
+{
+  return htobe16 (value);
+}
+
+_GL_ARPA_INET_INLINE uint32_t
+ntohl (uint32_t value)
+{
+  return htobe32 (value);
+}
+
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
@@ -150,6 +204,7 @@ _GL_WARN_ON_USE (inet_pton, "inet_pton is unportable - "
 # endif
 #endif
 
+_GL_INLINE_HEADER_END
 
 #endif /* _@GUARD_PREFIX@_ARPA_INET_H */
 #endif /* _@GUARD_PREFIX@_ARPA_INET_H */
diff --git a/m4/arpa_inet_h.m4 b/m4/arpa_inet_h.m4
index 9eac86d7e8..4a2538eaf5 100644
--- a/m4/arpa_inet_h.m4
+++ b/m4/arpa_inet_h.m4
@@ -70,6 +70,7 @@ AC_DEFUN([gl_ARPA_INET_H_DEFAULTS]
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_DECL_INET_NTOP=1;  AC_SUBST([HAVE_DECL_INET_NTOP])
   HAVE_DECL_INET_PTON=1;  AC_SUBST([HAVE_DECL_INET_PTON])
+  REPLACE_HTONL=0;        AC_SUBST([REPLACE_HTONL])
   REPLACE_INET_NTOP=0;    AC_SUBST([REPLACE_INET_NTOP])
   REPLACE_INET_PTON=0;    AC_SUBST([REPLACE_INET_PTON])
 ])
diff --git a/m4/htonl.m4 b/m4/htonl.m4
new file mode 100644
index 0000000000..aee4f272c7
--- /dev/null
+++ b/m4/htonl.m4
@@ -0,0 +1,42 @@
+# htonl.m4
+# serial 1
+dnl Copyright (C) 2024 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Collin Funk.
+
+AC_DEFUN([gl_FUNC_HTONL],
+[
+  AC_REQUIRE([gl_ARPA_INET_H_DEFAULTS])
+
+  if test $ac_cv_header_arpa_inet_h = yes; then
+    AC_CACHE_CHECK([if arpa/inet.h defines htonl, htons, ntohl, ntohs],
+      [gl_cv_func_htonl_working],
+      [gl_cv_func_htonl_working=no
+       AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+[[
+#include <arpa/inet.h>
+]],
+[[
+/* Host to network.  */
+int network_1 = htons (0.0);
+int network_2 = htonl (0.0);
+
+/* Network to host.  */
+int host_1 = ntohs (0.0);
+int host_2 = ntohl (0.0);
+
+/* Make sure the variables get used.  */
+return !(network_1 + network_2 + host_1 + host_2);
+]])],
+         [gl_cv_func_htonl_working=yes],
+         [gl_cv_func_htonl_working=no])
+      ])
+    if test $gl_cv_func_htonl_working = no; then
+      REPLACE_HTONL=1
+    fi
+  fi
+])
diff --git a/modules/arpa_inet b/modules/arpa_inet
index 3a6fd69561..3134c70651 100644
--- a/modules/arpa_inet
+++ b/modules/arpa_inet
@@ -3,11 +3,13 @@ A GNU-like <arpa/inet.h>.
 
 Files:
 lib/arpa_inet.in.h
+lib/arpa_inet.c
 m4/arpa_inet_h.m4
 m4/sys_socket_h.m4
 m4/socklen.m4
 
 Depends-on:
+extern-inline
 gen-header
 include_next
 snippet/arg-nonnull
@@ -22,6 +24,7 @@ AC_PROG_MKDIR_P
 
 Makefile.am:
 BUILT_SOURCES += arpa/inet.h
+lib_SOURCES += arpa_inet.c
 
 # We need the following in order to create <arpa/inet.h> when the system
 # doesn't have one.
@@ -40,6 +43,7 @@ arpa/inet.h: arpa_inet.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON
 	      -e 's|@''HAVE_WS2TCPIP_H''@|$(HAVE_WS2TCPIP_H)|g' \
 	      -e 's|@''HAVE_DECL_INET_NTOP''@|$(HAVE_DECL_INET_NTOP)|g' \
 	      -e 's|@''HAVE_DECL_INET_PTON''@|$(HAVE_DECL_INET_PTON)|g' \
+	      -e 's|@''REPLACE_HTONL''@|$(REPLACE_HTONL)|g' \
 	      -e 's|@''REPLACE_INET_NTOP''@|$(REPLACE_INET_NTOP)|g' \
 	      -e 's|@''REPLACE_INET_PTON''@|$(REPLACE_INET_PTON)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
diff --git a/modules/htonl b/modules/htonl
new file mode 100644
index 0000000000..cb393e094b
--- /dev/null
+++ b/modules/htonl
@@ -0,0 +1,26 @@
+Description:
+htonl, htons, ntohl, ntohs functions: convert between network and host
+byte order
+
+Files:
+m4/htonl.m4
+
+Depends-on:
+arpa_inet
+endian                  [test $REPLACE_HTONL = 1]
+
+configure.ac:
+gl_FUNC_HTONL
+
+Makefile.am:
+
+Include:
+<arpa/inet.h>
+
+Link:
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-- 
2.46.0

>From c341a871800bb04ff9b80582aa053e87e496aca9 Mon Sep 17 00:00:00 2001
From: Collin Funk <[email protected]>
Date: Sat, 10 Aug 2024 17:16:45 -0700
Subject: [PATCH 2/2] htonl: Add tests.

* modules/htonl-tests: New file.
* tests/test-htonl.c: New file.
---
 ChangeLog           |   4 ++
 modules/htonl-tests |  13 ++++++
 tests/test-htonl.c  | 104 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 modules/htonl-tests
 create mode 100644 tests/test-htonl.c

diff --git a/ChangeLog b/ChangeLog
index 111c08d415..5938c70ea9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2024-08-10  Collin Funk  <[email protected]>
 
+	htonl: Add tests.
+	* modules/htonl-tests: New file.
+	* tests/test-htonl.c: New file.
+
 	htonl: New module.
 	* modules/htonl: New file.
 	* lib/arpa_inet.c: New file.
diff --git a/modules/htonl-tests b/modules/htonl-tests
new file mode 100644
index 0000000000..c745b48838
--- /dev/null
+++ b/modules/htonl-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-htonl.c
+tests/macros.h
+
+Depends-on:
+endian
+stdint
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-htonl
+check_PROGRAMS += test-htonl
diff --git a/tests/test-htonl.c b/tests/test-htonl.c
new file mode 100644
index 0000000000..f360fb82e7
--- /dev/null
+++ b/tests/test-htonl.c
@@ -0,0 +1,104 @@
+/* Test of host and network byte order conversion functions.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Collin Funk <[email protected]>, 2024.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <arpa/inet.h>
+
+#include <endian.h>
+#include <stdint.h>
+
+#include "macros.h"
+
+/* Test byte order conversion functions with constant values.  */
+static void
+test_convert_constant (void)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  /* 16-bit.  */
+  ASSERT (htons (UINT16_C (0x1234)) == UINT16_C (0x1234));
+  ASSERT (ntohs (UINT16_C (0x1234)) == UINT16_C (0x1234));
+
+  /* 32-bit.  */
+  ASSERT (htonl (UINT32_C (0x12345678)) == UINT32_C (0x12345678));
+  ASSERT (ntohl (UINT32_C (0x12345678)) == UINT32_C (0x12345678));
+#else
+  /* 16-bit.  */
+  ASSERT (htons (UINT16_C (0x1234)) == UINT16_C (0x3412));
+  ASSERT (ntohs (UINT16_C (0x1234)) == UINT16_C (0x3412));
+
+  /* 32-bit.  */
+  ASSERT (htonl (UINT32_C (0x12345678)) == UINT32_C (0x78563412));
+  ASSERT (ntohl (UINT32_C (0x12345678)) == UINT32_C (0x78563412));
+#endif
+}
+
+/* Test that the byte order conversion functions evaluate their
+   arguments once.  */
+static void
+test_convert_eval_once (void)
+{
+  /* 16-bit.  */
+  {
+    uint16_t value = 0;
+    ASSERT (htons (value++) == 0);
+    ASSERT (value == 1);
+  }
+  {
+    uint16_t value = 0;
+    ASSERT (ntohs (value++) == 0);
+    ASSERT (value == 1);
+  }
+
+  /* 32-bit.  */
+  {
+    uint32_t value = 0;
+    ASSERT (htonl (value++) == 0);
+    ASSERT (value == 1);
+  }
+  {
+    uint32_t value = 0;
+    ASSERT (ntohl (value++) == 0);
+    ASSERT (value == 1);
+  }
+}
+
+/* Test that the byte order conversion functions accept floating-point
+   arguments.  */
+static void
+test_convert_double (void)
+{
+  /* 16-bit.  */
+  ASSERT (htons (0.0) == 0);
+  ASSERT (ntohs (0.0) == 0);
+
+  /* 32-bit.  */
+  ASSERT (htonl (0.0) == 0);
+  ASSERT (ntohs (0.0) == 0);
+}
+
+int
+main (void)
+{
+  test_convert_constant ();
+  test_convert_eval_once ();
+  test_convert_double ();
+
+  return test_exit_status;
+}
-- 
2.46.0

Reply via email to