| 443 | } |
| 444 | |
| 445 | static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count, ...) |
| 446 | { |
| 447 | va_list ap; |
| 448 | int rc; |
| 449 | struct iovec *vec; |
| 450 | int i; |
| 451 | |
| 452 | vec = (struct iovec *)apr_palloc(r->pool, count * sizeof(struct iovec)); |
| 453 | va_start(ap, count); |
| 454 | for (i = 0; i < count; i++) { |
| 455 | vec[i].iov_base = va_arg(ap, caddr_t); |
| 456 | vec[i].iov_len = va_arg(ap, apr_size_t); |
| 457 | } |
| 458 | va_end(ap); |
| 459 | |
| 460 | #ifndef HAVE_CGID_FDPASSING |
| 461 | do { |
| 462 | rc = writev(fd, vec, count); |
| 463 | } while (rc < 0 && errno == EINTR); |
| 464 | #else |
| 465 | { |
| 466 | struct msghdr msg = { 0 }; |
| 467 | struct cmsghdr *cmsg; |
| 468 | union { /* union for alignment */ |
| 469 | char buf[CMSG_SPACE(sizeof(int))]; |
| 470 | struct cmsghdr align; |
| 471 | } u; |
| 472 | |
| 473 | msg.msg_iov = vec; |
| 474 | msg.msg_iovlen = count; |
| 475 | |
| 476 | if (auxfd) { |
| 477 | msg.msg_control = u.buf; |
| 478 | msg.msg_controllen = sizeof(u.buf); |
| 479 | |
| 480 | cmsg = CMSG_FIRSTHDR(&msg); |
| 481 | cmsg->cmsg_level = SOL_SOCKET; |
| 482 | cmsg->cmsg_type = SCM_RIGHTS; |
| 483 | cmsg->cmsg_len = CMSG_LEN(sizeof(int)); |
| 484 | *((int *) CMSG_DATA(cmsg)) = auxfd; |
| 485 | } |
| 486 | |
| 487 | do { |
| 488 | rc = sendmsg(fd, &msg, 0); |
| 489 | } while (rc < 0 && errno == EINTR); |
| 490 | } |
| 491 | #endif |
| 492 | |
| 493 | if (rc < 0) { |
| 494 | return errno; |
| 495 | } |
| 496 | |
| 497 | return APR_SUCCESS; |
| 498 | } |
| 499 | |
| 500 | static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, |
| 501 | int *errfd, cgid_req_t *req) |