And while we are on it, I would like to submit minor
authorBruce Momjian <bruce@momjian.us>
Tue, 1 Mar 2005 00:38:11 +0000 (00:38 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 1 Mar 2005 00:38:11 +0000 (00:38 +0000)
changes to make snprintf() vsnprintf() and printf()
functions in src/port/snprintf.c thread-safe.

Nicolai Tufar

src/port/snprintf.c

index 854bb624d4bc3725414600d676389f25d0a4e413..122f4f3ba68fba417ee3810fd32b633d56a7e7ab 100644 (file)
@@ -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++;
 }