Thread-safe snprintf() vsnprintf() and printf()

Nicolai Tufar <[email protected]>
Newsgroups gmane.comp.db.postgresql.devel.win32,gmane.comp.db.postgresql.devel.general,gmane.comp.db.postgresql.devel.patches
Message-ID <[email protected]>
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


---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [email protected]
snprintf.diff (text/x-patch, 9.1 KB)
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 -0000	1.7
--- src/port/snprintf.c	28 Feb 2005 23:11:22 -0000
***************
*** 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 because a goto has to be attached to a statement */
--- 446,473 ----
  				case FMTSTR:
  					fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust,
  						fmtparptr[i]->len, fmtparptr[i]->zpad,
! 						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, end);
  					break;
  				case FMTFLOAT:
  					fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type,
  						fmtparptr[i]->ljust, fmtparptr[i]->len,
! 						fmtparptr[i]->precision, fmtparptr[i]->pointflag,
! 						end);
  					break;
  				case FMTCHAR:
! 					dopr_outch(fmtparptr[i]->charvalue, end);
  					break;
  				}
  				format = fmtpar[i].fmtend;
  				goto nochar;
  			}
  		}
! 		dopr_outch(ch, end);
  nochar:
  	/* nothing */
  	; /* semicolon required because a goto has to be attached to a statement */
***************
*** 477,483 ****
  }
  
  static void
! fmtstr(char *value, int ljust, int len, int zpad, int maxwidth)
  {
  	int			padlen,
  				strlen;			/* amount to pad */
--- 476,482 ----
  }
  
  static void
! fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end)
  {
  	int			padlen,
  				strlen;			/* amount to pad */
***************
*** 494,512 ****
  		padlen = -padlen;
  	while (padlen > 0)
  	{
! 		dopr_outch(' ');
  		--padlen;
  	}
! 	dostr(value, maxwidth);
  	while (padlen < 0)
  	{
! 		dopr_outch(' ');
  		++padlen;
  	}
  }
  
  static void
! fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad)
  {
  	int			signvalue = 0;
  	ulong_long	uvalue;
--- 493,511 ----
  		padlen = -padlen;
  	while (padlen > 0)
  	{
! 		dopr_outch(' ', end);
  		--padlen;
  	}
! 	dostr(value, maxwidth, end);
  	while (padlen < 0)
  	{
! 		dopr_outch(' ', end);
  		++padlen;
  	}
  }
  
  static void
! fmtnum(long_long value, int base, int dosign, int ljust, int len, int zpad, char *end)
  {
  	int			signvalue = 0;
  	ulong_long	uvalue;
***************
*** 561,594 ****
  	{
  		if (signvalue)
  		{
! 			dopr_outch(signvalue);
  			--padlen;
  			signvalue = 0;
  		}
  		while (padlen > 0)
  		{
! 			dopr_outch(zpad);
  			--padlen;
  		}
  	}
  	while (padlen > 0)
  	{
! 		dopr_outch(' ');
  		--padlen;
  	}
  	if (signvalue)
! 		dopr_outch(signvalue);
  	while (place > 0)
! 		dopr_outch(convert[--place]);
  	while (padlen < 0)
  	{
! 		dopr_outch(' ');
  		++padlen;
  	}
  }
  
  static void
! fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag)
  {
  	char		fmt[32];
  	char		convert[512];
--- 560,593 ----
  	{
  		if (signvalue)
  		{
! 			dopr_outch(signvalue, end);
  			--padlen;
  			signvalue = 0;
  		}
  		while (padlen > 0)
  		{
! 			dopr_outch(zpad, end);
  			--padlen;
  		}
  	}
  	while (padlen > 0)
  	{
! 		dopr_outch(' ', end);
  		--padlen;
  	}
  	if (signvalue)
! 		dopr_outch(signvalue, end);
  	while (place > 0)
! 		dopr_outch(convert[--place], end);
  	while (padlen < 0)
  	{
! 		dopr_outch(' ', end);
  		++padlen;
  	}
  }
  
  static void
! fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end)
  {
  	char		fmt[32];
  	char		convert[512];
***************
*** 615,648 ****
  
  	while (padlen > 0)
  	{
! 		dopr_outch(' ');
  		--padlen;
  	}
! 	dostr(convert, 0);
  	while (padlen < 0)
  	{
! 		dopr_outch(' ');
  		++padlen;
  	}
  }
  
  static void
! dostr(char *str, int cut)
  {
  	if (cut)
  	{
  		while (*str && cut-- > 0)
! 			dopr_outch(*str++);
  	}
  	else
  	{
  		while (*str)
! 			dopr_outch(*str++);
  	}
  }
  
  static void
! dopr_outch(int c)
  {
  #ifdef NOT_USED
  	if (iscntrl((unsigned char) c) && c != '\n' && c != '\t')
--- 614,647 ----
  
  	while (padlen > 0)
  	{
! 		dopr_outch(' ', end);
  		--padlen;
  	}
! 	dostr(convert, 0, end);
  	while (padlen < 0)
  	{
! 		dopr_outch(' ', end);
  		++padlen;
  	}
  }
  
  static void
! dostr(char *str, int cut, char *end)
  {
  	if (cut)
  	{
  		while (*str && cut-- > 0)
! 			dopr_outch(*str++, end);
  	}
  	else
  	{
  		while (*str)
! 			dopr_outch(*str++, end);
  	}
  }
  
  static void
! dopr_outch(int c, char *end)
  {
  #ifdef NOT_USED
  	if (iscntrl((unsigned char) c) && c != '\n' && c != '\t')
***************
*** 654,659 ****
  #endif
  	if (end == 0 || output < end)
  		*output++ = c;
- 	else
- 		SnprfOverflow++;
  }
--- 653,656 ----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.