1 /* Test program for POSIX shm_* functions.
2 Copyright (C) 2000-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
34 /* We want to see output immediately. */
35 #define STDOUT_UNBUFFERED
37 static char shm_test_name
[sizeof "/glibc-shm-test-" + sizeof (pid_t
) * 3];
38 static char shm_escape_name
[sizeof "/../escaped-" + sizeof (pid_t
) * 3];
41 init_shm_test_names (void)
43 snprintf (shm_test_name
, sizeof (shm_test_name
), "/glibc-shm-test-%u",
45 snprintf (shm_escape_name
, sizeof (shm_escape_name
), "/../escaped-%u",
50 worker (int write_now
)
56 int fd
= shm_open (shm_test_name
, O_RDWR
, 0600);
59 error (EXIT_FAILURE
, 0, "failed to open shared memory object: shm_open");
66 if (fstat64 (fd
, &st
) == -1)
67 error (EXIT_FAILURE
, 0, "stat failed");
68 if (st
.st_size
!= 4000)
69 error (EXIT_FAILURE
, 0, "size incorrect");
71 mem
= mmap (NULL
, 4000, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
72 if (mem
== MAP_FAILED
)
73 error (EXIT_FAILURE
, 0, "mmap failed");
76 ts
.tv_nsec
= 500000000;
79 for (i
= 0; i
<= 4; ++i
)
82 /* Wait until the first bytes of the memory region are 0, 1, 2, 3, 4. */
85 for (i
= 0; i
<= 4; ++i
)
90 /* OK, that's done. */
93 nanosleep (&ts
, NULL
);
97 for (i
= 0; i
<= 4; ++i
)
100 /* Wait until the first bytes of the memory region are 4, 5, 6, 7, 8. */
103 for (i
= 0; i
<= 4; ++i
)
108 /* OK, that's done. */
111 nanosleep (&ts
, NULL
);
114 if (munmap (mem
, 4000) == -1)
115 error (EXIT_FAILURE
, errno
, "munmap");
133 init_shm_test_names ();
135 fd
= shm_open (shm_escape_name
, O_RDWR
| O_CREAT
| O_TRUNC
| O_EXCL
, 0600);
138 perror ("read file outside of SHMDIR directory");
143 /* Create the shared memory object. */
144 fd
= shm_open (shm_test_name
, O_RDWR
| O_CREAT
| O_TRUNC
| O_EXCL
, 0600);
147 /* If shm_open is unimplemented we skip the test. */
150 perror ("shm_open unimplemented. Test skipped.");
154 error (EXIT_FAILURE
, 0, "failed to create shared memory object: shm_open");
157 /* Size the object. We make it 4000 bytes long. */
158 if (ftruncate (fd
, 4000) == -1)
160 /* This failed. Must be a bug in the implementation of the
161 shared memory itself. */
162 perror ("failed to size of shared memory object: ftruncate");
164 shm_unlink (shm_test_name
);
168 if (fstat64 (fd
, &st
) == -1)
170 shm_unlink (shm_test_name
);
171 error (EXIT_FAILURE
, 0, "initial stat failed");
173 if (st
.st_size
!= 4000)
175 shm_unlink (shm_test_name
);
176 error (EXIT_FAILURE
, 0, "initial size not correct");
179 /* Spawn to processes which will do the work. */
185 /* Couldn't create a second process. */
188 shm_unlink (shm_test_name
);
197 /* Couldn't create a second process. */
200 kill (pid1
, SIGTERM
);
201 waitpid (pid1
, &ignore
, 0);
203 shm_unlink (shm_test_name
);
207 /* Wait until the two processes are finished. */
208 waitpid (pid1
, &status1
, 0);
209 waitpid (pid2
, &status2
, 0);
211 /* Now we can unlink the shared object. */
212 shm_unlink (shm_test_name
);
214 return (!WIFEXITED (status1
) || WEXITSTATUS (status1
) != 0
215 || !WIFEXITED (status2
) || WEXITSTATUS (status2
) != 0);
219 cleanup_handler (void)
221 shm_unlink (shm_test_name
);
224 #define CLEANUP_HANDLER cleanup_handler
226 #include <support/test-driver.c>