skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

ancil_send_fd.c (1012B)


      1 /* ISC license. */
      2 
      3 #include <skalibs/nonposix.h>
      4 
      5 #include <errno.h>
      6 #include <string.h>
      7 #include <sys/uio.h>
      8 #include <sys/socket.h>
      9 
     10 #include <skalibs/ancil.h>
     11 #include <skalibs/posixishard.h>
     12 
     13 union aligner_u
     14 {
     15   struct cmsghdr cmsghdr ;
     16   int i ;
     17 } ;
     18 
     19 int ancil_send_fd (int sock, int fd, char ch)
     20 {
     21   ssize_t r ;
     22   struct iovec v = { .iov_base = &ch, .iov_len = 1 } ;
     23   union aligner_u ancilbuf[1 + (CMSG_SPACE(sizeof(int)) - 1) / sizeof(union aligner_u)] ;
     24   struct msghdr hdr =
     25   {
     26     .msg_name = 0,
     27     .msg_namelen = 0,
     28     .msg_iov = &v,
     29     .msg_iovlen = 1,
     30     .msg_control = ancilbuf,
     31     .msg_controllen = CMSG_SPACE(sizeof(int))
     32   } ;
     33   struct cmsghdr *c = CMSG_FIRSTHDR(&hdr) ;
     34   memset(hdr.msg_control, 0, hdr.msg_controllen) ;
     35   c->cmsg_level = SOL_SOCKET ;
     36   c->cmsg_type = SCM_RIGHTS ;
     37   c->cmsg_len = CMSG_LEN(sizeof(int)) ;
     38   memcpy(CMSG_DATA(c), &fd, sizeof(int)) ;
     39   do r = sendmsg(sock, &hdr, MSG_NOSIGNAL) ;
     40   while (r < 0 && errno == EINTR) ;
     41   if (r <= 0) return 0 ;
     42   return 1 ;
     43 }