sendfd.C 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * copied from http://code.swtch.com/plan9port/src/0e6ae8ed3276/src/lib9/sendfd.c
  3. * modified
  4. * */
  5. #include <sys/socket.h>
  6. #include <sys/uio.h>
  7. #include <unistd.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #ifndef CMSG_ALIGN
  12. # ifdef __sun__
  13. # define CMSG_ALIGN _CMSG_DATA_ALIGN
  14. # else
  15. # define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
  16. # endif
  17. #endif
  18. #ifndef CMSG_SPACE
  19. # define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+CMSG_ALIGN(len))
  20. #endif
  21. #ifndef CMSG_LEN
  22. # define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+(len))
  23. #endif
  24. int sendfd(int s, int fd, int flags) {
  25. char buf[1];
  26. struct iovec iov;
  27. struct msghdr msg;
  28. struct cmsghdr *cmsg;
  29. int n;
  30. char cms[CMSG_SPACE(sizeof(int))];
  31. buf[0] = 69;
  32. iov.iov_base = buf;
  33. iov.iov_len = 1;
  34. memset(&msg, 0, sizeof msg);
  35. msg.msg_iov = &iov;
  36. msg.msg_iovlen = 1;
  37. msg.msg_control = (caddr_t) cms;
  38. msg.msg_controllen = CMSG_LEN(sizeof(int));
  39. cmsg = CMSG_FIRSTHDR(&msg);
  40. cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  41. cmsg->cmsg_level = SOL_SOCKET;
  42. cmsg->cmsg_type = SCM_RIGHTS;
  43. memmove(CMSG_DATA(cmsg), &fd, sizeof(int));
  44. if ((n = sendmsg(s, &msg, flags)) != (int) iov.iov_len) return -1;
  45. return 0;
  46. }
  47. int recvfd(int s, int flags) {
  48. int n;
  49. int fd;
  50. char buf[1];
  51. struct iovec iov;
  52. struct msghdr msg;
  53. struct cmsghdr *cmsg;
  54. char cms[CMSG_SPACE(sizeof(int))];
  55. iov.iov_base = buf;
  56. iov.iov_len = 1;
  57. memset(&msg, 0, sizeof msg);
  58. msg.msg_name = 0;
  59. msg.msg_namelen = 0;
  60. msg.msg_iov = &iov;
  61. msg.msg_iovlen = 1;
  62. msg.msg_control = (caddr_t) cms;
  63. msg.msg_controllen = sizeof cms;
  64. if ((n = recvmsg(s, &msg, flags)) <= 0) {
  65. //fprintf(stderr,"recvfd(fd=%i): recvmsg() returned %i; errno: %s\n",s,n,strerror(errno));
  66. return -1;
  67. }
  68. cmsg = CMSG_FIRSTHDR(&msg);
  69. if (cmsg == NULL) {
  70. errno = 0;
  71. fprintf(stderr,"recvfd(fd=%i): CMSG_FIRSTHDR(&msg) is NULL; n=%i, val=%i\n",s,n,(int)buf[0]);
  72. return -1;
  73. }
  74. memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
  75. return fd;
  76. }