Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit09a89cb

Browse files
committed
Get rid of use of asprintf() in favor of a more portable implementation.
asprintf(), aside from not being particularly portable, has a fundamentallybadly-designed API; the psprintf() function that was added in passing inthe previous patch has a much better API choice. Moreover, the NetBSDimplementation that was borrowed for the previous patch doesn't work withnon-C99-compliant vsnprintf, which is something we still have to cope withon some platforms; and it depends on va_copy which isn't all that portableeither. Get rid of that code in favor of an implementation similar to whatwe've used for many years in stringinfo.c. Also, move it into libpgcommonsince it's not really libpgport material.I think this patch will be enough to turn the buildfarm green again, butthere's still cosmetic work left to do, namely get rid of pg_asprintf()in favor of using psprintf(). That will come in a followon patch.
1 parent586a8fc commit09a89cb

File tree

18 files changed

+251
-242
lines changed

18 files changed

+251
-242
lines changed

‎configure

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21500,8 +21500,7 @@ fi
2150021500

2150121501

2150221502

21503-
21504-
for ac_func in asprintf crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy
21503+
for ac_func in crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy
2150521504
do
2150621505
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
2150721506
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5

‎configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ else
13441344
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
13451345
fi
13461346

1347-
AC_REPLACE_FUNCS([asprintfcrypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy])
1347+
AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy])
13481348

13491349
case $host_os in
13501350

‎src/backend/libpq/auth.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,15 +1015,17 @@ pg_GSS_recvauth(Port *port)
10151015
*/
10161016
if (getenv("KRB5_KTNAME")==NULL)
10171017
{
1018-
char*kt_path;
1018+
size_tkt_len=strlen(pg_krb_server_keyfile)+14;
1019+
char*kt_path=malloc(kt_len);
10191020

1020-
if (asprintf(&kt_path,"KRB5_KTNAME=%s",pg_krb_server_keyfile)<0)
1021+
if (!kt_path)
10211022
{
10221023
ereport(LOG,
10231024
(errcode(ERRCODE_OUT_OF_MEMORY),
10241025
errmsg("out of memory")));
10251026
returnSTATUS_ERROR;
10261027
}
1028+
snprintf(kt_path,kt_len,"KRB5_KTNAME=%s",pg_krb_server_keyfile);
10271029
putenv(kt_path);
10281030
}
10291031
}

‎src/backend/utils/init/miscinit.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,12 @@ make_absolute_path(const char *path)
165165
}
166166
}
167167

168-
if (asprintf(&new,"%s/%s",buf,path)<0)
168+
new=malloc(strlen(buf)+strlen(path)+2);
169+
if (!new)
169170
ereport(FATAL,
170171
(errcode(ERRCODE_OUT_OF_MEMORY),
171172
errmsg("out of memory")));
173+
sprintf(new,"%s/%s",buf,path);
172174
free(buf);
173175
}
174176
else

‎src/backend/utils/mmgr/mcxt.c

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -852,52 +852,3 @@ pnstrdup(const char *in, Size len)
852852
out[len]='\0';
853853
returnout;
854854
}
855-
856-
/*
857-
* asprintf()-like functions around palloc, adapted from
858-
* http://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/pkgtools/libnbcompat/files/asprintf.c
859-
*/
860-
861-
char*
862-
psprintf(constchar*format, ...)
863-
{
864-
va_listap;
865-
char*retval;
866-
867-
va_start(ap,format);
868-
retval=pvsprintf(format,ap);
869-
va_end(ap);
870-
871-
returnretval;
872-
}
873-
874-
char*
875-
pvsprintf(constchar*format,va_listap)
876-
{
877-
char*buf,*new_buf;
878-
size_tlen;
879-
intretval;
880-
va_listap2;
881-
882-
len=128;
883-
buf=palloc(len);
884-
885-
va_copy(ap2,ap);
886-
retval=vsnprintf(buf,len,format,ap);
887-
Assert(retval >=0);
888-
889-
if (retval<len)
890-
{
891-
new_buf=repalloc(buf,retval+1);
892-
va_end(ap2);
893-
returnnew_buf;
894-
}
895-
896-
len= (size_t)retval+1;
897-
pfree(buf);
898-
buf=palloc(len);
899-
retval=vsnprintf(buf,len,format,ap2);
900-
va_end(ap2);
901-
Assert(retval==len-1);
902-
returnbuf;
903-
}

‎src/bin/psql/large_obj.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,12 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
200200
char*cmdbuf;
201201
char*bufptr;
202202
size_tslen=strlen(comment_arg);
203-
intrv;
204203

