| /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as | |
| * applicable. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include "testutil.h" | |
| #include "apr_thread_proc.h" | |
| #include "apr_errno.h" | |
| #include "apr_general.h" | |
| #include "apr_lib.h" | |
| #include "apr_strings.h" | |
| #if APR_HAS_OTHER_CHILD | |
| static char reasonstr[256]; | |
| static void ocmaint(int reason, void *data, int status) | |
| { | |
| switch (reason) { | |
| case APR_OC_REASON_DEATH: | |
| apr_cpystrn(reasonstr, "APR_OC_REASON_DEATH", | |
| strlen("APR_OC_REASON_DEATH") + 1); | |
| break; | |
| case APR_OC_REASON_LOST: | |
| apr_cpystrn(reasonstr, "APR_OC_REASON_LOST", | |
| strlen("APR_OC_REASON_LOST") + 1); | |
| break; | |
| case APR_OC_REASON_UNWRITABLE: | |
| apr_cpystrn(reasonstr, "APR_OC_REASON_UNWRITEABLE", | |
| strlen("APR_OC_REASON_UNWRITEABLE") + 1); | |
| break; | |
| case APR_OC_REASON_RESTART: | |
| apr_cpystrn(reasonstr, "APR_OC_REASON_RESTART", | |
| strlen("APR_OC_REASON_RESTART") + 1); | |
| break; | |
| } | |
| } | |
| #ifndef SIGKILL | |
| #define SIGKILL 1 | |
| #endif | |
| /* It would be great if we could stress this stuff more, and make the test | |
| * more granular. | |
| */ | |
| static void test_child_kill(abts_case *tc, void *data) | |
| { | |
| apr_file_t *std = NULL; | |
| apr_proc_t newproc; | |
| apr_procattr_t *procattr = NULL; | |
| const char *args[3]; | |
| apr_status_t rv; | |
| args[0] = apr_pstrdup(p, "occhild" EXTENSION); | |
| args[1] = apr_pstrdup(p, "-X"); | |
| args[2] = NULL; | |
| rv = apr_procattr_create(&procattr, p); | |
| ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); | |
| rv = apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_NO_PIPE, | |
| APR_NO_PIPE); | |
| ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); | |
| rv = apr_proc_create(&newproc, "./occhild" EXTENSION, args, NULL, procattr, p); | |
| ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); | |
| ABTS_PTR_NOTNULL(tc, newproc.in); | |
| ABTS_PTR_EQUAL(tc, NULL, newproc.out); | |
| ABTS_PTR_EQUAL(tc, NULL, newproc.err); | |
| std = newproc.in; | |
| apr_proc_other_child_register(&newproc, ocmaint, NULL, std, p); | |
| apr_sleep(apr_time_from_sec(1)); | |
| rv = apr_proc_kill(&newproc, SIGKILL); | |
| ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); | |
| /* allow time for things to settle... */ | |
| apr_sleep(apr_time_from_sec(3)); | |
| apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING); | |
| ABTS_STR_EQUAL(tc, "APR_OC_REASON_DEATH", reasonstr); | |
| } | |
| #else | |
| static void oc_not_impl(abts_case *tc, void *data) | |
| { | |
| ABTS_NOT_IMPL(tc, "Other child logic not implemented on this platform"); | |
| } | |
| #endif | |
| abts_suite *testoc(abts_suite *suite) | |
| { | |
| suite = ADD_SUITE(suite) | |
| #if !APR_HAS_OTHER_CHILD | |
| abts_run_test(suite, oc_not_impl, NULL); | |
| #else | |
| abts_run_test(suite, test_child_kill, NULL); | |
| #endif | |
| return suite; | |
| } | |