Skip to content

Commit 9989e90

Browse files
committed
Make port snprintf.c finally thread-safe.
1 parent 87aafa1 commit 9989e90

File tree

1 file changed

+53
-42
lines changed

1 file changed

+53
-42
lines changed

src/port/snprintf.c

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@
6666
* causing nasty effects.
6767
**************************************************************/
6868

69-
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.9 2005/03/01 05:47:28 momjian Exp $";*/
69+
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.10 2005/03/02 00:02:13 momjian Exp $";*/
7070

7171
int snprintf(char *str, size_t count, const char *fmt,...);
7272
int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
7373
int printf(const char *format, ...);
74-
static void dopr(char *buffer, const char *format, va_list args, char *end);
74+
static void dopr(char *buffer, const char *format, va_list args, char *end);
7575

7676
int
7777
printf(const char *fmt,...)
@@ -119,13 +119,14 @@ vsnprintf(char *str, size_t count, const char *fmt, va_list args)
119119
* dopr(): poor man's version of doprintf
120120
*/
121121

122-
static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end);
123-
static void fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *end);
124-
static void fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end);
125-
static void dostr(char *str, int cut, char *end);
126-
static void dopr_outch(int c, char *end);
127-
128-
static char *output;
122+
static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth,
123+
char *end, char **output);
124+
static void fmtnum(int64 value, int base, int dosign, int ljust, int len,
125+
int zpad, char *end, char **output);
126+
static void fmtfloat(double value, char type, int ljust, int len,
127+
int precision, int pointflag, char *end, char **output);
128+
static void dostr(char *str, int cut, char *end, char **output);
129+
static void dopr_outch(int c, char *end, char **output);
129130

130131
#define FMTSTR 1
131132
#define FMTNUM 2
@@ -152,7 +153,12 @@ dopr(char *buffer, const char *format, va_list args, char *end)
152153
int fmtpos = 1;
153154
int realpos = 0;
154155
int position;
155-
static struct{
156+
char *output;
157+
/* In thread mode this structure is too large. */
158+
#ifndef ENABLE_THREAD_SAFETY
159+
static
160+
#endif
161+
struct{
156162
const char* fmtbegin;
157163
const char* fmtend;
158164
void* value;
@@ -235,7 +241,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
235241
goto nextch;
236242
case 'u':
237243
case 'U':
238-
/* fmtnum(value,base,dosign,ljust,len,zpad) */
244+
/* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
239245
if (longflag)
240246
{
241247
if (longlongflag)
@@ -259,7 +265,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
259265
break;
260266
case 'o':
261267
case 'O':
262-
/* fmtnum(value,base,dosign,ljust,len,zpad) */
268+
/* fmtnum(value,base,dosign,ljust,len,zpad,&output) */
263269
if (longflag)
264270
{
265271
if (longlongflag)
@@ -286,7 +292,9 @@ dopr(char *buffer, const char *format, va_list args, char *end)
286292
if (longflag)
287293
{
288294
if (longlongflag)
295+
{
289296
value = va_arg(args, int64);
297+
}
290298
else
291299
value = va_arg(args, long);
292300
}
@@ -396,11 +404,11 @@ dopr(char *buffer, const char *format, va_list args, char *end)
396404
case '%':
397405
break;
398406
default:
399-
dostr("???????", 0, end);
407+
dostr("???????", 0, end, &output);
400408
}
401409
break;
402410
default:
403-
dopr_outch(ch, end);
411+
dopr_outch(ch, end, &output);
404412
break;
405413
}
406414
}
@@ -427,28 +435,28 @@ dopr(char *buffer, const char *format, va_list args, char *end)
427435
case FMTSTR:
428436
fmtstr(fmtparptr[i]->value, fmtparptr[i]->ljust,
429437
fmtparptr[i]->len, fmtparptr[i]->zpad,
430-
fmtparptr[i]->maxwidth, end);
438+
fmtparptr[i]->maxwidth, end, &output);
431439
break;
432440
case FMTNUM:
433441
fmtnum(fmtparptr[i]->numvalue, fmtparptr[i]->base,
434442
fmtparptr[i]->dosign, fmtparptr[i]->ljust,
435-
fmtparptr[i]->len, fmtparptr[i]->zpad, end);
443+
fmtparptr[i]->len, fmtparptr[i]->zpad, end, &output);
436444
break;
437445
case FMTFLOAT:
438446
fmtfloat(fmtparptr[i]->fvalue, fmtparptr[i]->type,
439447
fmtparptr[i]->ljust, fmtparptr[i]->len,
440448
fmtparptr[i]->precision, fmtparptr[i]->pointflag,
441-
end);
449+
end, &output);
442450
break;
443451
case FMTCHAR:
444-
dopr_outch(fmtparptr[i]->charvalue, end);
452+
dopr_outch(fmtparptr[i]->charvalue, end, &output);
445453
break;
446454
}
447455
format = fmtpar[i].fmtend;
448456
goto nochar;
449457
}
450458
}
451-
dopr_outch(ch, end);
459+
dopr_outch(ch, end, &output);
452460
nochar:
453461
/* nothing */
454462
; /* semicolon required because a goto has to be attached to a statement */
@@ -457,7 +465,8 @@ dopr(char *buffer, const char *format, va_list args, char *end)
457465
}
458466

