Loading...
--- Libc/Libc-1725.40.4/stdio/FreeBSD/vfprintf.c
+++ Libc/Libc-825.26/stdio/FreeBSD/vfprintf.c
@@ -30,14 +30,6 @@
* SUCH DAMAGE.
*/
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wint-conversion"
-
-#include <TargetConditionals.h>
-#if !TARGET_OS_DRIVERKIT
-#define OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE 1
-#endif
-
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
@@ -72,20 +64,13 @@
#include <stdarg.h>
#include "un-namespace.h"
-#include <os/assumes.h>
-#include <mach-o/dyld_priv.h>
-#include <mach/mach.h>
-
#include "libc_private.h"
#include "local.h"
#include "fvwrite.h"
#include "printflocal.h"
-#include "libc_hooks_impl.h"
static int __sprint(FILE *, locale_t, struct __suio *);
-#if 0
static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0);
-#endif
static char *__wcsconv(wchar_t *, int, locale_t);
__private_extern__ const char *__fix_nogrouping(const char *);
@@ -181,7 +166,6 @@
return (err);
}
-#if 0
/*
* Helper function for `fprintf to unbuffered unix file': creates a
* temporary buffer. We only work on write-only files; this avoids
@@ -222,7 +206,6 @@
fp->_flags |= __SERR;
return (ret);
}
-#endif
/*
* Convert a wide character string argument for the %ls format to a multibyte
@@ -292,10 +275,14 @@
{
int ret;
- libc_hooks_will_write(fp, sizeof(*fp));
-
+ NORMALIZE_LOCALE(loc);
FLOCKFILE(fp);
- ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, loc, fmt0, ap);
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0)
+ ret = __sbprintf(fp, loc, fmt0, ap);
+ else
+ ret = __vfprintf(fp, loc, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
@@ -304,14 +291,7 @@
vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
{
- int ret;
-
- libc_hooks_will_write(fp, sizeof(*fp));
-
- FLOCKFILE(fp);
- ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, __current_locale(), fmt0, ap);
- FUNLOCKFILE(fp);
- return ret;
+ return vfprintf_l(fp, __current_locale(), fmt0, ap);
}
/*
@@ -325,26 +305,6 @@
#error "BUF must be large enough to format a uintmax_t"
#endif
-__private_extern__ bool
-__printf_is_memory_read_only(void *addr, size_t __unused size)
-{
- vm_address_t address = addr;
- vm_size_t vmsize = 0;
- vm_region_basic_info_data_64_t info;
- mach_msg_type_number_t info_cnt = VM_REGION_BASIC_INFO_COUNT_64;
- memory_object_name_t object = MACH_PORT_NULL;
- kern_return_t kr = KERN_SUCCESS;
-
- kr = vm_region_64(mach_task_self(),
- &address,
- &vmsize,
- VM_REGION_BASIC_INFO_64,
- (vm_region_info_t) &info,
- &info_cnt,
- &object);
- return (kr == KERN_SUCCESS) && !(info.protection & VM_PROT_WRITE);
-}
-
/*
* Non-MT-safe version
*/
@@ -353,18 +313,14 @@
{
char *fmt; /* format string */
int ch; /* character from fmt */
- ssize_t n, n2; /* handy integer (short term usage) */
+ int n, n2; /* handy integer (short term usage) */
char *cp; /* handy char pointer (short term usage) */
int flags; /* flags as above */
- ssize_t ret; /* return value accumulator */
- ssize_t width; /* width from format (%8d), or 0 */
- ssize_t prec; /* precision from format; <0 for N/A */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format; <0 for N/A */
char sign; /* sign prefix (' ', '+', '-', or \0) */
struct grouping_state gs; /* thousands' grouping info */
-
-#ifndef ALLOW_DYNAMIC_PERCENT_N
- bool static_format_checked = false;
-#endif // ALLOW_DYNAMIC_PERCENT_N
#ifndef NO_FLOATING_POINT
/*
@@ -405,9 +361,9 @@
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
int base; /* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
- ssize_t realsz; /* field size expanded by dprec, sign, etc */
- ssize_t size; /* size of converted field or string */
- ssize_t prsize; /* max size of printed field */
+ int realsz; /* field size expanded by dprec, sign, etc */
+ int size; /* size of converted field or string */
+ int prsize; /* max size of printed field */
const char *xdigs; /* digits for %[xX] conversion */
struct io_state io; /* I/O buffering state */
char buf[BUF]; /* buffer with space for digits of uintmax_t */
@@ -502,15 +458,19 @@
val = GETARG (int); \
}
- /* The following has been moved to __v2printf() */
-#if 0
+#if 0 // xprintf pending API review
+ if (__use_xprintf == 0 && getenv("USE_XPRINTF"))
+ __use_xprintf = 1;
+ if (__use_xprintf > 0)
+ return (__xvprintf(fp, loc, fmt0, ap));
+#endif
+
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
if (prepwrite(fp) != 0) {
errno = EBADF;
return (EOF);
}
ORIENT(fp, -1);
-#endif
convbuf = NULL;
fmt = (char *)fmt0;
@@ -533,9 +493,8 @@
for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
/* void */;
if ((n = fmt - cp) != 0) {
- if (ret + n >= INT_MAX) {
+ if ((unsigned)ret + n > INT_MAX) {
ret = EOF;
- errno = EOVERFLOW;
goto error;
}
PRINT(cp, n);
@@ -875,37 +834,22 @@
void *ptr = GETARG(void *);
if (ptr == NULL)
continue;
-
-#ifndef ALLOW_DYNAMIC_PERCENT_N
- if (!static_format_checked) {
- static_format_checked = __printf_is_memory_read_only((void*)fmt0, strlen(fmt0));
- }
- if (!static_format_checked) {
-#if OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE
- os_crash("%%n used in a non-immutable format string: %s", fmt0);
-#else
- os_crash("%%n used in a non-immutable format string");
-#endif
- }
-#endif // ALLOW_DYNAMIC_PERCENT_N
-
- if (flags & LLONGINT) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, long long, ret);
- } else if (flags & SIZET) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, ssize_t, ret);
- } else if (flags & PTRDIFFT) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, ptrdiff_t, ret);
- } else if (flags & INTMAXT) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, intmax_t, ret);
- } else if (flags & LONGINT) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, long, ret);
- } else if (flags & SHORTINT) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, short, ret);
- } else if (flags & CHARINT) {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, signed char, ret);
- } else {
- LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, int, ret);
- }
+ else if (flags & LLONGINT)
+ *(long long *)ptr = ret;
+ else if (flags & SIZET)
+ *(ssize_t *)ptr = (ssize_t)ret;
+ else if (flags & PTRDIFFT)
+ *(ptrdiff_t *)ptr = ret;
+ else if (flags & INTMAXT)
+ *(intmax_t *)ptr = ret;
+ else if (flags & LONGINT)
+ *(long *)ptr = ret;
+ else if (flags & SHORTINT)
+ *(short *)ptr = ret;
+ else if (flags & CHARINT)
+ *(signed char *)ptr = ret;
+ else
+ *(int *)ptr = ret;
continue; /* no output */
}
case 'O':
@@ -947,11 +891,11 @@
if (flags & LONGINT) {
wchar_t *wcp;
- free(convbuf);
- if ((wcp = GETARG(wchar_t *)) == NULL) {
- convbuf = NULL;
+ if (convbuf != NULL)
+ free(convbuf);
+ if ((wcp = GETARG(wchar_t *)) == NULL)
cp = "(null)";
- } else {
+ else {
convbuf = __wcsconv(wcp, prec, loc);
if (convbuf == NULL) {
fp->_flags |= __SERR;
@@ -961,16 +905,7 @@
}
} else if ((cp = GETARG(char *)) == NULL)
cp = "(null)";
- {
- size_t cp_len = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
- if (cp_len < INT_MAX) {
- size = cp_len;
- } else {
- ret = EOF;
- goto error;
- }
- libc_hooks_will_read(cp, size);
- }
+ size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
sign = '\0';
break;
case 'U':
@@ -1042,7 +977,7 @@
}
size = buf + BUF - cp;
if (size > BUF) /* should never happen */
- LIBC_ABORT("size (%zd) > BUF (%d)", size, BUF);
+ LIBC_ABORT("size (%d) > BUF (%d)", size, BUF);
if ((flags & GROUPING) && size != 0)
size += grouping_init(&gs, size, loc);
break;
@@ -1367,9 +1302,8 @@
realsz += 2;
prsize = width > realsz ? width : realsz;
- if (ret + prsize >= INT_MAX) {
+ if ((unsigned)ret + prsize > INT_MAX) {
ret = EOF;
- errno = EOVERFLOW;
goto error;
}
@@ -1457,12 +1391,13 @@
if (dtoaresult != NULL)
freedtoa(dtoaresult);
#endif
- free(convbuf);
+ if (convbuf != NULL)
+ free(convbuf);
if (__sferror(fp))
ret = EOF;
if ((argtable != NULL) && (argtable != statargtable))
free (argtable);
- return (ret < 0 || ret >= INT_MAX) ? -1 : (int)ret;
+ return (ret);
/* NOTREACHED */
}
-#pragma clang diagnostic pop
+