205-
rv=asprintf(&cmdbuf,"COMMENT ON LARGE OBJECT %u IS '",loid);
206-
if (rv<0)
204+
cmdbuf=malloc(slen*2+256);
205+
if (!cmdbuf)
207206
returnfail_lo_xact("\\lo_import",own_transaction);
208-
bufptr=cmdbuf+rv;
207+
sprintf(cmdbuf,"COMMENT ON LARGE OBJECT %u IS '",loid);
208+
bufptr=cmdbuf+strlen(cmdbuf);
209209
bufptr+=PQescapeStringConn(pset.db,bufptr,comment_arg,slen,NULL);
210210
strcpy(bufptr,"'");
211211

‎src/common/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ include $(top_builddir)/src/Makefile.global
2323
overrideCPPFLAGS := -DFRONTEND$(CPPFLAGS)
2424
LIBS +=$(PTHREAD_LIBS)
2525

26-
OBJS_COMMON = exec.o pgfnames.o relpath.o rmtree.o wait_error.o
26+
OBJS_COMMON = exec.o pgfnames.opsprintf.orelpath.o rmtree.o wait_error.o
2727

2828
OBJS_FRONTEND =$(OBJS_COMMON) fe_memutils.o
2929

‎src/common/fe_memutils.c

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,6 @@ pg_free(void *ptr)
9393
free(ptr);
9494
}
9595

