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