pass_fd.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 Fhg Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27. #ifdef USE_TCP
  28. #include <sys/types.h>
  29. #include <sys/socket.h>
  30. /* remove this after replacing fprintf*/
  31. #include <stdio.h>
  32. /* at least 1 byte must be sent! */
  33. int send_fd(int unix_socket, void* data, int data_len, int fd)
  34. {
  35. struct msghdr msg;
  36. struct iovec iov[1];
  37. struct cmsghdr* cmsg;
  38. int ret;
  39. union {
  40. struct cmsghdr cm;
  41. char control[CMSG_SPACE(sizeof(fd))];
  42. }control_un;
  43. msg.msg_control=control_un.control;
  44. msg.msg_controllen=sizeof(control_un.control);
  45. msg.msg_name=0;
  46. msg.msg_namelen=0;
  47. iov[0].iov_base=data;
  48. iov[0].iov_len=data_len;
  49. msg.msg_iov=iov;
  50. msg.msg_iovlen=1;
  51. cmsg=CMSG_FIRSTHDR(&msg);
  52. cmsg->cmsg_level = SOL_SOCKET;
  53. cmsg->cmsg_type = SCM_RIGHTS;
  54. cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
  55. *(int*)CMSG_DATA(cmsg)=fd;
  56. msg.msg_flags=0;
  57. ret=sendmsg(unix_socket, &msg, 0);
  58. return ret;
  59. }
  60. int receive_fd(int unix_socket, void* data, int data_len, int* fd)
  61. {
  62. struct msghdr msg;
  63. struct iovec iov[1];
  64. struct cmsghdr* cmsg;
  65. int new_fd;
  66. int ret;
  67. union{
  68. struct cmsghdr cm;
  69. char control[CMSG_SPACE(sizeof(new_fd))];
  70. }control_un;
  71. msg.msg_control=control_un.control;
  72. msg.msg_controllen=sizeof(control_un.control);
  73. msg.msg_name=0;
  74. msg.msg_namelen=0;
  75. iov[0].iov_base=data;
  76. iov[0].iov_len=data_len;
  77. msg.msg_iov=iov;
  78. msg.msg_iovlen=1;
  79. ret=recvmsg(unix_socket, &msg, 0);
  80. if (ret<=0) goto error;
  81. cmsg=CMSG_FIRSTHDR(&msg);
  82. if ((cmsg!=0) && (cmsg->cmsg_len==CMSG_LEN(sizeof(new_fd)))){
  83. if (cmsg->cmsg_type!= SCM_RIGHTS){
  84. fprintf(stderr, " msg control type != SCM_RIGHTS\n");
  85. ret=-1;
  86. goto error;
  87. }
  88. if (cmsg->cmsg_level!= SOL_SOCKET){
  89. fprintf(stderr, " msg level != SOL_SOCKET\n");
  90. ret=-1;
  91. goto error;
  92. }
  93. *fd=*((int*) CMSG_DATA(cmsg));
  94. }else{
  95. fprintf(stderr, " no descriptor passed, cmsg=%p, len=%d\n",
  96. cmsg, cmsg->cmsg_len);
  97. *fd=-1;
  98. /* it's not really an error */
  99. }
  100. error:
  101. return ret;
  102. }
  103. #endif