all the python scripts are for python2, and fedora31 requires to be specific
[vsys-scripts.git] / root-context / fdpass.c
1 // Modified version of library functions in FUSE
2 //
3
4 #include <assert.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/mount.h>
10 #include <sys/socket.h>
11 #include <sys/un.h>
12
13 int send_fd(int sock_fd, int fd)
14 {
15         int retval;
16         struct msghdr msg;
17         struct cmsghdr *p_cmsg;
18         struct iovec vec;
19         size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
20         int *p_fds;
21         char sendchar = 0;
22
23         msg.msg_control = cmsgbuf;
24         msg.msg_controllen = sizeof(cmsgbuf);
25         p_cmsg = CMSG_FIRSTHDR(&msg);
26         p_cmsg->cmsg_level = SOL_SOCKET;
27         p_cmsg->cmsg_type = SCM_RIGHTS;
28         p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
29         p_fds = (int *) CMSG_DATA(p_cmsg);
30         *p_fds = fd;
31         msg.msg_controllen = p_cmsg->cmsg_len;
32         msg.msg_name = NULL;
33         msg.msg_namelen = 0;
34         msg.msg_iov = &vec;
35         msg.msg_iovlen = 1;
36         msg.msg_flags = 0;
37         /* "To pass file descriptors or credentials you need to send/read at
38          * least one byte" (man 7 unix) */
39         vec.iov_base = &sendchar;
40         vec.iov_len = sizeof(sendchar);
41         while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
42         if (retval != 1) {
43                 perror("sending file descriptor");
44         fprintf(stderr,"File descriptor: %d", sock_fd);
45                 return -1;
46         }
47         return 0;
48 }
49
50
51 /* return value:
52  * >= 0  => fd
53  * -1    => error
54  */
55 int receive_fd(int fd)
56 {
57         struct msghdr msg;
58         struct iovec iov;
59         char buf[1];
60         int rv;
61         size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
62         struct cmsghdr *cmsg;
63
64         iov.iov_base = buf;
65         iov.iov_len = 1;
66
67         msg.msg_name = 0;
68         msg.msg_namelen = 0;
69         msg.msg_iov = &iov;
70         msg.msg_iovlen = 1;
71         /* old BSD implementations should use msg_accrights instead of
72          * msg_control; the interface is different. */
73         msg.msg_control = ccmsg;
74         msg.msg_controllen = sizeof(ccmsg);
75
76         while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
77         if (rv == -1) {
78                 perror("recvmsg");
79                 return -1;
80         }
81         if(!rv) {
82                 /* EOF */
83                 return -1;
84         }
85
86         cmsg = CMSG_FIRSTHDR(&msg);
87         if (!cmsg->cmsg_type == SCM_RIGHTS) {
88                 fprintf(stderr, "got control message of unknown type %d\n",
89                         cmsg->cmsg_type);
90                 return -1;
91         }
92         return *(int*)CMSG_DATA(cmsg);
93 }
94