]> git.saurik.com Git - apple/libc.git/blame - sys/semctl.c
Libc-498.tar.gz
[apple/libc.git] / sys / semctl.c
CommitLineData
3d9156a7
A
1/*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#include <unistd.h>
24#include <stdarg.h>
25#include <sys/sem.h>
224c7076
A
26
27#if !__DARWIN_UNIX03
28#include <errno.h>
29/*
30 * Because KERNEL is defined, including errno.h doesn't define errno, so
31 * we have to do it ourselves.
32 */
33extern int * __error(void);
34#define errno (*__error())
35#endif /* !__DARWIN_UNIX03 */
3d9156a7
A
36
37/*
38 * Stub function to account for the differences in the ipc_perm structure,
39 * while maintaining binary backward compatibility.
40 */
224c7076
A
41extern int __semctl(int semid, int semnum, int cmd, void *);
42
3d9156a7
A
43int
44semctl(int semid, int semnum, int cmd, ...)
45{
3d9156a7 46 va_list ap;
224c7076
A
47 int rv;
48 int val = 0;
49#if __DARWIN_UNIX03
3d9156a7
A
50 struct __semid_ds_new *ds;
51
52 va_start(ap, cmd);
224c7076
A
53 if (cmd == SETVAL) {
54 val = va_arg(ap, int);
55 rv = __semctl(semid, semnum, cmd, (void *)val);
56 } else {
57 ds = va_arg(ap, struct __semid_ds_new *);
58 rv = __semctl(semid, semnum, cmd, (void *)ds);
59 }
3d9156a7
A
60 va_end(ap);
61
224c7076 62 return rv;
3d9156a7 63#else /* !__DARWIN_UNIX03 */
3d9156a7
A
64 struct __semid_ds_new ds;
65 struct __semid_ds_new *ds_new = &ds;
224c7076 66 struct __semid_ds_old *ds_old = NULL;
3d9156a7
A
67
68 va_start(ap, cmd);
224c7076
A
69 if (cmd == SETVAL)
70 val = va_arg(ap, int);
71 else
72 ds_old = va_arg(ap, struct __semid_ds_old *);
3d9156a7
A
73 va_end(ap);
74
75#define _UP_CVT(x) ds_new-> x = ds_old-> x
76#define _DN_CVT(x) ds_old-> x = ds_new-> x
77
224c7076
A
78 if ((cmd == IPC_SET || cmd == IPC_STAT) && ds_old == NULL) {
79 /* Return EFAULT if ds_old is NULL (like the kernel would do) */
80 errno = EFAULT;
81 return -1;
82 }
3d9156a7
A
83 if (cmd == IPC_SET) {
84 /* convert before call */
85 _UP_CVT(sem_perm.uid);
86 _UP_CVT(sem_perm.gid);
87 _UP_CVT(sem_perm.cuid);
88 _UP_CVT(sem_perm.cgid);
89 _UP_CVT(sem_perm.mode);
90 ds_new->sem_perm._seq = ds_old->sem_perm.seq;
91 ds_new->sem_perm._key = ds_old->sem_perm.key;
92 _UP_CVT(sem_base);
93 _UP_CVT(sem_nsems);
94 _UP_CVT(sem_otime);
95 _UP_CVT(sem_pad1); /* binary compatibility */
96 _UP_CVT(sem_ctime);
97 _UP_CVT(sem_pad2); /* binary compatibility */
98 _UP_CVT(sem_pad3[0]); /* binary compatibility */
99 _UP_CVT(sem_pad3[1]); /* binary compatibility */
100 _UP_CVT(sem_pad3[2]); /* binary compatibility */
101 _UP_CVT(sem_pad3[3]); /* binary compatibility */
102 }
224c7076
A
103 switch (cmd) {
104 case SETVAL:
105 /* syscall must use LP64 quantities */
106 rv = __semctl(semid, semnum, cmd, (void *)val);
107 break;
108 case IPC_SET:
109 case IPC_STAT:
110 rv = __semctl(semid, semnum, cmd, ds_new);
111 break;
112 default:
113 rv = __semctl(semid, semnum, cmd, ds_old);
114 break;
115 }
3d9156a7
A
116
117 if (cmd == IPC_STAT) {
118 /* convert after call */
119 _DN_CVT(sem_perm.uid); /* warning! precision loss! */
120 _DN_CVT(sem_perm.gid); /* warning! precision loss! */
121 _DN_CVT(sem_perm.cuid); /* warning! precision loss! */
122 _DN_CVT(sem_perm.cgid); /* warning! precision loss! */
123 _DN_CVT(sem_perm.mode);
224c7076
A
124 ds_old->sem_perm.seq = ds_new->sem_perm._seq;
125 ds_old->sem_perm.key = ds_new->sem_perm._key;
3d9156a7
A
126 _DN_CVT(sem_base);
127 _DN_CVT(sem_nsems);
128 _DN_CVT(sem_otime);
129 _DN_CVT(sem_pad1); /* binary compatibility */
130 _DN_CVT(sem_ctime);
131 _DN_CVT(sem_pad2); /* binary compatibility */
132 _DN_CVT(sem_pad3[0]); /* binary compatibility */
133 _DN_CVT(sem_pad3[1]); /* binary compatibility */
134 _DN_CVT(sem_pad3[2]); /* binary compatibility */
135 _DN_CVT(sem_pad3[3]); /* binary compatibility */
136 }
137
138 return (rv);
139#endif /* !__DARWIN_UNIX03 */
140}