I ran into a compilation error a long time ago (not Gnulib related)
because I declared strmode using the mode_t argument unconditionally.
This is an issue because FreeBSD uses int as the first argument and
not mode_t, which is typedef'd to __uint16_t. This test is mostly to
make sure that doesn't happen due to this module. I've added some
basic functionality tests too.

NetBSD fixed that declaration in 1997 [1], FreeBSD did in version
14.0 [2]. OpenBSD still has it declared with an int argument even
though mode_t is a __uint32_t there [3] [4] [5].

Collin

[1] 
https://github.com/NetBSD/src/commit/3664382e532de079a7dc0f9430d55ce2419af50d
[2] 
https://github.com/freebsd/freebsd-src/commit/849dcdb1c0c50b13f97d67c912f0edac82688281
[3] 
https://github.com/openbsd/src/blob/1245b84dd8b155eea7f3aeffc9acb78e7116673b/include/string.h#L131
[4] 
https://github.com/openbsd/src/blob/1245b84dd8b155eea7f3aeffc9acb78e7116673b/sys/sys/_types.h#L54
[5] https://man.openbsd.org/strmode.3
From d8e12a7f5082deaa2e26ca2d908915f3197ba6b1 Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Tue, 18 Jun 2024 21:21:47 -0700
Subject: [PATCH] filemode: Add tests.

* modules/filemode-tests: New file.
* tests/test-filemode.c: New file.
---
 ChangeLog              |  6 ++++
 modules/filemode-tests | 11 ++++++
 tests/test-filemode.c  | 78 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)
 create mode 100644 modules/filemode-tests
 create mode 100644 tests/test-filemode.c

diff --git a/ChangeLog b/ChangeLog
index 988f36b6fc..d7abbaadce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-06-18  Collin Funk  <collin.fu...@gmail.com>
+
+	filemode: Add tests.
+	* modules/filemode-tests: New file.
+	* tests/test-filemode.c: New file.
+
 2024-06-18  Bruno Haible  <br...@clisp.org>
 
 	copysignl tests: Avoid failure on Solaris 11.4.
diff --git a/modules/filemode-tests b/modules/filemode-tests
new file mode 100644
index 0000000000..983bc1e672
--- /dev/null
+++ b/modules/filemode-tests
@@ -0,0 +1,11 @@
+Files:
+tests/test-filemode.c
+tests/macros.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-filemode
+check_PROGRAMS += test-filemode
diff --git a/tests/test-filemode.c b/tests/test-filemode.c
new file mode 100644
index 0000000000..56c2fdc033
--- /dev/null
+++ b/tests/test-filemode.c
@@ -0,0 +1,78 @@
+/* Test the sig2str and str2sig 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 <collin.fu...@gmail.com>, 2024.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "filemode.h"
+
+#include <sys/stat.h>
+
+/* The strmode function is already defined on some systems in <string.h> or
+   <unistd.h>.  On FreeBSD versions 13 and lower the function takes an int
+   instead of a mode_t (uint16_t) as it's first argument.  Include these
+   headers here to make sure our declaration doesn't conflict with system
+   functions.  */
+#include <string.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+struct mode_to_string
+{
+  mode_t mode;
+  char str[12];
+};
+
+static const struct mode_to_string table[] =
+  {
+    { S_IFCHR, "c--------- " },
+    { S_IFDIR, "d--------- " },
+    { S_IFIFO, "p--------- " },
+    { S_IFREG, "---------- " },
+    { S_IFCHR | S_IRUSR | S_IWGRP | S_IXOTH, "cr---w---x " },
+    { S_IFDIR | S_IXUSR | S_IRGRP | S_IWOTH, "d--xr---w- " },
+    { S_IFIFO | S_IWUSR | S_IXGRP | S_IROTH, "p-w---xr-- " },
+#if S_ISUID
+    { S_IFREG | S_ISUID, "---S------ " },
+    { S_IFREG | S_ISUID | S_IXUSR, "---s------ " },
+#endif
+#if S_ISGID
+    { S_IFREG | S_ISGID, "------S--- " },
+    { S_IFREG | S_ISGID | S_IXGRP, "------s--- " },
+#endif
+#if S_ISVTX
+    { S_IFREG | S_ISVTX, "---------T " },
+    { S_IFREG | S_ISVTX | S_IXOTH, "---------t " },
+#endif
+  };
+
+int
+main (void)
+{
+  size_t i;
+  char buffer[12];
+
+  for (i = 0; i < SIZEOF (table); ++i)
+    {
+      strmode (table[i].mode, buffer);
+      ASSERT (STREQ (table[i].str, buffer));
+    }
+
+  return test_exit_status;
+}
-- 
2.45.2

Reply via email to