diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2012-06-26 14:53:24 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2012-06-26 14:53:24 +0000 |
commit | 98d4eeada8bec1625d6a480d3139018eb12b9abd (patch) | |
tree | 874b69c1bd0dc872cdefec19d63fa2f9f1faa14a /lib/libc/stdio | |
parent | d14eab152633551a34c3058feb21fd6030c5a822 (diff) |
Use nl_langinfo(RADIXCHAR) instead of localeconv()->decimal_point in
printf() and avoid calling it unless needed (i.e., when we have a
floating point value to print). This isn't a big concern currently
due to our limited locale support and current localeconv()
implementation, but it's still technically a data race and
implementing POSIX 2008 per-thread locales is likely to make it worse.
nl_langinfo() isn't guaranteed by POSIX to be thread-safe either, but
at least our current implementation is thread-safe and it's a simpler
interface to keep that way. Printing floating point values isn't
async-signal-safe anyway due to gdtoa()'s use of malloc(), so that's
not an issue.
ok deraadt, stsp, millert
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r-- | lib/libc/stdio/vfprintf.c | 7 | ||||
-rw-r--r-- | lib/libc/stdio/vfwprintf.c | 7 |
2 files changed, 10 insertions, 4 deletions
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 8deb37f40f9..b85f9a5a901 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfprintf.c,v 1.61 2011/07/06 19:53:52 stsp Exp $ */ +/* $OpenBSD: vfprintf.c,v 1.62 2012/06/26 14:53:23 matthew Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -41,6 +41,7 @@ #include <sys/mman.h> #include <errno.h> +#include <langinfo.h> #include <limits.h> #include <stdarg.h> #include <stddef.h> @@ -299,7 +300,7 @@ __vfprintf(FILE *fp, const char *fmt0, __va_list ap) * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ - char *decimal_point = localeconv()->decimal_point; + char *decimal_point = NULL; int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; @@ -1014,6 +1015,8 @@ number: if ((dprec = prec) >= 0) if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ + if (decimal_point == NULL) + decimal_point = nl_langinfo(RADIXCHAR); if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c index b58985dd1ba..0619772323d 100644 --- a/lib/libc/stdio/vfwprintf.c +++ b/lib/libc/stdio/vfwprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfwprintf.c,v 1.4 2011/05/09 19:49:51 stsp Exp $ */ +/* $OpenBSD: vfwprintf.c,v 1.5 2012/06/26 14:53:23 matthew Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -41,6 +41,7 @@ #include <sys/mman.h> #include <errno.h> +#include <langinfo.h> #include <limits.h> #include <stdarg.h> #include <stddef.h> @@ -302,7 +303,7 @@ __vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, __va_list ap) * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ - char *decimal_point = localeconv()->decimal_point; + char *decimal_point = NULL; int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; @@ -996,6 +997,8 @@ number: if ((dprec = prec) >= 0) if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ + if (decimal_point == NULL) + decimal_point = nl_langinfo(RADIXCHAR); if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); |