read_fd.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* include read_fd */
  2. #include "unp.h"
  3. ssize_t
  4. read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
  5. {
  6. struct msghdr msg;
  7. struct iovec iov[1];
  8. ssize_t n;
  9. #ifdef HAVE_MSGHDR_MSG_CONTROL
  10. union {
  11. struct cmsghdr cm;
  12. char control[CMSG_SPACE(sizeof(int))];
  13. } control_un;
  14. struct cmsghdr *cmptr;
  15. msg.msg_control = control_un.control;
  16. msg.msg_controllen = sizeof(control_un.control);
  17. #else
  18. int newfd;
  19. msg.msg_accrights = (caddr_t) &newfd;
  20. msg.msg_accrightslen = sizeof(int);
  21. #endif
  22. msg.msg_name = NULL;
  23. msg.msg_namelen = 0;
  24. iov[0].iov_base = ptr;
  25. iov[0].iov_len = nbytes;
  26. msg.msg_iov = iov;
  27. msg.msg_iovlen = 1;
  28. if ( (n = recvmsg(fd, &msg, 0)) <= 0)
  29. return(n);
  30. #ifdef HAVE_MSGHDR_MSG_CONTROL
  31. if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
  32. cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
  33. if (cmptr->cmsg_level != SOL_SOCKET)
  34. err_quit("control level != SOL_SOCKET");
  35. if (cmptr->cmsg_type != SCM_RIGHTS)
  36. err_quit("control type != SCM_RIGHTS");
  37. *recvfd = *((int *) CMSG_DATA(cmptr));
  38. } else
  39. *recvfd = -1; /* descriptor was not passed */
  40. #else
  41. /* *INDENT-OFF* */
  42. if (msg.msg_accrightslen == sizeof(int))
  43. *recvfd = newfd;
  44. else
  45. *recvfd = -1; /* descriptor was not passed */
  46. /* *INDENT-ON* */
  47. #endif
  48. return(n);
  49. }
  50. /* end read_fd */
  51. ssize_t
  52. Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
  53. {
  54. ssize_t n;
  55. if ( (n = read_fd(fd, ptr, nbytes, recvfd)) < 0)
  56. err_sys("read_fd error");
  57. return(n);
  58. }