From 295dd338c37f9b9710c25c421bbc2f366ec6d94f Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 1 Mar 2005 00:38:11 +0000 Subject: [PATCH] And while we are on it, I would like to submit minor changes to make snprintf() vsnprintf() and printf() functions in src/port/snprintf.c thread-safe. Nicolai Tufar --- src/port/snprintf.c | 81 ++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/src/port/snprintf.c b/src/port/snprintf.c index 854bb624d4..122f4f3ba6 100644 --- a/src/port/snprintf.c +++ b/src/port/snprintf.c @@ -82,24 +82,22 @@ typedef unsigned long ulong_long; * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from - * causing nast effects. + * causing nasty effects. **************************************************************/ -/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.7 2005/02/28 14:16:16 momjian Exp $";*/ -static char *end; -static int SnprfOverflow; +/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.8 2005/03/01 00:38:11 momjian Exp $";*/ int snprintf(char *str, size_t count, const char *fmt,...); int vsnprintf(char *str, size_t count, const char *fmt, va_list args); int printf(const char *format, ...); -static void dopr(char *buffer, const char *format, va_list args); +static void dopr(char *buffer, const char *format, va_list args, char *end); int printf(const char *fmt,...) { int len; va_list args; - static char* buffer[4096]; + char* buffer[4096]; char* p; va_start(args, fmt); @@ -127,10 +125,10 @@ snprintf(char *str, size_t count, const char *fmt,...) int vsnprintf(char *str, size_t count, const char *fmt, va_list args) { + char *end; str[0] = '\0'; end = str + count - 1; - SnprfOverflow = 0; - dopr(str, fmt, args); + dopr(str, fmt, args, end); if (count > 0) end[0] = '\0'; return strlen(str); @@ -140,11 +138,11 @@ vsnprintf(char *str, size_t count, const char *fmt, va_list args) * dopr(): poor man's version of doprintf */ -static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth); -static void fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad); -static void fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag); -static void dostr(char *str, int cut); -static void dopr_outch(int c); +static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end); +static void fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad, char *end); +static void fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end); +static void dostr(char *str, int cut, char *end); +static void dopr_outch(int c, char *end); static char *output; @@ -154,7 +152,7 @@ static char *output; #define FMTCHAR 4 static void -dopr(char *buffer, const char *format, va_list args) +dopr(char *buffer, const char *format, va_list args, char *end) { int ch; long_long value; @@ -417,11 +415,11 @@ dopr(char *buffer, const char *format, va_list args) case '%': break; default: - dostr("???????", 0); + dostr("???????", 0, end); } break; default: - dopr_outch(ch); + dopr_outch(ch, end); break; } } @@ -448,27 +446,28 @@ performpr: case FMTSTR: fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust, fmtparptr[i]->len, fmtparptr[i]->zpad, - fmtparptr[i]->maxwidth); + fmtparptr[i]->maxwidth, end); break; case FMTNUM: fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base, fmtparptr[i]->dosign, fmtparptr[i]->ljust, - fmtparptr[i]->len, fmtparptr[i]->zpad); + fmtparptr[i]->len, fmtparptr[i]->zpad, end); break; case FMTFLOAT: fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type, fmtparptr[i]->ljust, fmtparptr[i]->len, - fmtparptr[i]->precision, fmtparptr[i]->pointflag); + fmtparptr[i]->precision, fmtparptr[i]->pointflag, + end); break; case FMTCHAR: - dopr_outch(fmtparptr[i]->charvalue); + dopr_outch(fmtparptr[i]->charvalue, end); break; } format = fmtpar[i].fmtend; goto nochar; } } - dopr_outch(ch); + dopr_outch(ch, end); nochar: /* nothing */ ; /* semicolon required because a goto has to be attached to a statement */ @@ -477,7 +476,7 @@ nochar: } static void -fmtstr(char *value, int ljust, int len, int zpad, int maxwidth) +fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end) { int padlen, strlen; /* amount to pad */ @@ -494,19 +493,19 @@ fmtstr(char *value, int ljust, int len, int zpad, int maxwidth) padlen = -padlen; while (padlen > 0) { - dopr_outch(' '); + dopr_outch(' ', end); --padlen; } - dostr(value, maxwidth); + dostr(value, maxwidth, end); while (padlen < 0) { - dopr_outch(' '); + dopr_outch(' ', end); ++padlen; } } static void -fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad) +fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad, char *end) { int signvalue = 0; ulong_long uvalue; @@ -561,34 +560,34 @@ fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad) { if (signvalue) { - dopr_outch(signvalue); + dopr_outch(signvalue, end); --padlen; signvalue = 0; } while (padlen > 0) { - dopr_outch(zpad); + dopr_outch(zpad, end); --padlen; } } while (padlen > 0) { - dopr_outch(' '); + dopr_outch(' ', end); --padlen; } if (signvalue) - dopr_outch(signvalue); + dopr_outch(signvalue, end); while (place > 0) - dopr_outch(convert[--place]); + dopr_outch(convert[--place], end); while (padlen < 0) { - dopr_outch(' '); + dopr_outch(' ', end); ++padlen; } } static void -fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag) +fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end) { char fmt[32]; char convert[512]; @@ -615,34 +614,34 @@ fmtfloat(double value, char type, int ljust, int len, int precision, int pointfl while (padlen > 0) { - dopr_outch(' '); + dopr_outch(' ', end); --padlen; } - dostr(convert, 0); + dostr(convert, 0, end); while (padlen < 0) { - dopr_outch(' '); + dopr_outch(' ', end); ++padlen; } } static void -dostr(char *str, int cut) +dostr(char *str, int cut, char *end) { if (cut) { while (*str && cut-- > 0) - dopr_outch(*str++); + dopr_outch(*str++, end); } else { while (*str) - dopr_outch(*str++); + dopr_outch(*str++, end); } } static void -dopr_outch(int c) +dopr_outch(int c, char *end) { #ifdef NOT_USED if (iscntrl((unsigned char) c) && c != '\n' && c != '\t') @@ -654,6 +653,4 @@ dopr_outch(int c) #endif if (end == 0 || output < end) *output++ = c; - else - SnprfOverflow++; } -- GitLab