1226031Sstas/* 2226031Sstas * Copyright (c) 2009 Kungliga Tekniska H�gskolan 3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4226031Sstas * All rights reserved. 5226031Sstas * 6226031Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 7226031Sstas * 8226031Sstas * Redistribution and use in source and binary forms, with or without 9226031Sstas * modification, are permitted provided that the following conditions 10226031Sstas * are met: 11226031Sstas * 12226031Sstas * 1. Redistributions of source code must retain the above copyright 13226031Sstas * notice, this list of conditions and the following disclaimer. 14226031Sstas * 15226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 16226031Sstas * notice, this list of conditions and the following disclaimer in the 17226031Sstas * documentation and/or other materials provided with the distribution. 18226031Sstas * 19226031Sstas * 3. Neither the name of the Institute nor the names of its contributors 20226031Sstas * may be used to endorse or promote products derived from this software 21226031Sstas * without specific prior written permission. 22226031Sstas * 23226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33226031Sstas * SUCH DAMAGE. 34226031Sstas */ 35226031Sstas 36226031Sstas#include "hi_locl.h" 37226031Sstas#ifdef HAVE_GCD 38226031Sstas#include <dispatch/dispatch.h> 39226031Sstas#else 40226031Sstas#include "heim_threads.h" 41226031Sstas#endif 42226031Sstas 43226031Sstasstruct heim_icred { 44226031Sstas uid_t uid; 45226031Sstas gid_t gid; 46226031Sstas pid_t pid; 47226031Sstas pid_t session; 48226031Sstas}; 49226031Sstas 50226031Sstasvoid 51226031Sstasheim_ipc_free_cred(heim_icred cred) 52226031Sstas{ 53226031Sstas free(cred); 54226031Sstas} 55226031Sstas 56226031Sstasuid_t 57226031Sstasheim_ipc_cred_get_uid(heim_icred cred) 58226031Sstas{ 59226031Sstas return cred->uid; 60226031Sstas} 61226031Sstas 62226031Sstasgid_t 63226031Sstasheim_ipc_cred_get_gid(heim_icred cred) 64226031Sstas{ 65226031Sstas return cred->gid; 66226031Sstas} 67226031Sstas 68226031Sstaspid_t 69226031Sstasheim_ipc_cred_get_pid(heim_icred cred) 70226031Sstas{ 71226031Sstas return cred->pid; 72226031Sstas} 73226031Sstas 74226031Sstaspid_t 75226031Sstasheim_ipc_cred_get_session(heim_icred cred) 76226031Sstas{ 77226031Sstas return cred->session; 78226031Sstas} 79226031Sstas 80226031Sstas 81226031Sstasint 82226031Sstas_heim_ipc_create_cred(uid_t uid, gid_t gid, pid_t pid, pid_t session, heim_icred *cred) 83226031Sstas{ 84226031Sstas *cred = calloc(1, sizeof(**cred)); 85226031Sstas if (*cred == NULL) 86226031Sstas return ENOMEM; 87226031Sstas (*cred)->uid = uid; 88226031Sstas (*cred)->gid = gid; 89226031Sstas (*cred)->pid = pid; 90226031Sstas (*cred)->session = session; 91226031Sstas return 0; 92226031Sstas} 93226031Sstas 94226031Sstas#ifndef HAVE_GCD 95226031Sstasstruct heim_isemaphore { 96226031Sstas HEIMDAL_MUTEX mutex; 97226031Sstas pthread_cond_t cond; 98226031Sstas long counter; 99226031Sstas}; 100226031Sstas#endif 101226031Sstas 102226031Sstasheim_isemaphore 103226031Sstasheim_ipc_semaphore_create(long value) 104226031Sstas{ 105226031Sstas#ifdef HAVE_GCD 106226031Sstas return (heim_isemaphore)dispatch_semaphore_create(value); 107226031Sstas#elif !defined(ENABLE_PTHREAD_SUPPORT) 108226031Sstas heim_assert(0, "no semaphore support w/o pthreads"); 109226031Sstas return NULL; 110226031Sstas#else 111226031Sstas heim_isemaphore s = malloc(sizeof(*s)); 112226031Sstas if (s == NULL) 113226031Sstas return NULL; 114226031Sstas HEIMDAL_MUTEX_init(&s->mutex); 115226031Sstas pthread_cond_init(&s->cond, NULL); 116226031Sstas s->counter = value; 117226031Sstas return s; 118226031Sstas#endif 119226031Sstas} 120226031Sstas 121226031Sstaslong 122226031Sstasheim_ipc_semaphore_wait(heim_isemaphore s, time_t t) 123226031Sstas{ 124226031Sstas#ifdef HAVE_GCD 125226031Sstas uint64_t timeout; 126226031Sstas if (t == HEIM_IPC_WAIT_FOREVER) 127226031Sstas timeout = DISPATCH_TIME_FOREVER; 128226031Sstas else 129226031Sstas timeout = (uint64_t)t * NSEC_PER_SEC; 130226031Sstas 131226031Sstas return dispatch_semaphore_wait((dispatch_semaphore_t)s, timeout); 132226031Sstas#elif !defined(ENABLE_PTHREAD_SUPPORT) 133226031Sstas heim_assert(0, "no semaphore support w/o pthreads"); 134226031Sstas return 0; 135226031Sstas#else 136226031Sstas HEIMDAL_MUTEX_lock(&s->mutex); 137226031Sstas /* if counter hits below zero, we get to wait */ 138226031Sstas if (--s->counter < 0) { 139226031Sstas int ret; 140226031Sstas 141226031Sstas if (t == HEIM_IPC_WAIT_FOREVER) 142226031Sstas ret = pthread_cond_wait(&s->cond, &s->mutex); 143226031Sstas else { 144226031Sstas struct timespec ts; 145226031Sstas ts.tv_sec = t; 146226031Sstas ts.tv_nsec = 0; 147226031Sstas ret = pthread_cond_timedwait(&s->cond, &s->mutex, &ts); 148226031Sstas } 149226031Sstas if (ret) { 150226031Sstas HEIMDAL_MUTEX_unlock(&s->mutex); 151226031Sstas return errno; 152226031Sstas } 153226031Sstas } 154226031Sstas HEIMDAL_MUTEX_unlock(&s->mutex); 155226031Sstas 156226031Sstas return 0; 157226031Sstas#endif 158226031Sstas} 159226031Sstas 160226031Sstaslong 161226031Sstasheim_ipc_semaphore_signal(heim_isemaphore s) 162226031Sstas{ 163226031Sstas#ifdef HAVE_GCD 164226031Sstas return dispatch_semaphore_signal((dispatch_semaphore_t)s); 165226031Sstas#elif !defined(ENABLE_PTHREAD_SUPPORT) 166226031Sstas heim_assert(0, "no semaphore support w/o pthreads"); 167226031Sstas return EINVAL; 168226031Sstas#else 169226031Sstas int wakeup; 170226031Sstas HEIMDAL_MUTEX_lock(&s->mutex); 171226031Sstas wakeup = (++s->counter == 0) ; 172226031Sstas HEIMDAL_MUTEX_unlock(&s->mutex); 173226031Sstas if (wakeup) 174226031Sstas pthread_cond_signal(&s->cond); 175226031Sstas return 0; 176226031Sstas#endif 177226031Sstas} 178226031Sstas 179226031Sstasvoid 180226031Sstasheim_ipc_semaphore_release(heim_isemaphore s) 181226031Sstas{ 182226031Sstas#ifdef HAVE_GCD 183226031Sstas dispatch_release((dispatch_semaphore_t)s); 184226031Sstas#elif !defined(ENABLE_PTHREAD_SUPPORT) 185226031Sstas heim_assert(0, "no semaphore support w/o pthreads"); 186226031Sstas#else 187226031Sstas HEIMDAL_MUTEX_lock(&s->mutex); 188226031Sstas if (s->counter != 0) 189226031Sstas abort(); 190226031Sstas HEIMDAL_MUTEX_unlock(&s->mutex); 191226031Sstas HEIMDAL_MUTEX_destroy(&s->mutex); 192226031Sstas pthread_cond_destroy(&s->cond); 193226031Sstas free(s); 194226031Sstas#endif 195226031Sstas} 196226031Sstas 197226031Sstasvoid 198226031Sstasheim_ipc_free_data(heim_idata *data) 199226031Sstas{ 200226031Sstas if (data->data) 201226031Sstas free(data->data); 202226031Sstas data->data = NULL; 203226031Sstas data->length = 0; 204226031Sstas} 205