]>
git.saurik.com Git - apple/libc.git/blob - libdarwin/h/cleanup.h
c74c8f1e1a1362efde7c8b419daa7aaf3625a42a
2 * Copyright (c) 2018 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 * Attributes to handle automatic clean-up of certain types of variables when
27 * they go out of scope.
29 * IMPORTANT: These attributes will NOT cause a variable to be cleaned up when
30 * its value changes. For example, this pattern would leak:
32 * void *__os_free ptr = malloc(10);
33 * ptr = somewhere_else;
36 * You should only use these attributes for very well-scoped, temporary
39 #ifndef __DARWIN_CLEANUP_H
40 #define __DARWIN_CLEANUP_H
44 #include <os/assumes.h>
45 #include <os/object_private.h>
47 #include <sys/errno.h>
48 #include <sys/cdefs.h>
53 #include <mach/mach_init.h>
54 #include <mach/port.h>
55 #include <mach/mach_port.h>
56 #include <mach/kern_return.h>
60 #if __has_attribute(cleanup)
63 * An attribute that may be applied to a variable's type. This attribute causes
64 * the variable to be passed to free(3) when it goes out of scope. Applying this
65 * attribute to variables that do not reference heap allocations will result in
68 #define __os_free __attribute__((cleanup(__os_cleanup_free)))
70 __os_cleanup_free(void *__p
)
72 void **tp
= (void **)__p
;
79 * An attribute that may be applied to a variable's type. This attribute causes
80 * the variable to be passed to close(2) when it goes out of scope. Applying
81 * this attribute to variables that do not reference a valid file descriptor
82 * will result in undefined behavior. If the variable's value is -1 upon going
83 * out-of-scope, no cleanup is performed.
85 #define __os_close __attribute__((cleanup(__os_cleanup_close)))
87 __os_cleanup_close(int *__fd
)
93 posix_assert_zero(close(fd
));
98 * An attribute that may be applied to a variable's type. This attribute causes
99 * the variable to be passed to fclose(3) when it goes out of scope. Applying
100 * this attribute to variables that do not reference a valid FILE* will result
101 * in undefined behavior. If the variable's value is NULL upon going out-of-
102 * scope, no cleanup is performed.
104 #define __os_fclose __attribute__((cleanup(__os_cleanup_fclose)))
106 __os_cleanup_fclose(FILE **__fp
)
117 os_assert_zero(errno
);
122 * @define __os_close_mach_recv
123 * An attribute that may be applied to a variable's type. This attribute causes
124 * the variable to be passed to {@link darwin_mach_port_close_recv} when it goes
125 * out of scope. Applying this attribute to variables that do not reference a
126 * valid Mach port receive right will result in undefined behavior. If the
127 * variable's value is MACH_PORT_NULL or MACH_PORT_DEAD upon going out-of-scope,
128 * no cleanup is performed.
130 #define __os_close_mach_recv \
131 __attribute__((cleanup(__os_cleanup_close_mach_recv)))
133 __os_cleanup_close_mach_recv(mach_port_t
*__p
)
135 mach_port_t p
= *__p
;
136 kern_return_t kr
= KERN_FAILURE
;
138 if (!MACH_PORT_VALID(p
)) {
142 kr
= mach_port_destruct(mach_task_self(), p
, 0, 0);
147 * @define __os_release_mach_send
148 * An attribute that may be applied to a variable's type. This attribute causes
149 * the variable to be passed to {@link darwin_mach_port_release} when it goes
150 * out of scope. Applying this attribute to variables that do not reference a
151 * valid Mach port send right or MACH_PORT_NULL or MACH_PORT_DEAD will result
152 * in undefined behavior. If the variable's value is MACH_PORT_NULL or
153 * MACH_PORT_DEAD upon going out-of-scope, no cleanup is performed.
155 #define __os_release_mach_send \
156 __attribute__((cleanup(__os_cleanup_release_mach_send)))
158 __os_cleanup_release_mach_send(mach_port_t
*__p
)
160 mach_port_t p
= *__p
;
161 kern_return_t kr
= KERN_FAILURE
;
163 if (!MACH_PORT_VALID(p
)) {
167 kr
= mach_port_deallocate(mach_task_self(), p
);
172 * @define __os_preserve_errno
173 * An attribute that may be applied to a variable's type. This attribute sets
174 * the global errno to the value of the variable when the variable goes out of
175 * scope. This attribute is useful for preserving the value of errno upon entry
176 * to a function and guaranteeing that it is restored upon exit.
178 #define __os_preserve_errno \
179 __unused __attribute__((cleanup(__os_cleanup_errno)))
181 __os_cleanup_errno(int *__e
)
187 * @define __os_release
188 * An attribute that may be applied to a variable's type. This attribute causes
189 * the variable to be passed to os_release() when it goes out of scope. Applying
190 * this attribute to a variable which does not reference a valid os_object_t
191 * object will result in undefined behavior. If the variable's value is NULL
192 * upon going out-of-scope, no cleanup is performed.
194 * This attribute may be applied to dispatch and XPC objects.
196 #define __os_release __attribute__((cleanup(__os_cleanup_os_release)))
198 __os_cleanup_os_release(void *__p
)
200 _os_object_t
*tp
= (_os_object_t
*)__p
;
201 _os_object_t o
= *tp
;
208 #if __COREFOUNDATION__
210 * @define __os_cfrelease
211 * An attribute that may be applied to a variable's type. This attribute causes
212 * the variable to be passed to CFRelease() when it goes out of scope. Applying
213 * this attribute to a variable which does not reference a valid CoreFoundation
214 * object will result in undefined behavior. If the variable's value is NULL
215 * upon going out-of-scope, no cleanup is performed.
217 #define __os_cfrelease __attribute__((cleanup(__os_cleanup_cfrelease)))
219 __os_cleanup_cfrelease(void *__p
)
221 CFTypeRef
*tp
= (CFTypeRef
*)__p
;
228 #endif // __COREFOUNDATION__
230 #else // __has_attribute(cleanup)
231 #define __os_free __attribute__((__os_not_supported))
232 #define __os_close __attribute__((__os_not_supported))
233 #define __os_fclose __attribute__((__os_not_supported))
234 #define __os_close_mach_recv __attribute__((__os_not_supported))
235 #define __os_release_mach_send __attribute__((__os_not_supported))
236 #define __os_preserve_errno __attribute__((__os_not_supported))
237 #define __os_release __attribute__((__os_not_supported))
238 #define __os_cfrelease __attribute__((__os_not_supported))
239 #endif // __has_attribute(cleanup)
243 #endif // __DARWIN_CLEANUP_H