]>
git.saurik.com Git - apple/libc.git/blob - libdarwin/stdio.c
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@
27 fcheck_np(FILE *f
, size_t n
, size_t expected
)
38 __builtin_unreachable();
49 if (os_fd_valid(dfd
)) {
60 os_crash("failed to dup fd");
62 os_crash("unhandled error: %s", symerror_np(errno
));
70 claimfd_np(os_fd_t
*fdp
, const guardid_t
*gdid
, u_int gdflags
)
76 ret
= change_fdguard_np(fd
, NULL
, 0, gdid
, gdflags
, NULL
);
78 os_crash("change_fdguard_np: %{darwin.errno}d", errno
);
87 xferfd_np(os_fd_t
*fdp
, const guardid_t
*gdid
, u_int gdflags
)
92 ret
= change_fdguard_np(fd
, gdid
, gdflags
, NULL
, 0, NULL
);
94 os_crash("change_fdguard_np: %{darwin.errno}d", errno
);
102 close_drop_np(os_fd_t
*fdp
, const guardid_t
*gdid
)
108 ret
= guarded_close_np(fd
, gdid
);
113 posix_assert_zero(ret
);
118 close_drop_optional_np(os_fd_t
*fdp
, const guardid_t
*gdid
)
120 if (!os_fd_valid(*fdp
)) {
123 close_drop_np(fdp
, gdid
);
127 zsnprintf_np(char *buff
, size_t len
, const char *fmt
, ...)
133 np
= vsnprintf(buff
, len
, fmt
, ap
);
138 } else if ((size_t)np
>= len
) {
146 crfprintf_np(FILE *f
, const char *fmt
, ...)
151 vcrfprintf_np(f
, fmt
, ap
);
156 vcrfprintf_np(FILE *f
, const char *fmt
, va_list ap
)
158 vfprintf(f
, fmt
, ap
);
163 wfprintf_np(FILE *f
, ssize_t initpad
, size_t pad
, size_t width
,
164 const char *fmt
, ...)
169 vwfprintf_np(f
, initpad
, pad
, width
, fmt
, ap
);
174 vwfprintf_np(FILE *f
, ssize_t initpad
, size_t pad
, size_t width
,
175 const char *fmt
, va_list ap
)
177 char *__os_free string
= NULL
;
178 char *__os_free working
= NULL
;
179 char *__os_free init_padding
= NULL
;
180 char *__os_free padding
= NULL
;
181 const char *curline
= NULL
;;
183 size_t initpad_labs
= (size_t)labs(initpad
);
186 if (width
&& width
<= pad
) {
187 os_crash("width cannot be smaller than pad");
189 if (width
&& (initpad
> 0) && width
<= initpad_labs
) {
190 os_crash("width cannot be smaller than initpad");
192 if (width
&& (initpad
< 0) && width
<= initpad_labs
) {
193 os_crash("width cannot be smaller than negative initpad");
196 ret
= vasprintf(&string
, fmt
, ap
);
197 if (ret
< 0 || !string
) {
204 // The working buffer will always be large enough to handle any individual
205 // line. vasprintf(3) returns the number of characters printed not including
206 // the null terminator, so add space for that.
207 working
= malloc(left
+ 1);
212 init_padding
= malloc(initpad_labs
+ 1);
218 memset(init_padding
, ' ', initpad
);
219 init_padding
[initpad
] = 0;
224 padding
= malloc(pad
+ 1);
229 memset(padding
, ' ', pad
);
233 size_t which_pad
= pad
;
234 char *which_padding
= padding
;
235 bool findspace
= true;
236 size_t n2consume
= 0;
237 char *breakchar
= NULL
;
239 if (curline
== string
) {
240 which_padding
= init_padding
;
241 which_pad
= initpad_labs
;
245 // Width is unconstrained so just consume the entire string and
246 // indent any new lines within.
250 n2consume
= width
- which_pad
;
251 if (n2consume
>= left
) {
257 strlcpy(working
, curline
, n2consume
+ 1);
258 breakchar
= strchr(working
, '\n');
259 if (!breakchar
&& findspace
) {
260 // No new line within our maximally-constrained width of characters,
261 // so search for a space instead.
262 breakchar
= strrchr(working
, ' ');
266 // Found something to break on, so nerf it and only consume the
267 // characters up until that break character.
269 n2consume
= (size_t)(breakchar
- working
);
270 curline
+= n2consume
+ 1;
273 fprintf(f
, "%s%s\n", which_padding
, working
);