459467
static void
460-
fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end)
468+
fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end,
469+
char **output)
461470
{
462471
int padlen,
463472
strlen; /* amount to pad */
@@ -474,19 +483,20 @@ fmtstr(char *value, int ljust, int len, int zpad, int maxwidth, char *end)
474483
padlen = -padlen;
475484
while (padlen > 0)
476485
{
477-
dopr_outch(' ', end);
486+
dopr_outch(' ', end, output);
478487
--padlen;
479488
}
480-
dostr(value, maxwidth, end);
489+
dostr(value, maxwidth, end, output);
481490
while (padlen < 0)
482491
{
483-
dopr_outch(' ', end);
492+
dopr_outch(' ', end, output);
484493
++padlen;
485494
}
486495
}
487496

488497
static void
489-
fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *end)
498+
fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad,
499+
char *end, char **output)
490500
{
491501
int signvalue = 0;
492502
uint64 uvalue;
@@ -541,34 +551,35 @@ fmtnum(int64 value, int base, int dosign, int ljust, int len, int zpad, char *en
541551
{
542552
if (signvalue)
543553
{
544-
dopr_outch(signvalue, end);
554+
dopr_outch(signvalue, end, output);
545555
--padlen;
546556
signvalue = 0;
547557
}
548558
while (padlen > 0)
549559
{
550-
dopr_outch(zpad, end);
560+
dopr_outch(zpad, end, output);
551561
--padlen;
552562
}
553563
}
554564
while (padlen > 0)
555565
{
556-
dopr_outch(' ', end);
566+
dopr_outch(' ', end, output);
557567
--padlen;
558568
}
559569
if (signvalue)
560-
dopr_outch(signvalue, end);
570+
dopr_outch(signvalue, end, output);
561571
while (place > 0)
562-
dopr_outch(convert[--place], end);
572+
dopr_outch(convert[--place], end, output);
563573
while (padlen < 0)
564574
{
565-
dopr_outch(' ', end);
575+
dopr_outch(' ', end, output);
566576
++padlen;
567577
}
568578
}
569579

570580
static void
571-
fmtfloat(double value, char type, int ljust, int len, int precision, int pointflag, char *end)
581+
fmtfloat(double value, char type, int ljust, int len, int precision,
582+
int pointflag, char *end, char **output)
572583
{
573584
char fmt[32];
574585
char convert[512];
@@ -595,43 +606,43 @@ fmtfloat(double value, char type, int ljust, int len, int precision, int pointfl
595606

596607
while (padlen > 0)
597608
{
598-
dopr_outch(' ', end);
609+
dopr_outch(' ', end, output);
599610
--padlen;
600611
}
601-
dostr(convert, 0, end);
612+
dostr(convert, 0, end, output);
602613
while (padlen < 0)
603614
{
604-
dopr_outch(' ', end);
615+
dopr_outch(' ', end, output);
605616
++padlen;
606617
}
607618
}
608619

609620
static void
610-
dostr(char *str, int cut, char *end)
621+
dostr(char *str, int cut, char *end, char **output)
611622
{
612623
if (cut)
613624
{
614625
while (*str && cut-- > 0)
615-
dopr_outch(*str++, end);
626+
dopr_outch(*str++, end, output);
616627
}
617628
else
618629
{
619630
while (*str)
620-
dopr_outch(*str++, end);
631+
dopr_outch(*str++, end, output);
621632
}
622633
}
623634

624635
static void
625-
dopr_outch(int c, char *end)
636+
dopr_outch(int c, char *end, char **output)
626637
{
627638
#ifdef NOT_USED
628639
if (iscntrl((unsigned char) c) && c != '\n' && c != '\t')
629640
{
630641
c = '@' + (c & 0x1F);
631-
if (end == 0 || output < end)
632-
*output++ = '^';
642+
if (end == 0 || *output < end)
643+
*(*output)++ = '^';
633644
}
634645
#endif
635-
if (end == 0 || output < end)
636-
*output++ = c;
646+
if (end == 0 || *output < end)
647+
*(*output)++ = c;
637648
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy