mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2026-02-18 22:05:37 -05:00
iochannel/pstream/pdispatch: Add support for receiving file descriptors
The file descriptors are read from the iochannel just like the creds are. So instead of passing just creds (and creds_valid), we now pass the entire pa_ancil struct. Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
parent
cc7a317e85
commit
06bc22b220
9 changed files with 84 additions and 31 deletions
|
|
@ -348,21 +348,26 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
|
|||
return r;
|
||||
}
|
||||
|
||||
ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *creds, bool *creds_valid) {
|
||||
ssize_t pa_iochannel_read_with_ancil(pa_iochannel*io, void*data, size_t l, pa_ancil *ancil) {
|
||||
ssize_t r;
|
||||
struct msghdr mh;
|
||||
struct iovec iov;
|
||||
union {
|
||||
struct cmsghdr hdr;
|
||||
uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
|
||||
uint8_t data[CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * MAX_ANCIL_FDS)];
|
||||
} cmsg;
|
||||
|
||||
pa_assert(io);
|
||||
pa_assert(data);
|
||||
pa_assert(l);
|
||||
pa_assert(io->ifd >= 0);
|
||||
pa_assert(creds);
|
||||
pa_assert(creds_valid);
|
||||
pa_assert(ancil);
|
||||
|
||||
if (io->ifd_type > 0) {
|
||||
ancil->creds_valid = false;
|
||||
ancil->nfd = 0;
|
||||
return pa_iochannel_read(io, data, l);
|
||||
}
|
||||
|
||||
pa_zero(iov);
|
||||
iov.iov_base = data;
|
||||
|
|
@ -378,19 +383,34 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr
|
|||
if ((r = recvmsg(io->ifd, &mh, 0)) >= 0) {
|
||||
struct cmsghdr *cmh;
|
||||
|
||||
*creds_valid = false;
|
||||
ancil->creds_valid = false;
|
||||
ancil->nfd = 0;
|
||||
|
||||
for (cmh = CMSG_FIRSTHDR(&mh); cmh; cmh = CMSG_NXTHDR(&mh, cmh)) {
|
||||
|
||||
if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_CREDENTIALS) {
|
||||
if (cmh->cmsg_level != SOL_SOCKET)
|
||||
continue;
|
||||
|
||||
if (cmh->cmsg_type == SCM_CREDENTIALS) {
|
||||
struct ucred u;
|
||||
pa_assert(cmh->cmsg_len == CMSG_LEN(sizeof(struct ucred)));
|
||||
memcpy(&u, CMSG_DATA(cmh), sizeof(struct ucred));
|
||||
|
||||
creds->gid = u.gid;
|
||||
creds->uid = u.uid;
|
||||
*creds_valid = true;
|
||||
break;
|
||||
ancil->creds.gid = u.gid;
|
||||
ancil->creds.uid = u.uid;
|
||||
ancil->creds_valid = true;
|
||||
}
|
||||
else if (cmh->cmsg_type == SCM_RIGHTS) {
|
||||
int nfd = (cmh->cmsg_len - CMSG_LEN(0)) / sizeof(int);
|
||||
if (nfd > MAX_ANCIL_FDS) {
|
||||
int i;
|
||||
pa_log("Trying to receive too many file descriptors!");
|
||||
for (i = 0; i < nfd; i++)
|
||||
pa_close(((int*) CMSG_DATA(cmh))[i]);
|
||||
continue;
|
||||
}
|
||||
memcpy(ancil->fds, CMSG_DATA(cmh), nfd * sizeof(int));
|
||||
ancil->nfd = nfd;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -398,6 +418,11 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr
|
|||
enable_events(io);
|
||||
}
|
||||
|
||||
if (r == -1 && errno == ENOTSOCK) {
|
||||
io->ifd_type = 1;
|
||||
return pa_iochannel_read_with_ancil(io, data, l, ancil);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue