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.
Best regards,
Nicolai Tufar
Index: src/port/snprintf.c
===
RCS file: /projects/cvsroot/pgsql/src/port/snprintf.c,v
retrieving revision 1.7
diff -c -r1.7 snprintf.c
*** src/port/snprintf.c 28 Feb 2005 14:16:16 - 1.7
--- src/port/snprintf.c 28 Feb 2005 23:11:22 -
***
*** 82,105
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
! * causing nast 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;
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);
int
printf(const char *fmt,...)
{
int len;
va_list args;
! static char* buffer[4096];
char* p;
va_start(args, fmt);
--- 82,103
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
! * causing nasty effects.
**/
! /*static char _id[] = $PostgreSQL: pgsql/src/port/snprintf.c,v 1.6 2005/02/22 04:57:24 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, char *end);
int
printf(const char *fmt,...)
{
int len;
va_list args;
! char* buffer[4096];
char* p;
va_start(args, fmt);
***
*** 127,136
int
vsnprintf(char *str, size_t count, const char *fmt, va_list args)
{
str[0] = '\0';
end = str + count - 1;
! SnprfOverflow = 0;
! dopr(str, fmt, args);
if (count 0)
end[0] = '\0';
return strlen(str);
--- 125,134
int
vsnprintf(char *str, size_t count, const char *fmt, va_list args)
{
+ char *end;
str[0] = '\0';
end = str + count - 1;
! dopr(str, fmt, args, end);
if (count 0)
end[0] = '\0';
return strlen(str);
***
*** 140,150
* 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 char *output;
--- 138,148
* dopr(): poor man's version of doprintf
*/
! 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,160
#define FMTCHAR 4
static void
! dopr(char *buffer, const char *format, va_list args)
{
int ch;
long_long value;
--- 152,158
#define FMTCHAR 4
static void
! dopr(char *buffer, const char *format, va_list args, char *end)
{
int ch;
long_long value;
***
*** 417,427
case '%':
break;
default:
! dostr(???, 0);
}
break;
default:
! dopr_outch(ch);
break;
}
}
--- 415,425
case '%':
break;
default:
! dostr(???, 0, end);
}
break;
default:
! dopr_outch(ch, end);
break;
}
}
***
*** 448,474
case FMTSTR:
fmtstr(fmtparptr[i]-value, fmtparptr[i]-ljust,
fmtparptr[i]-len, fmtparptr[i]-zpad,
! fmtparptr[i]-maxwidth);
break;
case FMTNUM:
fmtnum(fmtparptr[i]-numvalue, fmtparptr[i]-base,
fmtparptr[i]-dosign, fmtparptr[i]-ljust,
! fmtparptr[i]-len, fmtparptr[i]-zpad);
break;
case FMTFLOAT:
fmtfloat(fmtparptr[i]-fvalue, fmtparptr[i]-type,
fmtparptr[i]-ljust, fmtparptr[i]-len,
! fmtparptr[i]-precision, fmtparptr[i]-pointflag);
break;
case FMTCHAR:
! dopr_outch(fmtparptr[i]-charvalue);
break;
}
format = fmtpar[i].fmtend;
goto nochar;
}
}
! dopr_outch(ch);
nochar:
/* nothing */
; /* semicolon required