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_thread_proc.h"
19 #include "apr_errno.h"
20 #include "apr_general.h"
21 #include "apr_lib.h"
22 #include "apr_strings.h"
23
24 #if APR_HAS_OTHER_CHILD
25
26 static char reasonstr[256];
27
ocmaint(int reason,void * data,int status)28 static void ocmaint(int reason, void *data, int status)
29 {
30 switch (reason) {
31 case APR_OC_REASON_DEATH:
32 apr_cpystrn(reasonstr, "APR_OC_REASON_DEATH",
33 strlen("APR_OC_REASON_DEATH") + 1);
34 break;
35 case APR_OC_REASON_LOST:
36 apr_cpystrn(reasonstr, "APR_OC_REASON_LOST",
37 strlen("APR_OC_REASON_LOST") + 1);
38 break;
39 case APR_OC_REASON_UNWRITABLE:
40 apr_cpystrn(reasonstr, "APR_OC_REASON_UNWRITEABLE",
41 strlen("APR_OC_REASON_UNWRITEABLE") + 1);
42 break;
43 case APR_OC_REASON_RESTART:
44 apr_cpystrn(reasonstr, "APR_OC_REASON_RESTART",
45 strlen("APR_OC_REASON_RESTART") + 1);
46 break;
47 }
48 }
49
50 #ifndef SIGKILL
51 #define SIGKILL 1
52 #endif
53
54 /* It would be great if we could stress this stuff more, and make the test
55 * more granular.
56 */
test_child_kill(abts_case * tc,void * data)57 static void test_child_kill(abts_case *tc, void *data)
58 {
59 apr_file_t *std = NULL;
60 apr_proc_t newproc;
61 apr_procattr_t *procattr = NULL;
62 const char *args[3];
63 apr_status_t rv;
64
65 args[0] = apr_pstrdup(p, "occhild" EXTENSION);
66 args[1] = apr_pstrdup(p, "-X");
67 args[2] = NULL;
68
69 rv = apr_procattr_create(&procattr, p);
70 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
71
72 rv = apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_NO_PIPE,
73 APR_NO_PIPE);
74 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
75
76 rv = apr_procattr_cmdtype_set(procattr, APR_PROGRAM_ENV);
77 APR_ASSERT_SUCCESS(tc, "Couldn't set copy environment", rv);
78
79 rv = apr_proc_create(&newproc, TESTBINPATH "occhild" EXTENSION, args, NULL, procattr, p);
80 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
81 ABTS_PTR_NOTNULL(tc, newproc.in);
82 ABTS_PTR_EQUAL(tc, NULL, newproc.out);
83 ABTS_PTR_EQUAL(tc, NULL, newproc.err);
84
85 std = newproc.in;
86
87 apr_proc_other_child_register(&newproc, ocmaint, NULL, std, p);
88
89 apr_sleep(apr_time_from_sec(1));
90 rv = apr_proc_kill(&newproc, SIGKILL);
91 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
92
93 /* allow time for things to settle... */
94 apr_sleep(apr_time_from_sec(3));
95
96 apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
97 ABTS_STR_EQUAL(tc, "APR_OC_REASON_DEATH", reasonstr);
98 }
99 #else
100
oc_not_impl(abts_case * tc,void * data)101 static void oc_not_impl(abts_case *tc, void *data)
102 {
103 ABTS_NOT_IMPL(tc, "Other child logic not implemented on this platform");
104 }
105 #endif
106
testoc(abts_suite * suite)107 abts_suite *testoc(abts_suite *suite)
108 {
109 suite = ADD_SUITE(suite)
110
111 #if !APR_HAS_OTHER_CHILD
112 abts_run_test(suite, oc_not_impl, NULL);
113 #else
114
115 abts_run_test(suite, test_child_kill, NULL);
116
117 #endif
118 return suite;
119 }
120
121