1/*** 2 This file is part of PulseAudio. 3 4 Copyright 2016 Ahmed S. Darwish <darwish.07@gmail.com> 5 6 PulseAudio is free software; you can redistribute it and/or modify 7 it under the terms of the GNU Lesser General Public License as 8 published by the Free Software Foundation; either version 2.1 of the 9 License, or (at your option) any later version. 10 11 PulseAudio is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 18***/ 19 20#ifdef HAVE_CONFIG_H 21#include <config.h> 22#endif 23 24#include <pulsecore/core-util.h> 25#include <pulsecore/creds.h> 26#include <pulsecore/macro.h> 27#include <pulsecore/pdispatch.h> 28#include <pulsecore/pstream.h> 29#include <pulsecore/tagstruct.h> 30 31#include "native-common.h" 32 33/* 34 * Command handlers shared between client and server 35 */ 36 37/* Check pa_pstream_register_memfd_mempool() for further details */ 38int pa_common_command_register_memfd_shmid(pa_pstream *p, pa_pdispatch *pd, uint32_t version, 39 uint32_t command, pa_tagstruct *t) { 40#if defined(HAVE_CREDS) && defined(HAVE_MEMFD) 41 pa_cmsg_ancil_data *ancil = NULL; 42 unsigned shm_id; 43 int ret = -1; 44 45 pa_assert(pd); 46 pa_assert(command == PA_COMMAND_REGISTER_MEMFD_SHMID); 47 pa_assert(t); 48 49 ancil = pa_pdispatch_take_ancil_data(pd); 50 if (!ancil) 51 goto finish; 52 53 /* Upon fd leaks and reaching our open fd limit, recvmsg(2) 54 * just strips all passed fds from the ancillary data */ 55 if (ancil->nfd == 0) { 56 pa_log("Expected 1 memfd fd to be received over pipe; got 0"); 57 pa_log("Did we reach our open file descriptors limit?"); 58 goto finish; 59 } 60 61 if (ancil->nfd != 1 || ancil->fds[0] == -1) 62 goto finish; 63 64 if (version < 31 || pa_tagstruct_getu32(t, &shm_id) < 0 || !pa_tagstruct_eof(t)) 65 goto finish; 66 67 pa_pstream_attach_memfd_shmid(p, shm_id, ancil->fds[0]); 68 69 ret = 0; 70finish: 71 if (ancil) 72 pa_cmsg_ancil_data_close_fds(ancil); 73 74 return ret; 75#else 76 return -1; 77#endif 78} 79