@@ -53,6 +53,7 @@ libsupport-routines = \
support_chroot \
support_copy_file \
support_copy_file_range \
+ support_count_maps \
support_create_timer \
support_descriptor_supports_holes \
support_descriptors \
@@ -319,6 +320,7 @@ tests = \
tst-support-process_state \
tst-support_blob_repeat \
tst-support_capture_subprocess \
+ tst-support_count_maps \
tst-support_descriptors \
tst-support_format_dns_packet \
tst-support_quote_blob \
@@ -96,6 +96,11 @@ int support_descriptor_supports_holes (int fd);
WHY_MSG as part of the diagnostic. */
void support_need_proc (const char *why_msg);
+/* Counts the number of mappings in the process address space.
+ Currently implemented using /proc/self/maps on Linux, so it needs
+ that to exist. */
+size_t support_count_maps (void);
+
/* Error-checking wrapper functions which terminate the process on
error. */
new file mode 100644
@@ -0,0 +1,51 @@
+/* Count the number of mappings.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/support.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+#include <errno.h>
+
+size_t
+support_count_maps (void)
+{
+ FILE *fp = fopen ("/proc/self/maps", "r");
+ if (fp == NULL)
+ {
+ if (errno == ENOENT)
+ FAIL_UNSUPPORTED ("support_count_maps: test needs /proc/self/maps");
+ else
+ FAIL_EXIT1 ("cannot open /proc/self/maps: %m");
+ }
+ size_t count = 0;
+ while (true)
+ {
+ switch (getc_unlocked (fp))
+ {
+ case EOF:
+ /* Error will be reported by xfclose below. */
+ goto out;
+ case '\n':
+ ++count;
+ break;
+ }
+ }
+ out:
+ xfclose (fp);
+ return count;
+}
new file mode 100644
@@ -0,0 +1,52 @@
+/* Test counting the number of mappings.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <support/support.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+#include <sys/mman.h>
+#include <support/xunistd.h>
+
+static int
+do_test (void)
+{
+ long int page_size = xsysconf (_SC_PAGESIZE);
+
+ size_t initial = support_count_maps ();
+ printf ("info: initial number of maps: %zu\n", initial);
+
+ void *ptr = xmmap (NULL, 2 * page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1);
+ size_t one_mapping = support_count_maps ();
+ printf ("info: new number of maps: %zu\n", one_mapping);
+ TEST_COMPARE (initial + 1, one_mapping);
+
+ /* The mapping gets split due to the protection flags change. */
+ xmprotect (ptr, page_size, PROT_READ);
+ size_t two_mappings = support_count_maps ();
+ TEST_COMPARE (initial + 2, two_mappings);
+
+ xmunmap (ptr, 2 * page_size);
+ size_t final = support_count_maps ();
+ TEST_COMPARE (initial, final);
+
+ return 0;
+}
+
+#include <support/test-driver.c>