2 * This file is part of DisOrder.
3 * Copyright (C) 2005 Richard Kettlewell
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 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 #include <sys/socket.h>
32 void speaker_send(int fd, const struct speaker_message *sm, int datafd) {
37 char size[CMSG_SPACE(sizeof (int))];
41 memset(&m, 0, sizeof m);
44 iov.iov_base = (void *)sm;
45 iov.iov_len = sizeof *sm;
47 m.msg_control = (void *)&u.cmsg;
48 m.msg_controllen = sizeof u;
49 memset(&u, 0, sizeof u);
50 u.cmsg.cmsg_len = CMSG_LEN(sizeof (int));
51 u.cmsg.cmsg_level = SOL_SOCKET;
52 u.cmsg.cmsg_type = SCM_RIGHTS;
53 *(int *)CMSG_DATA(&u.cmsg) = datafd;
56 ret = sendmsg(fd, &m, 0);
57 } while(ret < 0 && errno == EINTR);
59 fatal(errno, "sendmsg");
62 int speaker_recv(int fd, struct speaker_message *sm, int *datafd) {
67 char size[CMSG_SPACE(sizeof (int))];
71 memset(&m, 0, sizeof m);
74 iov.iov_base = (void *)sm;
75 iov.iov_len = sizeof *sm;
77 m.msg_control = (void *)&u.cmsg;
78 m.msg_controllen = sizeof u;
79 memset(&u, 0, sizeof u);
80 u.cmsg.cmsg_len = CMSG_LEN(sizeof (int));
81 u.cmsg.cmsg_level = SOL_SOCKET;
82 u.cmsg.cmsg_type = SCM_RIGHTS;
86 ret = recvmsg(fd, &m, MSG_DONTWAIT);
87 } while(ret < 0 && errno == EINTR);
89 if(errno != EAGAIN) fatal(errno, "recvmsg");
92 if((size_t)m.msg_controllen >= CMSG_LEN(sizeof (int))) {
94 fatal(0, "got an unexpected file descriptor from recvmsg");
96 *datafd = *(int *)CMSG_DATA(&u.cmsg);