]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2018 Apple 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 | ||
24 | /*! | |
25 | * @header | |
26 | * Non-standard, Darwin-specific additions for the stdio(3) family of APIs. | |
27 | */ | |
28 | #ifndef __DARWIN_STDIO_H | |
29 | #define __DARWIN_STDIO_H | |
30 | ||
31 | #include <os/base.h> | |
32 | #include <os/api.h> | |
33 | #include <sys/cdefs.h> | |
34 | #include <stdint.h> | |
35 | #include <stdbool.h> | |
36 | #include <stdio.h> | |
37 | #include <unistd.h> | |
38 | #include <sys/types.h> | |
39 | ||
40 | #if __has_include(<sys/guarded.h>) | |
41 | #include <sys/guarded.h> | |
42 | #else | |
43 | typedef uint64_t guardid_t; | |
44 | #endif | |
45 | ||
46 | #if DARWIN_TAPI | |
47 | #include "tapi.h" | |
48 | #endif | |
49 | ||
50 | __BEGIN_DECLS; | |
51 | ||
52 | /*! | |
53 | * @typedef os_fd_t | |
54 | * A type alias for a file descriptor. | |
55 | */ | |
56 | typedef int os_fd_t; | |
57 | ||
58 | /*! | |
59 | * @function os_fd_valid | |
60 | * Returns whether the given integer is a valid file descriptor number. | |
61 | * | |
62 | * @param fd | |
63 | * The integer to check. | |
64 | * | |
65 | * @result | |
66 | * A Boolean indicating whether the integer is a valid file descriptor number, | |
67 | * that is, greater than or equal to zero. | |
68 | */ | |
69 | DARWIN_API_AVAILABLE_20180727 | |
70 | OS_ALWAYS_INLINE OS_WARN_RESULT | |
71 | static inline bool | |
72 | os_fd_valid(os_fd_t fd) | |
73 | { | |
74 | return (fd >= STDIN_FILENO); | |
75 | } | |
76 | ||
77 | /*! | |
78 | * @function os_guardid_from_ptr | |
79 | * Converts the given pointer to a guardid_t. | |
80 | * | |
81 | * @param p | |
82 | * The pointer to convert. | |
83 | * | |
84 | * @result | |
85 | * The pointer as a guardid_t. | |
86 | */ | |
87 | DARWIN_API_AVAILABLE_20190830 | |
88 | OS_ALWAYS_INLINE OS_WARN_RESULT | |
89 | static inline guardid_t | |
90 | os_guardid_from_ptr(const void *p) | |
91 | { | |
92 | return (guardid_t)(uintptr_t)p; | |
93 | } | |
94 | ||
95 | /*! | |
96 | * @function fcheck_np | |
97 | * Checks the status of an fread(3) or fwrite(3) operation to a FILE. | |
98 | * | |
99 | * @param f | |
100 | * The file on which the operation was performed. | |
101 | * | |
102 | * @param n | |
103 | * The return value of the operation. | |
104 | * | |
105 | * @param expected | |
106 | * The expected return value of the operation. | |
107 | * | |
108 | * @result | |
109 | * One of the following integers: | |
110 | * | |
111 | * 0 The operation succeeded | |
112 | * EOF The operation encountered the end of the FILE stream before it | |
113 | * could complete | |
114 | * 1 There was an error | |
115 | */ | |
116 | DARWIN_API_AVAILABLE_20180727 | |
117 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 | |
118 | int | |
119 | fcheck_np(FILE *f, size_t n, size_t expected); | |
120 | ||
121 | /*! | |
122 | * @function dup_np | |
123 | * Variant of dup(2) that guarantees the dup(2) operation will either succeed or | |
124 | * not return. | |
125 | * | |
126 | * @param fd | |
127 | * The descriptor to dup(2). | |
128 | * | |
129 | * @result | |
130 | * A new file descriptor number that is functionally equivalent to what the | |
131 | * caller passed. | |
132 | * | |
133 | * @discussion | |
134 | * The implementation will retry if the operation was interrupted by a signal. | |
135 | * If the operation failed for any other reason, the implementation will | |
136 | * terminate the caller. | |
137 | */ | |
138 | DARWIN_API_AVAILABLE_20180727 | |
139 | OS_EXPORT OS_WARN_RESULT | |
140 | os_fd_t | |
141 | dup_np(os_fd_t fd); | |
142 | ||
143 | /*! | |
144 | * @function claimfd_np | |
145 | * Claims the given file descriptor for the caller's exclusive use by applying a | |
146 | * guard and invalidating the given storage. | |
147 | * | |
148 | * @param fdp | |
149 | * A pointer to the storage for the descriptor to claim. Upon return, a known- | |
150 | * invalid value is written into this memory. | |
151 | * | |
152 | * @param gdid | |
153 | * The optional guard value to enforce the caller's claim on the descriptor. | |
154 | * | |
155 | * @param gdflags | |
156 | * The guard flags to enforce the caller's claim on the descriptor. | |
157 | * | |
158 | * @result | |
159 | * The given descriptor with the guard applied. | |
160 | */ | |
161 | DARWIN_API_AVAILABLE_20190830 | |
162 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 | |
163 | os_fd_t | |
164 | claimfd_np(os_fd_t *fdp, const guardid_t *gdid, u_int gdflags); | |
165 | ||
166 | /*! | |
167 | * @function xferfd_np | |
168 | * Transfers ownership from the given file descriptor back to the general public | |
169 | * by clearing the guard associated with it. | |
170 | * | |
171 | * @param fdp | |
172 | * A pointer to the storage for the descriptor to claim. Upon return, a known- | |
173 | * invalid value is written into this memory. | |
174 | * | |
175 | * @param gdid | |
176 | * The optional guard value to reliquish ownership on the descriptor. | |
177 | * | |
178 | * @param gdflags | |
179 | * The guard flags to relinquish. | |
180 | * | |
181 | * @result | |
182 | * The given descriptor with the guard cleared. This descriptor is suitable for | |
183 | * claiming with {@link claimfd_np}. | |
184 | */ | |
185 | DARWIN_API_AVAILABLE_20190830 | |
186 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 | |
187 | os_fd_t | |
188 | xferfd_np(os_fd_t *fdp, const guardid_t *gdid, u_int gdflags); | |
189 | ||
190 | /*! | |
191 | * @function close_drop_np | |
192 | * Variant of close(2) which transfers ownership from the caller and performs | |
193 | * the close(2) operation. These semantics are useful for ensuring that a | |
194 | * descriptor is not erroneously re-used after it has been closed. To achieve | |
195 | * these semantics, this variant will clear the memory in which the descriptor | |
196 | * resides and replace it with a known-invalid value before returning. | |
197 | * | |
198 | * @param fdp | |
199 | * A pointer to the storage for the descriptor to close. Upon return, a known- | |
200 | * invalid value is written into this memory. | |
201 | * | |
202 | * @param gdid | |
203 | * The optional guard. If the descriptor is not guarded, pass NULL. | |
204 | * | |
205 | * @discussion | |
206 | * If the implementation encounters a failure to close a valid descriptor | |
207 | * number, the caller will be terminated. | |
208 | */ | |
209 | OS_EXPORT OS_NONNULL1 | |
210 | void | |
211 | close_drop_np(os_fd_t *fdp, const guardid_t *gdid); | |
212 | ||
213 | /*! | |
214 | * @function close_drop_optional_np | |
215 | * Variant of {@link close_drop} which will not attempt to close an invalid | |
216 | * descriptor. Otherwise all semantics are the same. | |
217 | * | |
218 | * @param fdp | |
219 | * A pointer to the storage for the descriptor to close. Upon return, a known- | |
220 | * invalid value is written into this memory. | |
221 | * | |
222 | * @param gdid | |
223 | * The optional guard. If the descriptor is not guarded, pass NULL. | |
224 | * | |
225 | * @discussion | |
226 | * If the implementation encounters a failure to close a valid descriptor | |
227 | * number, the caller will be terminated. The implementation will not attempt to | |
228 | * close the descriptor if its value is -1. | |
229 | */ | |
230 | OS_EXPORT OS_NONNULL1 | |
231 | void | |
232 | close_drop_optional_np(os_fd_t *fdp, const guardid_t *gdid); | |
233 | ||
234 | /*! | |
235 | * @function zsnprintf_np | |
236 | * snprintf(3) variant which returns the numnber of bytes written less the null | |
237 | * terminator. | |
238 | * | |
239 | * @param buff | |
240 | * The buffer in which to write the string. | |
241 | * | |
242 | * @param len | |
243 | * The length of the buffer. | |
244 | * | |
245 | * @param fmt | |
246 | * The printf(3)-like format string. | |
247 | * | |
248 | * @param ... | |
249 | * The arguments corresponding to the format string. | |
250 | * | |
251 | * @result | |
252 | * The number of bytes written into the buffer, less the null terminator. This | |
253 | * routine is useful for successive string printing that may be lossy, as it | |
254 | * will simply return zero when there is no space left in the destination | |
255 | * buffer, i.e. enables the following pattern: | |
256 | * | |
257 | * char *cur = buff; | |
258 | * size_t left = sizeof(buff); | |
259 | * for (i = 0; i < n_strings; i++) { | |
260 | * size_t n_written = zsnprintf_np(buff, left, "%s", strings[i]); | |
261 | * cur += n_written; | |
262 | * left -= n_written; | |
263 | * } | |
264 | * | |
265 | * This loop will safely terminate without any special care since, as soon as | |
266 | * the buffer's space is exhausted, all further calls to zsnprintf_np() will | |
267 | * write nothing and return zero. | |
268 | */ | |
269 | DARWIN_API_AVAILABLE_20170407 | |
270 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3 OS_FORMAT_PRINTF(3, 4) | |
271 | size_t | |
272 | zsnprintf_np(char *buff, size_t len, const char *fmt, ...); | |
273 | ||
274 | /*! | |
275 | * @function crfprintf_np | |
276 | * fprintf(3) variant that appends a new line character to the output. | |
277 | * | |
278 | * @param f | |
279 | * The file to which the output should be written. | |
280 | * | |
281 | * @param fmt | |
282 | * The printf(3)-like format string. | |
283 | * | |
284 | * @param ... | |
285 | * The arguments corresponding to the format string. | |
286 | */ | |
287 | DARWIN_API_AVAILABLE_20181020 | |
288 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_FORMAT_PRINTF(2, 3) | |
289 | void | |
290 | crfprintf_np(FILE *f, const char *fmt, ...); | |
291 | ||
292 | /*! | |
293 | * @function vcrfprintf_np | |
294 | * vfprintf(3) variant that appends a new line character to the output. | |
295 | * | |
296 | * @param f | |
297 | * The file to which the output should be written. | |
298 | * | |
299 | * @param fmt | |
300 | * The printf(3)-like format string. | |
301 | * | |
302 | * @param ap | |
303 | * The argument list corresponding to the format string. | |
304 | */ | |
305 | DARWIN_API_AVAILABLE_20181020 | |
306 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 | |
307 | void | |
308 | vcrfprintf_np(FILE *f, const char *fmt, va_list ap); | |
309 | ||
310 | /*! | |
311 | * @function wfprintf_np | |
312 | * fprintf(3) variant which wraps the output to the specified column width, | |
313 | * inserting new lines as necessary. Output will be word-wrapped with a trivial | |
314 | * algorithm. | |
315 | * | |
316 | * @param f | |
317 | * The file to which the output should be written. | |
318 | * | |
319 | * @param initpad | |
320 | * The number of spaces that should be inserted prior to the first line of | |
321 | * output. If a negative value is given, the implementation will assume that an | |
322 | * amount of spaces equal to the absolute value of the parameter has already | |
323 | * been written, and therefore it will only use the parameter to compute line- | |
324 | * wrapping information and not insert any additional spaces on the first line | |
325 | * of output. | |
326 | * | |
327 | * @param pad | |
328 | * The number of spaces that should be inserted prior to every line of output | |
329 | * except the first line. | |
330 | * | |
331 | * @param width | |
332 | * The maximum number of columns of each line of output. Pass zero to indicate | |
333 | * that there is no maximum. | |
334 | * | |
335 | * @param fmt | |
336 | * The printf(3)-like format string. | |
337 | * | |
338 | * @param ... | |
339 | * The arguments corresponding to the format string. | |
340 | * | |
341 | * @discussion | |
342 | * This routine will silently fail to print to the desired output stream if | |
343 | * there was a failure to allocate heap memory. | |
344 | */ | |
345 | DARWIN_API_AVAILABLE_20181020 | |
346 | OS_EXPORT OS_NONNULL1 OS_NONNULL5 OS_NONNULL6 | |
347 | void | |
348 | wfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width, | |
349 | const char *fmt, ...); | |
350 | ||
351 | /*! | |
352 | * @function vwfprintf_np | |
353 | * vfprintf(3) variant which wraps the output to the specified column width, | |
354 | * inserting new lines as necessary. Output will be word-wrapped with a trivial | |
355 | * algorithm. | |
356 | * | |
357 | * @param f | |
358 | * The file to which the output should be written. | |
359 | * | |
360 | * @param initpad | |
361 | * The number of spaces that should be inserted prior to the first line of | |
362 | * output. If a negative value is given, the implementation will assume that an | |
363 | * amount of spaces equal to the absolute value of the parameter has already | |
364 | * been written, and therefore it will only use the parameter to compute line- | |
365 | * wrapping information and not insert any additional spaces on the first line | |
366 | * of output. | |
367 | * | |
368 | * @param pad | |
369 | * The number of spaces that should be inserted prior to every line of output | |
370 | * except the first line. | |
371 | * | |
372 | * @param width | |
373 | * The maximum number of columns of each line of output. Pass zero to indicate | |
374 | * that there is no maximum. | |
375 | * | |
376 | * @param fmt | |
377 | * The printf(3)-like format string. | |
378 | * | |
379 | * @param ap | |
380 | * The argument list corresponding to the format string. | |
381 | * | |
382 | * @discussion | |
383 | * This routine will silently fail to print to the desired output stream if | |
384 | * there was a failure to allocate heap memory. | |
385 | */ | |
386 | DARWIN_API_AVAILABLE_20181020 | |
387 | OS_EXPORT OS_NONNULL1 OS_NONNULL5 OS_NONNULL6 | |
388 | void | |
389 | vwfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width, | |
390 | const char *fmt, va_list ap); | |
391 | ||
392 | __END_DECLS; | |
393 | ||
394 | #endif // __DARWIN_STDIO_H |