chiark / gitweb /
fishdescriptor: Upgrade licence of code from libxl
[chiark-utils.git] / fishdescriptor / donate.c
1 /*
2  * Copyright (C) 2009 Citrix Ltd.
3  * Copyright (C) 2017 Citrix Ltd.
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 int libxl__sendmsg_fds(libxl__gc *gc, int carrier,
20                        const void *data, size_t datalen,
21                        int nfds, const int fds[], const char *what) {
22     struct msghdr msg = { 0 };
23     struct cmsghdr *cmsg;
24     size_t spaceneeded = nfds * sizeof(fds[0]);
25     char control[CMSG_SPACE(spaceneeded)];
26     struct iovec iov;
27     int r;
28
29     iov.iov_base = (void*)data;
30     iov.iov_len  = datalen;
31
32     /* compose the message */
33     msg.msg_iov = &iov;
34     msg.msg_iovlen = 1;
35     msg.msg_control = control;
36     msg.msg_controllen = sizeof(control);
37
38     /* attach open fd */
39     cmsg = CMSG_FIRSTHDR(&msg);
40     cmsg->cmsg_level = SOL_SOCKET;
41     cmsg->cmsg_type = SCM_RIGHTS;
42     cmsg->cmsg_len = CMSG_LEN(spaceneeded);
43     memcpy(CMSG_DATA(cmsg), fds, spaceneeded);
44
45     msg.msg_controllen = cmsg->cmsg_len;
46
47     r = sendmsg(carrier, &msg, 0);
48     if (r < 0) {
49         LOGE(ERROR, "failed to send fd-carrying message (%s)", what);
50         return ERROR_FAIL;
51     }
52
53     return 0;
54 }