Apache HTTPD
testshm.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "testutil.h"
18#include "apr_shm.h"
19#include "apr_errno.h"
20#include "apr_general.h"
21#include "apr_lib.h"
22#include "apr_strings.h"
23#include "apr_thread_proc.h"
24#include "apr_time.h"
25#include "testshm.h"
26#include "apr.h"
27
28#if APR_HAVE_STDLIB_H
29#include <stdlib.h>
30#endif
31
32#if APR_HAS_SHARED_MEMORY
33
34static void test_anon_create(abts_case *tc, void *data)
35{
36 apr_status_t rv;
38
40 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
42
43 rv = apr_shm_destroy(shm);
44 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
45}
46
47static void test_check_size(abts_case *tc, void *data)
48{
49 apr_status_t rv;
52
54 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
56
59
60 rv = apr_shm_destroy(shm);
61 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
62}
63
64static void test_shm_allocate(abts_case *tc, void *data)
65{
66 apr_status_t rv;
68
70 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
72
76
77 rv = apr_shm_destroy(shm);
78 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
79}
80
81#if APR_HAS_FORK
82static void test_anon(abts_case *tc, void *data)
83{
85 apr_status_t rv;
88 int cnt, i;
89 int recvd;
90
92 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
94
97
101
102 rv = apr_proc_fork(&proc, p);
103 if (rv == APR_INCHILD) { /* child */
104 int num = msgwait("anon_test", N_MESSAGES,
105 5, /* wait for 5s */
106 10 /* with 10ms spin delay */);
107 /* exit with the number of messages received so that the parent
108 * can check that all messages were received.
109 */
110 exit(num);
111 }
112 else if (rv == APR_INPARENT) { /* parent */
113 i = N_BOXES;
114 cnt = 0;
115 while (cnt++ < N_MESSAGES) {
116 if ((i-=3) < 0) {
117 i += N_BOXES; /* start over at the top */
118 }
119 if (!msgput("anon_test", i)) {
120 cnt--;
121 }
123 }
124 }
125 else {
126 ABTS_FAIL(tc, "apr_proc_fork failed");
127 }
128 /* wait for the child */
131
132 rv = apr_shm_destroy(shm);
133 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
134}
135#endif
136
137static void test_named(abts_case *tc, void *data)
138{
139 apr_status_t rv;
140 apr_shm_t *shm = NULL;
144 int sent, received;
146 const char *args[4];
147
149
151 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
152 if (rv != APR_SUCCESS) {
153 return;
154 }
156
159
163
166 APR_ASSERT_SUCCESS(tc, "Couldn't create attr1", rv);
167
169 APR_ASSERT_SUCCESS(tc, "Couldn't set copy environment", rv);
170
171 args[0] = apr_pstrdup(p, "testshmproducer" EXTENSION);
172 args[1] = NULL;
173 rv = apr_proc_create(&pidproducer, TESTBINPATH "testshmproducer" EXTENSION, args,
174 NULL, attr1, p);
175 APR_ASSERT_SUCCESS(tc, "Couldn't launch producer", rv);
176
179 APR_ASSERT_SUCCESS(tc, "Couldn't create attr2", rv);
180
182 APR_ASSERT_SUCCESS(tc, "Couldn't set copy environment", rv);
183
184 args[0] = apr_pstrdup(p, "testshmconsumer" EXTENSION);
185 rv = apr_proc_create(&pidconsumer, TESTBINPATH "testshmconsumer" EXTENSION, args,
186 NULL, attr2, p);
187 APR_ASSERT_SUCCESS(tc, "Couldn't launch consumer", rv);
188
192
196
197 /* Cleanup before testing that producer and consumer worked correctly.
198 * This way, if they didn't succeed, we can just run this test again
199 * without having to cleanup manually.
200 */
201 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory",
203
205
206}
207
208static void test_named_remove(abts_case *tc, void *data)
209{
210 apr_status_t rv;
211 apr_shm_t *shm, *shm2;
212
214
216 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
217 if (rv != APR_SUCCESS) {
218 return;
219 }
221
223
224 /* On platforms which acknowledge the removal of the shared resource,
225 * ensure another of the same name may be created after removal;
226 */
227 if (rv == APR_SUCCESS)
228 {
230 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
231 if (rv != APR_SUCCESS) {
232 return;
233 }
235
236 rv = apr_shm_destroy(shm2);
237 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
238 }
239
240 rv = apr_shm_destroy(shm);
241 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
242
243 /* Now ensure no named resource remains which we may attach to */
245 ABTS_TRUE(tc, rv != 0);
246}
247
248static void test_named_delete(abts_case *tc, void *data)
249{
250 apr_status_t rv;
251 apr_shm_t *shm, *shm2;
252
254
256 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
257 if (rv != APR_SUCCESS) {
258 return;
259 }
261
262 rv = apr_shm_delete(shm);
263
264 /* On platforms which acknowledge the removal of the shared resource,
265 * ensure another of the same name may be created after removal;
266 */
267 if (rv == APR_SUCCESS)
268 {
270 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
271 if (rv != APR_SUCCESS) {
272 return;
273 }
275
276 rv = apr_shm_destroy(shm2);
277 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
278 }
279
280 rv = apr_shm_destroy(shm);
281 APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
282
283 /* Now ensure no named resource remains which we may attach to */
285 ABTS_TRUE(tc, rv != 0);
286}
287
288static void test_named_perms(abts_case *tc, void *data)
289{
290 apr_status_t rv;
291 apr_shm_t *shm;
294
296
298 APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
299 if (rv != APR_SUCCESS) {
300 return;
301 }
303
304 rv = apr_uid_current(&uid, &gid, p);
305 APR_ASSERT_SUCCESS(tc, "retrieve current uid/gid", rv);
306 if (rv) return;
307
311
312 if (rv == APR_ENOTIMPL)
313 ABTS_SKIP(tc, data, "apr_shm_perms_set not implemented for named shm");
314 else
315 APR_ASSERT_SUCCESS(tc, "Could not change permissions of shm segment", rv);
316}
317
318#endif
319
321{
322 suite = ADD_SUITE(suite)
323
324#if APR_HAS_SHARED_MEMORY
328#if APR_HAS_FORK
330#endif
331 abts_run_test(suite, test_named, NULL);
335#endif
336
337 return suite;
338}
339
340
void abts_run_test(abts_suite *ts, test_func f, void *value)
Definition abts.c:175
#define ABTS_SIZE_EQUAL(a, b, c)
Definition abts.h:121
#define ABTS_TRUE(a, b)
Definition abts.h:127
#define ADD_SUITE(suite)
Definition abts.h:67
#define ABTS_PTR_NOTNULL(a, b)
Definition abts.h:125
#define ABTS_SKIP(tc, data, msg)
Definition abts.h:135
#define ABTS_INT_EQUAL(a, b, c)
Definition abts.h:109
#define ABTS_FAIL(a, b)
Definition abts.h:128
#define EXTENSION
Definition testutil.h:43
#define TESTBINPATH
Definition testutil.h:35
#define APR_ASSERT_SUCCESS(tc, ctxt, rv)
Definition testutil.h:58
APR Error Codes.
APR Miscellaneous library routines.
APR general purpose library routines.
APR Shared Memory Routines.
APR Strings library.
APR Thread and Process Library.
APR Time Library.
#define APR_CHILD_DONE
Definition apr_errno.h:446
#define APR_INCHILD
Definition apr_errno.h:438
#define APR_INPARENT
Definition apr_errno.h:440
#define APR_ENOTIMPL
Definition apr_errno.h:476
apr_fileperms_t apr_uid_t uid
apr_fileperms_t apr_uid_t apr_gid_t gid
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
#define APR_FPROT_UWRITE
#define APR_FPROT_UREAD
apr_interval_time_t apr_int32_t * num
Definition apr_poll.h:273
apr_shm_t * shm
apr_proc_t * proc
const char const char *const * args
apr_exit_why_e
@ APR_WAIT
@ APR_PROC_EXIT
@ APR_PROGRAM_ENV
#define apr_time_from_msec(msec)
Definition apr_time.h:75
apr_size_t * retsize
Definition apr_time.h:219
gid_t apr_gid_t
Definition apr_user.h:54
uid_t apr_uid_t
Definition apr_user.h:45
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
abts_suite * testshm(abts_suite *suite)
Definition testshm.c:320
#define SHARED_SIZE
Definition testshm.h:35
mbox * boxes
Definition testshm.h:31
#define SHARED_FILENAME
Definition testshm.h:36
#define N_MESSAGES
Definition testshm.h:34
#define N_BOXES
Definition testshm.h:33