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 "apr_thread_proc.h"
18 #include "apr_errno.h"
19 #include "apr_general.h"
20 #include "apr_lib.h"
21 #include "apr_strings.h"
22 #include "testutil.h"
23
24 #define TESTSTR "This is a test"
25
26 #define PROC_CHILD_NAME TESTBINPATH "proc_child" EXTENSION
27
28 static char *proc_child;
29
30 static apr_proc_t newproc;
31
test_create_proc(abts_case * tc,void * data)32 static void test_create_proc(abts_case *tc, void *data)
33 {
34 const char *args[2];
35 apr_procattr_t *attr;
36 apr_file_t *testfile = NULL;
37 apr_status_t rv;
38 apr_size_t length;
39 char *buf;
40
41 rv = apr_procattr_create(&attr, p);
42 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
43
44 rv = apr_procattr_io_set(attr, APR_FULL_BLOCK, APR_FULL_BLOCK,
45 APR_NO_PIPE);
46 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
47
48 rv = apr_procattr_dir_set(attr, "data");
49 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
50
51 rv = apr_procattr_cmdtype_set(attr, APR_PROGRAM_ENV);
52 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
53
54 args[0] = "proc_child" EXTENSION;
55 args[1] = NULL;
56
57 rv = apr_proc_create(&newproc, proc_child, args, NULL,
58 attr, p);
59 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
60
61 testfile = newproc.in;
62
63 length = strlen(TESTSTR);
64 rv = apr_file_write(testfile, TESTSTR, &length);
65 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
66 ABTS_SIZE_EQUAL(tc, strlen(TESTSTR), length);
67
68 testfile = newproc.out;
69 length = 256;
70 buf = apr_pcalloc(p, length);
71 rv = apr_file_read(testfile, buf, &length);
72 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
73 ABTS_STR_EQUAL(tc, TESTSTR, buf);
74 }
75
test_proc_wait(abts_case * tc,void * data)76 static void test_proc_wait(abts_case *tc, void *data)
77 {
78 apr_status_t rv;
79
80 rv = apr_proc_wait(&newproc, NULL, NULL, APR_WAIT);
81 ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv);
82 }
83
test_file_redir(abts_case * tc,void * data)84 static void test_file_redir(abts_case *tc, void *data)
85 {
86 apr_file_t *testout = NULL;
87 apr_file_t *testerr = NULL;
88 apr_off_t offset;
89 apr_status_t rv;
90 const char *args[2];
91 apr_procattr_t *attr;
92 apr_file_t *testfile = NULL;
93 apr_size_t length;
94 char *buf;
95
96 testfile = NULL;
97 rv = apr_file_open(&testfile, "data/stdin",
98 APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL,
99 APR_OS_DEFAULT, p);
100 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
101 rv = apr_file_open(&testout, "data/stdout",
102 APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL,
103 APR_OS_DEFAULT, p);
104 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
105 rv = apr_file_open(&testerr, "data/stderr",
106 APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL,
107 APR_OS_DEFAULT, p);
108 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
109
110 length = strlen(TESTSTR);
111 apr_file_write(testfile, TESTSTR, &length);
112 offset = 0;
113 rv = apr_file_seek(testfile, APR_SET, &offset);
114 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
115 ABTS_ASSERT(tc, "File position mismatch, expected 0", offset == 0);
116
117 rv = apr_procattr_create(&attr, p);
118 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
119 rv = apr_procattr_child_in_set(attr, testfile, NULL);
120 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
121 rv = apr_procattr_child_out_set(attr, testout, NULL);
122 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
123 rv = apr_procattr_child_err_set(attr, testerr, NULL);
124 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
125 rv = apr_procattr_dir_set(attr, "data");
126 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
127 rv = apr_procattr_cmdtype_set(attr, APR_PROGRAM_ENV);
128 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
129
130 args[0] = "proc_child";
131 args[1] = NULL;
132
133 rv = apr_proc_create(&newproc, proc_child, args, NULL,
134 attr, p);
135 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
136
137 rv = apr_proc_wait(&newproc, NULL, NULL, APR_WAIT);
138 ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv);
139
140 offset = 0;
141 rv = apr_file_seek(testout, APR_SET, &offset);
142 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
143
144 length = 256;
145 buf = apr_pcalloc(p, length);
146 rv = apr_file_read(testout, buf, &length);
147 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
148 ABTS_STR_EQUAL(tc, TESTSTR, buf);
149
150
151 apr_file_close(testfile);
152 apr_file_close(testout);
153 apr_file_close(testerr);
154
155 rv = apr_file_remove("data/stdin", p);;
156 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
157 rv = apr_file_remove("data/stdout", p);;
158 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
159 rv = apr_file_remove("data/stderr", p);;
160 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
161 }
162
testproc(abts_suite * suite)163 abts_suite *testproc(abts_suite *suite)
164 {
165 suite = ADD_SUITE(suite)
166
167 apr_filepath_merge(&proc_child, NULL, PROC_CHILD_NAME, 0, p);
168 abts_run_test(suite, test_create_proc, NULL);
169 abts_run_test(suite, test_proc_wait, NULL);
170 abts_run_test(suite, test_file_redir, NULL);
171
172 return suite;
173 }
174
175