Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/ipc/common.c
Line
Count
Source
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
43
struct heim_icred {
44
    uid_t uid;
45
    gid_t gid;
46
    pid_t pid;
47
    pid_t session;
48
};
49
50
void
51
heim_ipc_free_cred(heim_icred cred)
52
0
{
53
0
    free(cred);
54
0
}
55
56
uid_t
57
heim_ipc_cred_get_uid(heim_icred cred)
58
0
{
59
0
    return cred ? cred->uid : (uid_t)-1;
60
0
}
61
62
gid_t
63
heim_ipc_cred_get_gid(heim_icred cred)
64
0
{
65
0
    return cred ? cred->gid : (gid_t)-1;
66
0
}
67
68
pid_t
69
heim_ipc_cred_get_pid(heim_icred cred)
70
0
{
71
0
    return cred ? cred->pid : (pid_t)0;
72
0
}
73
74
pid_t
75
heim_ipc_cred_get_session(heim_icred cred)
76
0
{
77
0
    return cred ? cred->session : (pid_t)-1;
78
0
}
79
80
81
int
82
_heim_ipc_create_cred(uid_t uid, gid_t gid, pid_t pid, pid_t session, heim_icred *cred)
83
0
{
84
0
    *cred = calloc(1, sizeof(**cred));
85
0
    if (*cred == NULL)
86
0
  return ENOMEM;
87
0
    (*cred)->uid = uid;
88
0
    (*cred)->gid = gid;
89
0
    (*cred)->pid = pid;
90
0
    (*cred)->session = session;
91
0
    return 0;
92
0
}
93
94
#ifndef HAVE_GCD
95
struct heim_isemaphore {
96
    HEIMDAL_MUTEX mutex;
97
#ifdef ENABLE_PTHREAD_SUPPORT
98
    pthread_cond_t cond;
99
#endif
100
    long counter;
101
};
102
#endif
103
104
heim_isemaphore
105
heim_ipc_semaphore_create(long value)
106
0
{
107
#ifdef HAVE_GCD
108
    return (heim_isemaphore)dispatch_semaphore_create(value);
109
#elif !defined(ENABLE_PTHREAD_SUPPORT)
110
0
    heim_assert(0, "no semaphore support w/o pthreads");
111
0
    return NULL;
112
#else
113
    heim_isemaphore s = malloc(sizeof(*s));
114
    if (s == NULL)
115
  return NULL;
116
    HEIMDAL_MUTEX_init(&s->mutex);
117
    pthread_cond_init(&s->cond, NULL);
118
    s->counter = value;
119
    return s;
120
#endif
121
0
}
122
123
long
124
heim_ipc_semaphore_wait(heim_isemaphore s, time_t t)
125
0
{
126
#ifdef HAVE_GCD
127
    uint64_t timeout;
128
    if (t == HEIM_IPC_WAIT_FOREVER)
129
  timeout = DISPATCH_TIME_FOREVER;
130
    else
131
  timeout = (uint64_t)t * NSEC_PER_SEC;
132
133
    return dispatch_semaphore_wait((dispatch_semaphore_t)s, timeout);
134
#elif !defined(ENABLE_PTHREAD_SUPPORT)
135
0
    heim_assert(0, "no semaphore support w/o pthreads");
136
0
    return 0;
137
#else
138
    HEIMDAL_MUTEX_lock(&s->mutex);
139
    /* if counter hits below zero, we get to wait */
140
    if (--s->counter < 0) {
141
  int ret;
142
143
  if (t == HEIM_IPC_WAIT_FOREVER)
144
      ret = pthread_cond_wait(&s->cond, &s->mutex);
145
  else {
146
      struct timespec ts;
147
      ts.tv_sec = t;
148
      ts.tv_nsec = 0;
149
      ret = pthread_cond_timedwait(&s->cond, &s->mutex, &ts);
150
  }
151
  if (ret) {
152
      HEIMDAL_MUTEX_unlock(&s->mutex);
153
      return errno;
154
  }
155
    }
156
    HEIMDAL_MUTEX_unlock(&s->mutex);
157
158
    return 0;
159
#endif
160
0
}
161
162
long
163
heim_ipc_semaphore_signal(heim_isemaphore s)
164
0
{
165
#ifdef HAVE_GCD
166
    return dispatch_semaphore_signal((dispatch_semaphore_t)s);
167
#elif !defined(ENABLE_PTHREAD_SUPPORT)
168
0
    heim_assert(0, "no semaphore support w/o pthreads");
169
0
    return EINVAL;
170
#else
171
    int wakeup;
172
    HEIMDAL_MUTEX_lock(&s->mutex);
173
    wakeup = (++s->counter == 0) ;
174
    HEIMDAL_MUTEX_unlock(&s->mutex);
175
    if (wakeup)
176
  pthread_cond_signal(&s->cond);
177
    return 0;
178
#endif
179
0
}
180
181
void
182
heim_ipc_semaphore_release(heim_isemaphore s)
183
0
{
184
#ifdef HAVE_GCD
185
    dispatch_release((dispatch_semaphore_t)s);
186
#elif !defined(ENABLE_PTHREAD_SUPPORT)
187
0
    heim_assert(0, "no semaphore support w/o pthreads");
188
#else
189
    HEIMDAL_MUTEX_lock(&s->mutex);
190
    if (s->counter != 0)
191
  abort();
192
    HEIMDAL_MUTEX_unlock(&s->mutex);
193
    HEIMDAL_MUTEX_destroy(&s->mutex);
194
    pthread_cond_destroy(&s->cond);
195
    free(s);
196
#endif
197
0
}
198
199
void
200
heim_ipc_free_data(heim_idata *data)
201
0
{
202
0
    if (data->data)
203
0
  free(data->data);
204
    data->data = NULL;
205
0
    data->length = 0;
206
0
}