xref: /xnu-11215.1.10/libsyscall/mach/mach/mach_right_private.h (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
1 /*
2  * Copyright (c) 2018 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 #ifndef __MACH_RIGHT_PRIVATE_H
29 #define __MACH_RIGHT_PRIVATE_H
30 
31 #include <os/base.h>
32 #include <mach/mach.h>
33 #include <mach/port.h>
34 #include <mach/mach_port.h>
35 #include <sys/cdefs.h>
36 #include <stdbool.h>
37 
38 __BEGIN_DECLS;
39 
40 /*!
41  * @typedef mach_right_recv_t
42  * A type representing the receive right to a Mach port.
43  */
44 typedef struct _mach_right_recv {
45 	mach_port_t mrr_name;
46 } mach_right_recv_t;
47 
48 /*!
49  * @const MACH_RIGHT_RECV_NULL
50  * A convenience initializer for a receive right object.
51  */
52 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
53 #define MACH_RIGHT_RECV_NULL ((mach_right_recv_t){MACH_PORT_NULL})
54 #elif defined(__cplusplus) && __cplusplus >= 201103L
55 #define MACH_RIGHT_RECV_NULL (mach_right_recv_t{MACH_PORT_NULL})
56 #elif defined(__cplusplus)
57 #define MACH_RIGHT_RECV_NULL \
58 	        (mach_right_recv_t((mach_right_recv_t){MACH_PORT_NULL}))
59 #else
60 #define MACH_RIGHT_RECV_NULL {MACH_PORT_NULL}
61 #endif
62 
63 /*!
64  * @typedef mach_right_send_t
65  * A type representing a send right to a Mach port.
66  */
67 typedef struct _mach_right_send {
68 	mach_port_t mrs_name;
69 } mach_right_send_t;
70 
71 /*!
72  * @const MACH_RIGHT_SEND_NULL
73  * A convenience initializer for a send right object.
74  */
75 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
76 #define MACH_RIGHT_SEND_NULL ((mach_right_send_t){MACH_PORT_NULL})
77 #elif defined(__cplusplus) && __cplusplus >= 201103L
78 #define MACH_RIGHT_SEND_NULL (mach_right_send_t{MACH_PORT_NULL})
79 #elif defined(__cplusplus)
80 #define MACH_RIGHT_SEND_NULL \
81 	        (mach_right_send_t((mach_right_send_t){MACH_PORT_NULL}))
82 #else
83 #define MACH_RIGHT_SEND_NULL {MACH_PORT_NULL}
84 #endif
85 
86 /*!
87  * @typedef mach_right_send_once_t
88  * A type representing a send-once right to a Mach port.
89  */
90 typedef struct _mach_right_send_once {
91 	mach_port_t mrso_name;
92 } mach_right_send_once_t;
93 
94 /*!
95  * @const MACH_RIGHT_SEND_ONCE_NULL
96  * A convenience initializer for a send-once right object.
97  */
98 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
99 #define MACH_RIGHT_SEND_ONCE_NULL ((mach_right_send_once_t){MACH_PORT_NULL})
100 #elif defined(__cplusplus) && __cplusplus >= 201103L
101 #define MACH_RIGHT_SEND_ONCE_NULL (mach_right_send_once_t{MACH_PORT_NULL})
102 #elif defined(__cplusplus)
103 #define MACH_RIGHT_SEND_ONCE_NULL \
104 	        (mach_right_send_once_t((mach_right_send_once_t){MACH_PORT_NULL}))
105 #else
106 #define MACH_RIGHT_SEND_ONCE_NULL {MACH_PORT_NULL}
107 #endif
108 
109 /*!
110  * @function mach_right_recv
111  * Wraps a port name as a receive right object.
112  *
113  * @param pn
114  * The port name. If this name is valid but does not represent a receive right,
115  * the behavior of mach_right_recv_* implementations is undefined.
116  *
117  * @result
118  * A new receive right object.
119  */
120 OS_ALWAYS_INLINE OS_WARN_RESULT
121 static inline mach_right_recv_t
mach_right_recv(mach_port_name_t pn)122 mach_right_recv(mach_port_name_t pn)
123 {
124 	mach_right_recv_t mrr = {pn};
125 	return mrr;
126 }
127 
128 /*!
129  * @function mach_right_send
130  * Wraps a port name as a send right object.
131  *
132  * @param pn
133  * The port name. If this name is valid but does not represent a send right, the
134  * behavior of mach_right_send_* implementations is undefined.
135  *
136  * @result
137  * A new send right object.
138  */
139 OS_ALWAYS_INLINE OS_WARN_RESULT
140 static inline mach_right_send_t
mach_right_send(mach_port_name_t pn)141 mach_right_send(mach_port_name_t pn)
142 {
143 	mach_right_send_t mrs = {pn};
144 	return mrs;
145 }
146 
147 /*!
148  * @function mach_right_send_valid
149  * Checks if the given send right object is valid.
150  *
151  * @param mrs
152  * The send right object to check.
153  *
154  * @result
155  * A Boolean indicating whether the right is valid.
156  */
157 OS_ALWAYS_INLINE OS_WARN_RESULT
158 static inline bool
mach_right_send_valid(mach_right_send_t mrs)159 mach_right_send_valid(mach_right_send_t mrs)
160 {
161 	return MACH_PORT_VALID(mrs.mrs_name);
162 }
163 
164 /*!
165  * @function mach_right_send_once
166  * Wraps a port name as a send-once right object.
167  *
168  * @param pn
169  * The port name. If this name is valid but does not represent a send-once
170  * right, the behavior of mach_right_send_once_* implementations is undefined.
171  *
172  * @result
173  * A new send-once right object.
174  */
175 OS_ALWAYS_INLINE OS_WARN_RESULT
176 static inline mach_right_send_once_t
mach_right_send_once(mach_port_name_t pn)177 mach_right_send_once(mach_port_name_t pn)
178 {
179 	mach_right_send_once_t mrso = {pn};
180 	return mrso;
181 }
182 
183 /*!
184  * @function mach_right_send_once_valid
185  * Checks if the given send-once right object is valid.
186  *
187  * @param mrso
188  * The send-once right object to check.
189  *
190  * @result
191  * A Boolean indicating whether the right is valid.
192  */
193 OS_ALWAYS_INLINE OS_WARN_RESULT
194 static inline bool
mach_right_send_once_valid(mach_right_send_once_t mrso)195 mach_right_send_once_valid(mach_right_send_once_t mrso)
196 {
197 	return MACH_PORT_VALID(mrso.mrso_name);
198 }
199 
200 /*!
201  * @typedef mach_right_flags_t
202  * Flags influencing the behavior of a constructed Mach port.
203  *
204  * @const MACH_RIGHT_RECV_INIT
205  * No flags set. This value is suitable for initialization purposes.
206  *
207  * @const MACH_RIGHT_RECV_UNGUARDED
208  * The given context should not serve as a guard for the underlying port's
209  * destruction.
210  *
211  * @const MACH_RIGHT_RECV_FLAG_STRICT
212  * Apply strict guarding for the constructed Mach port.
213  *
214  * @const MACH_RIGHT_RECV_FLAG_IMMOVABLE
215  * The constructed Mach port's receive right will be immovable.
216  */
217 OS_ENUM(mach_right_flags, uint64_t,
218     MACH_RIGHT_RECV_FLAG_INIT = 0,
219     MACH_RIGHT_RECV_FLAG_UNGUARDED = (1 << 0),
220     MACH_RIGHT_RECV_FLAG_STRICT = (1 << 1),
221     MACH_RIGHT_RECV_FLAG_IMMOVABLE = (1 << 2),
222     );
223 
224 /*!
225  * @function mach_right_recv_construct
226  * Allocates a new Mach port and returns the receive right to the caller.
227  *
228  * @param flags
229  * Flags to influence the behavior of the new port.
230  *
231  * @param sr
232  * If non-NULL, will be filled in with the name of a send right which
233  * corresponds to the new port. The caller is responsible for disposing of this
234  * send right with {@link mach_right_send_release}.
235  *
236  * @param ctx
237  * Context to be associated with the new port. By default, this context must be
238  * passed to {@link mach_right_recv_destruct} in order to destroy the underlying
239  * port. This requirement may be elided with the
240  * {@link MACH_RIGHT_RECV_UNGUARDED} flag.
241  *
242  * @result
243  * A new port handle which refers to the receive right for the newly-created
244  * port. The caller is responsible for disposing of this handle with
245  * {@link mach_right_recv_destruct}.
246  *
247  * @discussion
248  * The implementation will abort on any failure to allocate a new port object in
249  * the kernel. Thus the caller may assert that a new, valid receive right is
250  * always returned.
251  */
252 OS_EXPORT OS_WARN_RESULT
253 mach_right_recv_t
254 mach_right_recv_construct(mach_right_flags_t flags,
255     mach_right_send_t *_Nullable sr, uintptr_t ctx);
256 
257 /*!
258  * @function mach_right_recv_destruct
259  * Closes the port referred to by the given receive right.
260  *
261  * @param r
262  * The receive right for the port to manipulate.
263  *
264  * @param s
265  * A pointer to the send right to dispose of. If NULL is given, no attempt will
266  * be made to clean up any send right associated with the port. If the name of
267  * the given send right does not match the name of the given receive right, the
268  * implementation's behavior is undefined.
269  *
270  * @param ctx
271  * The context which guards the underlying port destruction. If the receive
272  * right was created with {@link MACH_RIGHT_RECV_UNGUARDED}, this parameter is
273  * ignored.
274  *
275  * @discussion
276  * If a send right is passed, the implementation performs the moral equivalent
277  * of
278  *
279  *     mach_right_recv_destruct(r, MACH_PORT_NULL, ctx);
280  *     mach_right_send_release(s);
281  *
282  * except in a more efficient manner, requiring only one system call.
283  *
284  * The implementation will abort on any failure to dispose of the port. As such,
285  * this routine should only be used on ports that are known to be under the
286  * caller's complete control.
287  */
288 OS_EXPORT
289 void
290 mach_right_recv_destruct(mach_right_recv_t r, mach_right_send_t *_Nullable s,
291     uintptr_t ctx);
292 
293 /*!
294  * @function mach_right_send_create
295  * Creates a send right to the port referenced by the given receive right.
296  *
297  * @param r
298  * The receive right for the port for which to create the send right.
299  *
300  * @result
301  * The name of the new send right. The caller is responsible for disposing of
302  * this send right with {@link mach_right_send_release}.
303  *
304  * This operation will increment the make-send count of the port referenced by
305  * the given receive right.
306  *
307  * @discussion
308  * The implementation will abort on any failure to create the send right. As
309  * such, this routine should only be used on ports that are known to be under
310  * the caller's complete control.
311  */
312 OS_EXPORT OS_WARN_RESULT
313 mach_right_send_t
314 mach_right_send_create(mach_right_recv_t r);
315 
316 /*!
317  * @function mach_right_send_retain
318  * Increments the user reference count for the given send right.
319  *
320  * @param s
321  * The send right to manipulate.
322  *
323  * @result
324  * If the reference count was successfully incremented, the given port name is
325  * returned. If either MACH_PORT_NULL or MACH_PORT_DEAD are given, the given
326  * value is returned. If the given send right became a dead name before or
327  * during the attempt to retain the send right, MACH_PORT_DEAD is returned.
328  *
329  * If the implementation encounters any other failure condition, it will abort.
330  */
331 OS_EXPORT OS_WARN_RESULT
332 mach_right_send_t
333 mach_right_send_retain(mach_right_send_t s);
334 
335 /*!
336  * @function mach_right_send_release
337  * Decrements the user reference count for the given send right.
338  *
339  * @param s
340  * The send right to manipulate.
341  *
342  * @discussion
343  * If the given send right became a dead name before or during the attempt to
344  * release it, the implementation will dispose of that dead name.
345  *
346  * If the implementation encounters any other failure condition, it will abort.
347  */
348 OS_EXPORT
349 void
350 mach_right_send_release(mach_right_send_t s);
351 
352 /*!
353  * @function mach_right_send_once_create
354  * Creates a send-once right from the given receive right.
355  *
356  * @param r
357  * The receive right for the port for which to create the send-once right.
358  *
359  * @result
360  * The newly-created send-once right.
361  *
362  * @discussion
363  * The implementation will abort on any failure to allocate a new send-once
364  * right, and therefore the caller should only provide a receive right which is
365  * under its complete control. The caller may assert that a new, valid send-once
366  * right is always returned.
367  *
368  * The returned send-once right will never share a name with the given receive
369  * right. A send-once right must be consumed either by using it to send a
370  * message or by consuming it with {@link mach_right_send_once_consume}.
371  *
372  * The returned right does not support retain/release semantics despite the
373  * presence of "create" in the name.
374  */
375 OS_EXPORT OS_WARN_RESULT
376 mach_right_send_once_t
377 mach_right_send_once_create(mach_right_recv_t r);
378 
379 /*!
380  * @function mach_right_send_once_consume
381  * Consumes the given send-once right.
382  *
383  * @param so
384  * The send-once right to manipulate.
385  *
386  * @discussion
387  * If the given send-once right became a dead name before or during the attempt
388  * to release it, the implementation will dispose of that dead name.
389  *
390  * If the implementation encounters any other failure condition, it will abort.
391  *
392  * This operation will cause a send-once notification to be delivered to the
393  * port to which the send-once right refers unless the right is a dead name, in
394  * which case there are no side effects.
395  */
396 OS_EXPORT
397 void
398 mach_right_send_once_consume(mach_right_send_once_t so);
399 
400 __END_DECLS;
401 
402 #endif // __MACH_RIGHT_PRIVATE_H
403