Handle stdout from CGI child. Duplicate of logic from the _read * method of the real APR pipe bucket implementation. */
| 308 | /* Handle stdout from CGI child. Duplicate of logic from the _read |
| 309 | * method of the real APR pipe bucket implementation. */ |
| 310 | static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, |
| 311 | const char **str, apr_size_t *len) |
| 312 | { |
| 313 | char *buf; |
| 314 | apr_status_t rv; |
| 315 | |
| 316 | *str = NULL; |
| 317 | *len = APR_BUCKET_BUFF_SIZE; |
| 318 | buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ |
| 319 | |
| 320 | rv = apr_file_read(out, buf, len); |
| 321 | |
| 322 | if (rv != APR_SUCCESS && rv != APR_EOF) { |
| 323 | apr_bucket_free(buf); |
| 324 | return rv; |
| 325 | } |
| 326 | |
| 327 | if (*len > 0) { |
| 328 | struct cgi_bucket_data *data = a->data; |
| 329 | apr_bucket_heap *h; |
| 330 | |
| 331 | /* Change the current bucket to refer to what we read */ |
| 332 | a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); |
| 333 | h = a->data; |
| 334 | h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ |
| 335 | *str = buf; |
| 336 | APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); |
| 337 | } |
| 338 | else { |
| 339 | apr_bucket_free(buf); |
| 340 | a = apr_bucket_immortal_make(a, "", 0); |
| 341 | *str = a->data; |
| 342 | } |
| 343 | return rv; |
| 344 | } |
| 345 | |
| 346 | /* Read method of CGI bucket: polls on stderr and stdout of the child, |
| 347 | * sending any stderr output immediately away to the error log. */ |
no test coverage detected