1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | #include "apr.h" |
18 | #include "apr_arch_misc.h" |
19 | #include "apr_arch_threadproc.h" |
20 | #include "apr_arch_file_io.h" |
21 | |
22 | #if APR_HAS_OTHER_CHILD1 |
23 | |
24 | #ifdef HAVE_TIME_H1 |
25 | #include <sys/time.h> |
26 | #endif |
27 | #ifdef HAVE_SYS_SELECT_H1 |
28 | #include <sys/select.h> |
29 | #endif |
30 | #if APR_HAVE_SYS_WAIT_H1 |
31 | #include <sys/wait.h> |
32 | #endif |
33 | #ifdef BEOS |
34 | #include <sys/socket.h> /* for fd_set definition! */ |
35 | #endif |
36 | |
37 | static apr_other_child_rec_t *other_children = NULL((void*)0); |
38 | |
39 | static apr_status_t other_child_cleanup(void *data) |
40 | { |
41 | apr_other_child_rec_t **pocr, *nocr; |
42 | |
43 | for (pocr = &other_children; *pocr; pocr = &(*pocr)->next) { |
44 | if ((*pocr)->data == data) { |
45 | nocr = (*pocr)->next; |
46 | (*(*pocr)->maintenance) (APR_OC_REASON_UNREGISTER3, (*pocr)->data, -1); |
47 | *pocr = nocr; |
48 | |
49 | return APR_SUCCESS0; |
50 | } |
51 | } |
52 | return APR_SUCCESS0; |
53 | } |
54 | |
55 | APR_DECLARE(void)void apr_proc_other_child_register(apr_proc_t *proc, |
56 | void (*maintenance) (int reason, void *, int status), |
57 | void *data, apr_file_t *write_fd, apr_pool_t *p) |
58 | { |
59 | apr_other_child_rec_t *ocr; |
60 | |
61 | ocr = apr_palloc(p, sizeof(*ocr)); |
62 | ocr->p = p; |
63 | ocr->proc = proc; |
64 | ocr->maintenance = maintenance; |
65 | ocr->data = data; |
66 | if (write_fd == NULL((void*)0)) { |
67 | ocr->write_fd = (apr_os_file_t) -1; |
68 | } |
69 | else { |
70 | #ifdef WIN32 |
71 | |
72 | |
73 | |
74 | ocr->write_fd = write_fd->filehand; |
75 | #else |
76 | ocr->write_fd = write_fd->filedes; |
77 | #endif |
78 | |
79 | } |
80 | ocr->next = other_children; |
81 | other_children = ocr; |
82 | apr_pool_cleanup_register(p, ocr->data, other_child_cleanup, |
83 | apr_pool_cleanup_null); |
84 | } |
85 | |
86 | APR_DECLARE(void)void apr_proc_other_child_unregister(void *data) |
87 | { |
88 | apr_other_child_rec_t *cur; |
89 | |
90 | cur = other_children; |
| |
91 | while (cur) { |
| 2 | | Assuming pointer value is null | |
|
| 3 | | Loop condition is false. Execution continues on line 99 | |
|
92 | if (cur->data == data) { |
93 | break; |
94 | } |
95 | cur = cur->next; |
96 | } |
97 | |
98 | |
99 | apr_pool_cleanup_kill(cur->p, cur->data, other_child_cleanup); |
| 4 | | Access to field 'p' results in a dereference of a null pointer (loaded from variable 'cur') |
|
100 | other_child_cleanup(data); |
101 | } |
102 | |
103 | APR_DECLARE(apr_status_t)apr_status_t apr_proc_other_child_alert(apr_proc_t *proc, |
104 | int reason, |
105 | int status) |
106 | { |
107 | apr_other_child_rec_t *ocr, *nocr; |
108 | |
109 | for (ocr = other_children; ocr; ocr = nocr) { |
110 | nocr = ocr->next; |
111 | if (ocr->proc->pid != proc->pid) |
112 | continue; |
113 | |
114 | ocr->proc = NULL((void*)0); |
115 | (*ocr->maintenance) (reason, ocr->data, status); |
116 | return APR_SUCCESS0; |
117 | } |
118 | return APR_EPROC_UNKNOWN(20000 + 27); |
119 | } |
120 | |
121 | APR_DECLARE(void)void apr_proc_other_child_refresh(apr_other_child_rec_t *ocr, |
122 | int reason) |
123 | { |
124 | |
125 | |
126 | |
127 | #ifdef WIN32 |
128 | DWORD status; |
129 | |
130 | if (ocr->proc == NULL((void*)0)) |
131 | return; |
132 | |
133 | if (!ocr->proc->hproc) { |
134 | |
135 | |
136 | |
137 | ocr->proc = NULL((void*)0); |
138 | (*ocr->maintenance) (APR_OC_REASON_LOST4, ocr->data, -1); |
139 | } |
140 | else if (!GetExitCodeProcess(ocr->proc->hproc, &status)) { |
141 | CloseHandle(ocr->proc->hproc); |
142 | ocr->proc->hproc = NULL((void*)0); |
143 | ocr->proc = NULL((void*)0); |
144 | (*ocr->maintenance) (APR_OC_REASON_LOST4, ocr->data, -1); |
145 | } |
146 | else if (status == STILL_ACTIVE) { |
147 | (*ocr->maintenance) (reason, ocr->data, -1); |
148 | } |
149 | else { |
150 | CloseHandle(ocr->proc->hproc); |
151 | ocr->proc->hproc = NULL((void*)0); |
152 | ocr->proc = NULL((void*)0); |
153 | (*ocr->maintenance) (APR_OC_REASON_DEATH0, ocr->data, status); |
154 | } |
155 | |
156 | #else /* ndef Win32 */ |
157 | pid_t waitret; |
158 | int status; |
159 | |
160 | if (ocr->proc == NULL((void*)0)) |
161 | return; |
162 | |
163 | waitret = waitpid(ocr->proc->pid, &status, WNOHANG1); |
164 | if (waitret == ocr->proc->pid) { |
165 | ocr->proc = NULL((void*)0); |
166 | (*ocr->maintenance) (APR_OC_REASON_DEATH0, ocr->data, status); |
167 | } |
168 | else if (waitret == 0) { |
169 | (*ocr->maintenance) (reason, ocr->data, -1); |
170 | } |
171 | else if (waitret == -1) { |
172 | |
173 | ocr->proc = NULL((void*)0); |
174 | (*ocr->maintenance) (APR_OC_REASON_LOST4, ocr->data, -1); |
175 | } |
176 | #endif |
177 | } |
178 | |
179 | APR_DECLARE(void)void apr_proc_other_child_refresh_all(int reason) |
180 | { |
181 | apr_other_child_rec_t *ocr, *next_ocr; |
182 | |
183 | for (ocr = other_children; ocr; ocr = next_ocr) { |
184 | next_ocr = ocr->next; |
185 | apr_proc_other_child_refresh(ocr, reason); |
186 | } |
187 | } |
188 | |
189 | #else /* !APR_HAS_OTHER_CHILD */ |
190 | |
191 | APR_DECLARE(void)void apr_proc_other_child_register(apr_proc_t *proc, |
192 | void (*maintenance) (int reason, void *, int status), |
193 | void *data, apr_file_t *write_fd, apr_pool_t *p) |
194 | { |
195 | return; |
196 | } |
197 | |
198 | APR_DECLARE(void)void apr_proc_other_child_unregister(void *data) |
199 | { |
200 | return; |
201 | } |
202 | |
203 | APR_DECLARE(apr_status_t)apr_status_t apr_proc_other_child_alert(apr_proc_t *proc, |
204 | int reason, |
205 | int status) |
206 | { |
207 | return APR_ENOTIMPL((20000 + 50000) + 23); |
208 | } |
209 | |
210 | APR_DECLARE(void)void apr_proc_other_child_refresh(apr_other_child_rec_t *ocr, |
211 | int reason) |
212 | { |
213 | return; |
214 | } |
215 | |
216 | APR_DECLARE(void)void apr_proc_other_child_refresh_all(int reason) |
217 | { |
218 | return; |
219 | } |
220 | |
221 | #endif /* APR_HAS_OTHER_CHILD */ |