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
18#include "apr.h"
19#include "testutil.h"
20#include "apr_general.h"
21#include "apr_pools.h"
22#include "apr_errno.h"
23#include "apr_dso.h"
24#include "apr_strings.h"
25#include "apr_file_info.h"
26#if APR_HAVE_UNISTD_H
27#include <unistd.h>
28#endif
29
30#if APR_HAS_DSO
31
32#ifdef NETWARE
33# define MOD_NAME "mod_test.nlm"
34#elif defined(BEOS) || defined(__MVS__)
35# define MOD_NAME "mod_test.so"
36#elif defined(WIN32)
37# define MOD_NAME TESTBINPATH "mod_test.dll"
38#elif defined(DARWIN)
39# define MOD_NAME ".libs/mod_test.so"
40# define LIB_NAME ".libs/libmod_test.dylib"
41#elif (defined(__hpux__) || defined(__hpux)) && !defined(__ia64)
42# define MOD_NAME ".libs/mod_test.sl"
43# define LIB_NAME ".libs/libmod_test.sl"
44#elif defined(_AIX) || defined(__bsdi__)
45# define MOD_NAME ".libs/libmod_test.so"
46# define LIB_NAME ".libs/libmod_test.so"
47#else /* Every other Unix */
48# define MOD_NAME ".libs/mod_test.so"
49# define LIB_NAME ".libs/libmod_test.so"
50#endif
51
52static char *modname;
53
54static void test_load_module(abts_case *tc, void *data)
55{
56    apr_dso_handle_t *h = NULL;
57    apr_status_t status;
58    char errstr[256];
59
60    status = apr_dso_load(&h, modname, p);
61    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
62    ABTS_PTR_NOTNULL(tc, h);
63
64    apr_dso_unload(h);
65}
66
67static void test_dso_sym(abts_case *tc, void *data)
68{
69    apr_dso_handle_t *h = NULL;
70    apr_dso_handle_sym_t func1 = NULL;
71    apr_status_t status;
72    void (*function)(char str[256]);
73    char teststr[256];
74    char errstr[256];
75
76    status = apr_dso_load(&h, modname, p);
77    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
78    ABTS_PTR_NOTNULL(tc, h);
79
80    status = apr_dso_sym(&func1, h, "print_hello");
81    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
82    ABTS_PTR_NOTNULL(tc, func1);
83
84    if (!tc->failed) {
85        function = (void (*)(char *))func1;
86        (*function)(teststr);
87        ABTS_STR_EQUAL(tc, "Hello - I'm a DSO!\n", teststr);
88    }
89
90    apr_dso_unload(h);
91}
92
93static void test_dso_sym_return_value(abts_case *tc, void *data)
94{
95    apr_dso_handle_t *h = NULL;
96    apr_dso_handle_sym_t func1 = NULL;
97    apr_status_t status;
98    int (*function)(int);
99    char errstr[256];
100
101    status = apr_dso_load(&h, modname, p);
102    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
103    ABTS_PTR_NOTNULL(tc, h);
104
105    status = apr_dso_sym(&func1, h, "count_reps");
106    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
107    ABTS_PTR_NOTNULL(tc, func1);
108
109    if (!tc->failed) {
110        function = (int (*)(int))func1;
111        status = (*function)(5);
112        ABTS_INT_EQUAL(tc, 5, status);
113    }
114
115    apr_dso_unload(h);
116}
117
118static void test_unload_module(abts_case *tc, void *data)
119{
120    apr_dso_handle_t *h = NULL;
121    apr_status_t status;
122    char errstr[256];
123    apr_dso_handle_sym_t func1 = NULL;
124
125    status = apr_dso_load(&h, modname, p);
126    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
127    ABTS_PTR_NOTNULL(tc, h);
128
129    status = apr_dso_unload(h);
130    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
131
132    status = apr_dso_sym(&func1, h, "print_hello");
133    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ESYMNOTFOUND(status));
134}
135
136
137#ifdef LIB_NAME
138static char *libname;
139
140static void test_load_library(abts_case *tc, void *data)
141{
142    apr_dso_handle_t *h = NULL;
143    apr_status_t status;
144    char errstr[256];
145
146    status = apr_dso_load(&h, libname, p);
147    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
148    ABTS_PTR_NOTNULL(tc, h);
149
150    apr_dso_unload(h);
151}
152
153static void test_dso_sym_library(abts_case *tc, void *data)
154{
155    apr_dso_handle_t *h = NULL;
156    apr_dso_handle_sym_t func1 = NULL;
157    apr_status_t status;
158    void (*function)(char str[256]);
159    char teststr[256];
160    char errstr[256];
161
162    status = apr_dso_load(&h, libname, p);
163    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
164    ABTS_PTR_NOTNULL(tc, h);
165
166    status = apr_dso_sym(&func1, h, "print_hello");
167    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
168    ABTS_PTR_NOTNULL(tc, func1);
169
170    if (!tc->failed) {
171        function = (void (*)(char *))func1;
172        (*function)(teststr);
173        ABTS_STR_EQUAL(tc, "Hello - I'm a DSO!\n", teststr);
174    }
175
176    apr_dso_unload(h);
177}
178
179static void test_dso_sym_return_value_library(abts_case *tc, void *data)
180{
181    apr_dso_handle_t *h = NULL;
182    apr_dso_handle_sym_t func1 = NULL;
183    apr_status_t status;
184    int (*function)(int);
185    char errstr[256];
186
187    status = apr_dso_load(&h, libname, p);
188    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
189    ABTS_PTR_NOTNULL(tc, h);
190
191    status = apr_dso_sym(&func1, h, "count_reps");
192    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
193    ABTS_PTR_NOTNULL(tc, func1);
194
195    if (!tc->failed) {
196        function = (int (*)(int))func1;
197        status = (*function)(5);
198        ABTS_INT_EQUAL(tc, 5, status);
199    }
200
201    apr_dso_unload(h);
202}
203
204static void test_unload_library(abts_case *tc, void *data)
205{
206    apr_dso_handle_t *h = NULL;
207    apr_status_t status;
208    char errstr[256];
209    apr_dso_handle_sym_t func1 = NULL;
210
211    status = apr_dso_load(&h, libname, p);
212    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
213    ABTS_PTR_NOTNULL(tc, h);
214
215    status = apr_dso_unload(h);
216    ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
217
218    status = apr_dso_sym(&func1, h, "print_hello");
219    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ESYMNOTFOUND(status));
220}
221
222#endif /* def(LIB_NAME) */
223
224static void test_load_notthere(abts_case *tc, void *data)
225{
226    apr_dso_handle_t *h = NULL;
227    apr_status_t status;
228
229    status = apr_dso_load(&h, "No_File.so", p);
230
231    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EDSOOPEN(status));
232    ABTS_PTR_NOTNULL(tc, h);
233}
234
235#endif /* APR_HAS_DSO */
236
237abts_suite *testdso(abts_suite *suite)
238{
239    suite = ADD_SUITE(suite)
240
241#if APR_HAS_DSO
242    apr_filepath_merge(&modname, NULL, MOD_NAME, 0, p);
243
244    abts_run_test(suite, test_load_module, NULL);
245    abts_run_test(suite, test_dso_sym, NULL);
246    abts_run_test(suite, test_dso_sym_return_value, NULL);
247    abts_run_test(suite, test_unload_module, NULL);
248
249#ifdef LIB_NAME
250    apr_filepath_merge(&libname, NULL, LIB_NAME, 0, p);
251
252    abts_run_test(suite, test_load_library, NULL);
253    abts_run_test(suite, test_dso_sym_library, NULL);
254    abts_run_test(suite, test_dso_sym_return_value_library, NULL);
255    abts_run_test(suite, test_unload_library, NULL);
256#endif
257
258    abts_run_test(suite, test_load_notthere, NULL);
259#endif /* APR_HAS_DSO */
260
261    return suite;
262}
263
264