96-
int
97-
pg_asprintf(char**ret,constchar*format, ...)
98-
{
99-
va_listap;
100-
intrc;
101-
102-
va_start(ap,format);
103-
rc=vasprintf(ret,format,ap);
104-
va_end(ap);
105-
106-
if (rc<0)
107-
{
108-
fprintf(stderr,_("out of memory\n"));
109-
exit(EXIT_FAILURE);
110-
}
111-
112-
returnrc;
113-
}
114-
11596
/*
11697
* Frontend emulation of backend memory management functions. Useful for
11798
* programs that compile backend files.
@@ -145,23 +126,3 @@ repalloc(void *pointer, Size size)
145126
{
146127
returnpg_realloc(pointer,size);
147128
}
148-
149-
char*
150-
psprintf(constchar*format, ...)
151-
{
152-
va_listap;
153-
intrc;
154-
char*ret;
155-
156-
va_start(ap,format);
157-
rc=vasprintf(&ret,format,ap);
158-
va_end(ap);
159-
160-
if (rc<0)
161-
{
162-
fprintf(stderr,_("out of memory\n"));
163-
exit(EXIT_FAILURE);
164-
}
165-
166-
returnret;
167-
}

‎src/common/psprintf.c

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* psprintf.c
4+
*sprintf into an allocated-on-demand buffer
5+
*
6+
*
7+
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
8+
* Portions Copyright (c) 1994, Regents of the University of California
9+
*
10+
*
11+
* IDENTIFICATION
12+
* src/common/psprintf.c
13+
*
14+
*-------------------------------------------------------------------------
15+
*/
16+
17+
#ifndefFRONTEND
18+
#include"postgres.h"
19+
#else
20+
#include"postgres_fe.h"
21+
#endif
22+
23+
#include"utils/memutils.h"
24+
25+
26+
staticsize_tpvsnprintf(char*buf,size_tlen,constchar*fmt,va_listargs)
27+
__attribute__((format(PG_PRINTF_ATTRIBUTE,3,0)));
28+
29+
30+
/*
31+
* psprintf
32+
*
33+
* Format text data under the control of fmt (an sprintf-style format string)
34+
* and return it in an allocated-on-demand buffer.The buffer is allocated
35+
* with palloc in the backend, or malloc in frontend builds. Caller is
36+
* responsible to free the buffer when no longer needed, if appropriate.
37+
*
38+
* Errors are not returned to the caller, but are reported via elog(ERROR)
39+
* in the backend, or printf-to-stderr-and-exit() in frontend builds.
40+
* One should therefore think twice about using this in libpq.
41+
*/
42+
char*
43+
psprintf(constchar*fmt,...)
44+
{
45+
size_tlen=128;/* initial assumption about buffer size */
46+
47+
for (;;)
48+
{
49+
char*result;
50+
va_listargs;
51+
52+
/*
53+
* Allocate result buffer.Note that in frontend this maps to malloc
54+
* with exit-on-error.
55+
*/
56+
result= (char*)palloc(len);
57+
58+
/* Try to format the data. */
59+
va_start(args,fmt);
60+
len=pvsnprintf(result,len,fmt,args);
61+
va_end(args);
62+
63+
if (len==0)
64+
returnresult;/* success */
65+
66+
/* Release buffer and loop around to try again with larger len. */
67+
pfree(result);
68+
}
69+
}
70+
71+
/*
72+
* pvsnprintf
73+
*
74+
* Attempt to format text data under the control of fmt (an sprintf-style
75+
* format string) and insert it into buf (which has length len).
76+
*
77+
* If successful, return zero.If there's not enough space in buf, return
78+
* an estimate of the buffer size needed to succeed (this *must* be more
79+
* than "len", else psprintf might loop infinitely).
80+
* Other error cases do not return.
81+
*
82+
* XXX This API is ugly, but there seems no alternative given the C spec's
83+
* restrictions on what can portably be done with va_list arguments: you have
84+
* to redo va_start before you can rescan the argument list, and we can't do
85+
* that from here.
86+
*/
87+
staticsize_t
88+
pvsnprintf(char*buf,size_tlen,constchar*fmt,va_listargs)
89+
{
90+
intnprinted;
91+
92+
Assert(len>0);
93+
94+
errno=0;
95+
96+
/*
97+
* Assert check here is to catch buggy vsnprintf that overruns the
98+
* specified buffer length. Solaris 7 in 64-bit mode is an example of a
99+
* platform with such a bug.
100+
*/
101+
#ifdefUSE_ASSERT_CHECKING
102+
buf[len-1]='\0';
103+
#endif
104+
105+
nprinted=vsnprintf(buf,len,fmt,args);
106+
107+
Assert(buf[len-1]=='\0');
108+
109+
/*
110+
* If vsnprintf reports an error other than ENOMEM, fail. The possible
111+
* causes of this are not user-facing errors, so elog should be enough.
112+
*/
113+
if (nprinted<0&&errno!=0&&errno!=ENOMEM)
114+
{
115+
#ifndefFRONTEND
116+
elog(ERROR,"vsnprintf failed: %m");
117+
#else
118+
fprintf(stderr,"vsnprintf failed: %s\n",strerror(errno));
119+
exit(EXIT_FAILURE);
120+
#endif
121+
}
122+
123+
/*
124+
* Note: some versions of vsnprintf return the number of chars actually
125+
* stored, not the total space needed as C99 specifies. And at least one
126+
* returns -1 on failure. Be conservative about believing whether the
127+
* print worked.
128+
*/
129+
if (nprinted >=0&& (size_t)nprinted<len-1)
130+
{
131+
/* Success. Note nprinted does not include trailing null. */
132+
return0;
133+
}
134+
135+
if (nprinted >=0&& (size_t)nprinted>len)
136+
{
137+
/*
138+
* This appears to be a C99-compliant vsnprintf, so believe its
139+
* estimate of the required space.(If it's wrong, this code will
140+
* still work, but may loop multiple times.) Note that the space
141+
* needed should be only nprinted+1 bytes, but we'd better allocate
142+
* one more than that so that the test above will succeed next time.
143+
*
144+
* In the corner case where the required space just barely overflows,
145+
* fall through so that we'll error out below (possibly after looping).
146+
*/
147+
if ((size_t)nprinted <=MaxAllocSize-2)
148+
returnnprinted+2;
149+
}
150+
151+
/*
152+
* Buffer overrun, and we don't know how much space is needed. Estimate
153+
* twice the previous buffer size.If this would overflow, choke.We use
154+
* a palloc-oriented overflow limit even when in frontend.
155+
*/
156+
if (len>MaxAllocSize /2)
157+
{
158+
#ifndefFRONTEND
159+
ereport(ERROR,
160+
(errcode(ERRCODE_OUT_OF_MEMORY),
161+
errmsg("out of memory")));
162+
#else
163+
fprintf(stderr,_("out of memory\n"));
164+
exit(EXIT_FAILURE);
165+
#endif
166+
}
167+
168+
returnlen*2;
169+
}
170+
171+
172+
/*
173+
* XXX this is going away shortly.
174+
*/
175+
#ifdefFRONTEND
176+
int
177+
pg_asprintf(char**ret,constchar*fmt, ...)
178+
{
179+
size_tlen=128;/* initial assumption about buffer size */
180+
181+
for (;;)
182+
{
183+
char*result;
184+
va_listargs;
185+
186+
/*
187+
* Allocate result buffer.Note that in frontend this maps to malloc
188+
* with exit-on-error.
189+
*/
190+
result= (char*)palloc(len);
191+
192+
/* Try to format the data. */
193+
va_start(args,fmt);
194+
len=pvsnprintf(result,len,fmt,args);
195+
va_end(args);
196+
197+
if (len==0)
198+
{
199+
*ret=result;
200+
return0;
201+
}
202+
203+
/* Release buffer and loop around to try again with larger len. */
204+
pfree(result);
205+
}
206+
}
207+
#endif

‎src/include/pg_config.h.in

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@
8787
/* Define to 1 if you have the `append_history' function. */
8888
#undef HAVE_APPEND_HISTORY
8989

90-
/* Define to 1 if you have the `asprintf' function. */
91-
#undef HAVE_ASPRINTF
92-
9390
/* Define to 1 if you have the `cbrt' function. */
9491
#undef HAVE_CBRT
9592

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp