Loading...
libdarwin/stdio.c /dev/null Libc-1725.40.4
--- /dev/null
+++ Libc/Libc-1725.40.4/libdarwin/stdio.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2018 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "internal.h"
+
+#pragma mark API
+int
+fcheck_np(FILE *f, size_t n, size_t expected)
+{
+	if (n == expected) {
+		return 0;
+	}
+	if (feof(f)) {
+		return EOF;
+	}
+	if (ferror(f)) {
+		return 1;
+	}
+	__builtin_unreachable();
+}
+
+os_fd_t
+dup_np(os_fd_t fd)
+{
+	os_fd_t dfd = -1;
+
+	while (true) {
+		dfd = dup(fd);
+
+		if (os_fd_valid(dfd)) {
+			break;
+		}
+
+		switch (errno) {
+		case EINTR:
+			break;
+		case EBADF:
+			os_crash("bad fd");
+		case EMFILE:
+		case ENFILE:
+			os_crash("failed to dup fd");
+		default:
+			os_crash("unhandled error: %s", symerror_np(errno));
+		}
+	}
+
+	return dfd;
+}
+
+os_fd_t
+claimfd_np(os_fd_t *fdp, const guardid_t *gdid, u_int gdflags)
+{
+	int ret = -1;
+	int fd = *fdp;
+
+	if (gdid) {
+		ret = change_fdguard_np(fd, NULL, 0, gdid, gdflags, NULL);
+		if (ret) {
+			os_crash("change_fdguard_np: %{darwin.errno}d", errno);
+		}
+	}
+
+	*fdp = -1;
+	return fd;
+}
+
+os_fd_t
+xferfd_np(os_fd_t *fdp, const guardid_t *gdid, u_int gdflags)
+{
+	int ret = -1;
+	int fd = *fdp;
+
+	ret = change_fdguard_np(fd, gdid, gdflags, NULL, 0, NULL);
+	if (ret) {
+		os_crash("change_fdguard_np: %{darwin.errno}d", errno);
+	}
+
+	*fdp = -1;
+	return fd;
+}
+
+void
+close_drop_np(os_fd_t *fdp, const guardid_t *gdid)
+{
+	int ret = -1;
+	int fd = *fdp;
+
+	if (gdid) {
+		ret = guarded_close_np(fd, gdid);
+	} else {
+		ret = close(fd);
+	}
+
+	posix_assert_zero(ret);
+	*fdp = -1;
+}
+
+void
+close_drop_optional_np(os_fd_t *fdp, const guardid_t *gdid)
+{
+	if (!os_fd_valid(*fdp)) {
+		return;
+	}
+	close_drop_np(fdp, gdid);
+}
+
+size_t
+zsnprintf_np(char *buff, size_t len, const char *fmt, ...)
+{
+	int np = 0;
+	va_list ap;
+
+	va_start(ap, fmt);
+	np = vsnprintf(buff, len, fmt, ap);
+	va_end(ap);
+
+	if (np < 0) {
+		np = 0;
+	} else if ((size_t)np >= len) {
+		np = (int)len - 1;
+	}
+
+	return (size_t)np;
+}
+
+void
+crfprintf_np(FILE *f, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vcrfprintf_np(f, fmt, ap);
+	va_end(ap);
+}
+
+void
+vcrfprintf_np(FILE *f, const char *fmt, va_list ap)
+{
+	vfprintf(f, fmt, ap);
+	fprintf(f, "\n");
+}
+
+void
+wfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width,
+		const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vwfprintf_np(f, initpad, pad, width, fmt, ap);
+	va_end(ap);
+}
+
+void
+vwfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width,
+		const char *fmt, va_list ap)
+{
+	char *__os_free string = NULL;
+	char *__os_free working = NULL;
+	char *__os_free init_padding = NULL;
+	char *__os_free padding = NULL;
+	const char *curline = NULL;;
+	size_t left = 0;
+	size_t initpad_labs = (size_t)labs(initpad);
+	int ret = -1;
+
+	if (width && width <= pad) {
+		os_crash("width cannot be smaller than pad");
+	}
+	if (width && (initpad > 0) && width <= initpad_labs) {
+		os_crash("width cannot be smaller than initpad");
+	}
+	if (width && (initpad < 0) && width <= initpad_labs) {
+		os_crash("width cannot be smaller than negative initpad");
+	}
+
+	ret = vasprintf(&string, fmt, ap);
+	if (ret < 0 || !string) {
+		return;
+	}
+
+	left = (size_t)ret;
+	curline = string;
+
+	// The working buffer will always be large enough to handle any individual
+	// line. vasprintf(3) returns the number of characters printed not including
+	// the null terminator, so add space for that.
+	working = malloc(left + 1);
+	if (!working) {
+		return;
+	}
+
+	init_padding = malloc(initpad_labs + 1);
+	if (!init_padding) {
+		return;
+	}
+
+	if (initpad >= 0) {
+		memset(init_padding, ' ', initpad);
+		init_padding[initpad] = 0;
+	} else {
+		init_padding[0] = 0;
+	}
+
+	padding = malloc(pad + 1);
+	if (!padding) {
+		return;
+	}
+
+	memset(padding, ' ', pad);
+	padding[pad] = 0;
+
+	do {
+		size_t which_pad = pad;
+		char *which_padding = padding;
+		bool findspace = true;
+		size_t n2consume = 0;
+		char *breakchar = NULL;
+
+		if (curline == string) {
+			which_padding = init_padding;
+			which_pad = initpad_labs;
+		}
+
+		if (width == 0) {
+			// Width is unconstrained so just consume the entire string and
+			// indent any new lines within.
+			n2consume = left;
+			findspace = false;
+		} else {
+			n2consume = width - which_pad;
+			if (n2consume >= left) {
+				n2consume = left;
+				findspace = false;
+			}
+		}
+
+		strlcpy(working, curline, n2consume + 1);
+		breakchar = strchr(working, '\n');
+		if (!breakchar && findspace) {
+			// No new line within our maximally-constrained width of characters,
+			// so search for a space instead.
+			breakchar = strrchr(working, ' ');
+		}
+
+		if (breakchar) {
+			// Found something to break on, so nerf it and only consume the
+			// characters up until that break character.
+			*breakchar = 0;
+			n2consume = (size_t)(breakchar - working);
+			curline += n2consume + 1;
+		}
+
+		fprintf(f, "%s%s\n", which_padding, working);
+		left -= n2consume;
+	} while (left);
+}