common.c revision 285830
1/* 2 * Copyright (c) 2009 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "hi_locl.h" 37#ifdef HAVE_GCD 38#include <dispatch/dispatch.h> 39#else 40#include "heim_threads.h" 41#endif 42 43struct heim_icred { 44 uid_t uid; 45 gid_t gid; 46 pid_t pid; 47 pid_t session; 48}; 49 50void 51heim_ipc_free_cred(heim_icred cred) 52{ 53 free(cred); 54} 55 56uid_t 57heim_ipc_cred_get_uid(heim_icred cred) 58{ 59 return cred->uid; 60} 61 62gid_t 63heim_ipc_cred_get_gid(heim_icred cred) 64{ 65 return cred->gid; 66} 67 68pid_t 69heim_ipc_cred_get_pid(heim_icred cred) 70{ 71 return cred->pid; 72} 73 74pid_t 75heim_ipc_cred_get_session(heim_icred cred) 76{ 77 return cred->session; 78} 79 80 81int 82_heim_ipc_create_cred(uid_t uid, gid_t gid, pid_t pid, pid_t session, heim_icred *cred) 83{ 84 *cred = calloc(1, sizeof(**cred)); 85 if (*cred == NULL) 86 return ENOMEM; 87 (*cred)->uid = uid; 88 (*cred)->gid = gid; 89 (*cred)->pid = pid; 90 (*cred)->session = session; 91 return 0; 92} 93 94#ifndef HAVE_GCD 95struct heim_isemaphore { 96 HEIMDAL_MUTEX mutex; 97 pthread_cond_t cond; 98 long counter; 99}; 100#endif 101 102heim_isemaphore 103heim_ipc_semaphore_create(long value) 104{ 105#ifdef HAVE_GCD 106 return (heim_isemaphore)dispatch_semaphore_create(value); 107#elif !defined(ENABLE_PTHREAD_SUPPORT) 108 heim_assert(0, "no semaphore support w/o pthreads"); 109 return NULL; 110#else 111 heim_isemaphore s = malloc(sizeof(*s)); 112 if (s == NULL) 113 return NULL; 114 HEIMDAL_MUTEX_init(&s->mutex); 115 pthread_cond_init(&s->cond, NULL); 116 s->counter = value; 117 return s; 118#endif 119} 120 121long 122heim_ipc_semaphore_wait(heim_isemaphore s, time_t t) 123{ 124#ifdef HAVE_GCD 125 uint64_t timeout; 126 if (t == HEIM_IPC_WAIT_FOREVER) 127 timeout = DISPATCH_TIME_FOREVER; 128 else 129 timeout = (uint64_t)t * NSEC_PER_SEC; 130 131 return dispatch_semaphore_wait((dispatch_semaphore_t)s, timeout); 132#elif !defined(ENABLE_PTHREAD_SUPPORT) 133 heim_assert(0, "no semaphore support w/o pthreads"); 134 return 0; 135#else 136 HEIMDAL_MUTEX_lock(&s->mutex); 137 /* if counter hits below zero, we get to wait */ 138 if (--s->counter < 0) { 139 int ret; 140 141 if (t == HEIM_IPC_WAIT_FOREVER) 142 ret = pthread_cond_wait(&s->cond, &s->mutex); 143 else { 144 struct timespec ts; 145 ts.tv_sec = t; 146 ts.tv_nsec = 0; 147 ret = pthread_cond_timedwait(&s->cond, &s->mutex, &ts); 148 } 149 if (ret) { 150 HEIMDAL_MUTEX_unlock(&s->mutex); 151 return errno; 152 } 153 } 154 HEIMDAL_MUTEX_unlock(&s->mutex); 155 156 return 0; 157#endif 158} 159 160long 161heim_ipc_semaphore_signal(heim_isemaphore s) 162{ 163#ifdef HAVE_GCD 164 return dispatch_semaphore_signal((dispatch_semaphore_t)s); 165#elif !defined(ENABLE_PTHREAD_SUPPORT) 166 heim_assert(0, "no semaphore support w/o pthreads"); 167 return EINVAL; 168#else 169 int wakeup; 170 HEIMDAL_MUTEX_lock(&s->mutex); 171 wakeup = (++s->counter == 0) ; 172 HEIMDAL_MUTEX_unlock(&s->mutex); 173 if (wakeup) 174 pthread_cond_signal(&s->cond); 175 return 0; 176#endif 177} 178 179void 180heim_ipc_semaphore_release(heim_isemaphore s) 181{ 182#ifdef HAVE_GCD 183 dispatch_release((dispatch_semaphore_t)s); 184#elif !defined(ENABLE_PTHREAD_SUPPORT) 185 heim_assert(0, "no semaphore support w/o pthreads"); 186#else 187 HEIMDAL_MUTEX_lock(&s->mutex); 188 if (s->counter != 0) 189 abort(); 190 HEIMDAL_MUTEX_unlock(&s->mutex); 191 HEIMDAL_MUTEX_destroy(&s->mutex); 192 pthread_cond_destroy(&s->cond); 193 free(s); 194#endif 195} 196 197void 198heim_ipc_free_data(heim_idata *data) 199{ 200 if (data->data) 201 free(data->data); 202 data->data = NULL; 203 data->length = 0; 204} 205