localedata: dz_BT, bo_CN: convert to UTF-8
[glibc.git] / sysdeps / unix / sysv / linux / tst-process_madvise.c
blob05599b1eec5443e20f9eff9ed7eea7f4591ce60f
1 /* Basic tests for Linux process_madvise.
2 Copyright (C) 2022-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <array_length.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <stdlib.h>
23 #include <support/check.h>
24 #include <support/process_state.h>
25 #include <support/support.h>
26 #include <support/xsocket.h>
27 #include <support/xunistd.h>
28 #include <sys/mman.h>
29 #include <sys/pidfd.h>
30 #include <sys/wait.h>
32 /* The pair of sockets used for coordination. The subprocess uses
33 sockets[1]. */
34 static int sockets[2];
36 static long int page_size;
38 static void
39 exit_subprocess (int dummy)
41 exit (EXIT_FAILURE);
44 static void
45 subprocess (void)
47 /* In case something goes wrong with parent before pidfd_send_signal. */
48 support_create_timer (5, 0, false, exit_subprocess);
50 void *p1 = xmmap (NULL, page_size * 2, PROT_READ | PROT_WRITE,
51 MAP_PRIVATE | MAP_ANONYMOUS, -1);
53 void *p2 = xmmap (NULL, page_size, PROT_READ | PROT_WRITE,
54 MAP_PRIVATE | MAP_ANONYMOUS, -1);
55 xmunmap(p2, page_size);
57 xsendto (sockets[1], &(struct iovec) { p1, page_size * 2 },
58 sizeof (struct iovec), 0, NULL, 0);
60 xsendto (sockets[1], &(struct iovec) { p2, page_size },
61 sizeof (struct iovec), 0, NULL, 0);
63 pause ();
65 _exit (0);
68 static int
69 do_test (void)
71 page_size = sysconf (_SC_PAGE_SIZE);
74 int r = pidfd_open (-1, 0);
75 TEST_COMPARE (r, -1);
76 if (errno == ENOSYS)
77 FAIL_UNSUPPORTED ("kernel does not support pidfd_open, skipping test");
79 TEST_COMPARE (errno, EINVAL);
82 TEST_COMPARE (socketpair (AF_UNIX, SOCK_STREAM, 0, sockets), 0);
84 pid_t pid = xfork ();
85 if (pid == 0)
87 xclose (sockets[0]);
88 subprocess ();
90 xclose (sockets[1]);
92 int pidfd = pidfd_open (pid, 0);
93 TEST_VERIFY (pidfd != -1);
95 /* The target process is going to send us two iovec's. The first one points
96 to a valid mapping, the other points to a previously valid mapping which
97 has now been unmapped. */
99 struct iovec iv;
100 xrecvfrom (sockets[0], &iv, sizeof (iv), 0, NULL, 0);
102 /* We expect this to succeed in the target process because the mapping
103 is valid. */
104 ssize_t ret = process_madvise (pidfd, &iv, 1, MADV_COLD, 0);
105 if (ret == -1 && errno == ENOSYS)
106 FAIL_UNSUPPORTED ("kernel does not support process_madvise, skipping"
107 "test");
108 TEST_COMPARE (ret, 2 * page_size);
112 struct iovec iv;
113 xrecvfrom (sockets[0], &iv, sizeof (iv), 0, NULL, 0);
115 /* We expect this to fail in the target process because the second iovec
116 points to an unmapped region. The target process arranges for this to
117 be the case. */
118 TEST_COMPARE (process_madvise (pidfd, &iv, 1, MADV_COLD, 0), -1);
119 TEST_COMPARE (errno, ENOMEM);
123 struct iovec iv[IOV_MAX + 1];
124 TEST_COMPARE (process_madvise (pidfd, iv, array_length (iv), MADV_COLD,
125 0), -1);
126 TEST_COMPARE (errno, EINVAL);
129 TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), 0);
131 siginfo_t info;
132 int r = waitid (P_PIDFD, pidfd, &info, WEXITED);
133 TEST_COMPARE (r, 0);
134 TEST_COMPARE (info.si_status, SIGKILL);
135 TEST_COMPARE (info.si_code, CLD_KILLED);
138 TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), -1);
139 TEST_COMPARE (errno, ESRCH);
141 return 0;
144 #include <support/test-driver.c>