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

Commit09a8931

Browse files
committed
Repair bug that would allow libpq to think a command had succeeded when
it really hadn't, due to double output of previous command's response.Fix prevents recursive entry to libpq routines. Found by Jan Wieck.
1 parent26b5d53 commit09a8931

File tree

3 files changed

+93
-21
lines changed

3 files changed

+93
-21
lines changed

‎src/backend/libpq/pqcomm.c

Lines changed: 87 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
3131
* Portions Copyright (c) 1994, Regents of the University of California
3232
*
33-
*$PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.171 2004/08/29 05:06:43 momjian Exp $
33+
*$PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.172 2004/09/26 00:26:19 tgl Exp $
3434
*
3535
*-------------------------------------------------------------------------
3636
*/
@@ -44,6 +44,7 @@
4444
*StreamClose- Close a client/backend connection
4545
*TouchSocketFile- Protect socket file against /tmp cleaners
4646
*pq_init- initialize libpq at backend startup
47+
*pq_comm_reset- reset libpq during error recovery
4748
*pq_close- shutdown libpq at backend exit
4849
*
4950
* low-level I/O:
@@ -88,21 +89,17 @@
8889
#include"storage/ipc.h"
8990

9091

91-
staticvoidpq_close(intcode,Datumarg);
92-
93-
#ifdefHAVE_UNIX_SOCKETS
94-
staticintLock_AF_UNIX(unsigned shortportNumber,char*unixSocketName);
95-
staticintSetup_AF_UNIX(void);
96-
#endif/* HAVE_UNIX_SOCKETS */
97-
98-
9992
/*
10093
* Configuration options
10194
*/
10295
intUnix_socket_permissions;
10396
char*Unix_socket_group;
10497

10598

99+
/* Where the Unix socket file is */
100+
staticcharsock_path[MAXPGPATH];
101+
102+
106103
/*
107104
* Buffers for low-level I/O
108105
*/
@@ -121,9 +118,20 @@ static intPqRecvLength;/* End of data available in PqRecvBuffer */
121118
/*
122119
* Message status
123120
*/
121+
staticboolPqCommBusy;
124122
staticboolDoingCopyOut;
125123

126124

125+
/* Internal functions */
126+
staticvoidpq_close(intcode,Datumarg);
127+
staticintinternal_putbytes(constchar*s,size_tlen);
128+
staticintinternal_flush(void);
129+
#ifdefHAVE_UNIX_SOCKETS
130+
staticintLock_AF_UNIX(unsigned shortportNumber,char*unixSocketName);
131+
staticintSetup_AF_UNIX(void);
132+
#endif/* HAVE_UNIX_SOCKETS */
133+
134+
127135
/* --------------------------------
128136
*pq_init - initialize libpq at backend startup
129137
* --------------------------------
@@ -132,10 +140,27 @@ void
132140
pq_init(void)
133141
{
134142
PqSendPointer=PqRecvPointer=PqRecvLength=0;
143+
PqCommBusy= false;
135144
DoingCopyOut= false;
136145
on_proc_exit(pq_close,0);
137146
}
138147

148+
/* --------------------------------
149+
*pq_comm_reset - reset libpq during error recovery
150+
*
151+
* This is called from error recovery at the outer idle loop. It's
152+
* just to get us out of trouble if we somehow manage to elog() from
153+
* inside a pqcomm.c routine (which ideally will never happen, but...)
154+
* --------------------------------
155+
*/
156+
void
157+
pq_comm_reset(void)
158+
{
159+
/* Do not throw away pending data, but do reset the busy flag */
160+
PqCommBusy= false;
161+
/* We can abort any old-style COPY OUT, too */
162+
pq_endcopyout(true);
163+
}
139164

140165
/* --------------------------------
141166
*pq_close - shutdown libpq at backend exit
@@ -174,8 +199,6 @@ pq_close(int code, Datum arg)
174199
*Stream functions are used for vanilla TCP connection protocol.
175200
*/
176201

177-
staticcharsock_path[MAXPGPATH];
178-
179202

180203
/* StreamDoUnlink()
181204
* Shutdown routine for backend connection
@@ -885,13 +908,30 @@ pq_getmessage(StringInfo s, int maxlen)
885908
*/
886909
int
887910
pq_putbytes(constchar*s,size_tlen)
911+
{
912+
intres;
913+
914+
/* Should only be called by old-style COPY OUT */
915+
Assert(DoingCopyOut);
916+
/* No-op if reentrant call */
917+
if (PqCommBusy)
918+
return0;
919+
PqCommBusy= true;
920+
res=internal_putbytes(s,len);
921+
PqCommBusy= false;
922+
returnres;
923+
}
924+
925+
staticint
926+
internal_putbytes(constchar*s,size_tlen)
888927
{
889928
size_tamount;
890929

891930
while (len>0)
892931
{
932+
/* If buffer is full, then flush it out */
893933
if (PqSendPointer >=PQ_BUFFER_SIZE)
894-
if (pq_flush())/* If buffer is full, then flush it out */
934+
if (internal_flush())
895935
returnEOF;
896936
amount=PQ_BUFFER_SIZE-PqSendPointer;
897937
if (amount>len)
@@ -912,6 +952,20 @@ pq_putbytes(const char *s, size_t len)
912952
*/
913953
int
914954
pq_flush(void)
955+
{
956+
intres;
957+
958+
/* No-op if reentrant call */
959+
if (PqCommBusy)
960+
return0;
961+
PqCommBusy= true;
962+
res=internal_flush();
963+
PqCommBusy= false;
964+
returnres;
965+
}
966+
967+
staticint
968+
internal_flush(void)
915969
{
916970
staticintlast_reported_send_errno=0;
917971

@@ -988,26 +1042,40 @@ pq_flush(void)
9881042
*then; dropping them is annoying, but at least they will still appear
9891043
*in the postmaster log.)
9901044
*
1045+
*We also suppress messages generated while pqcomm.c is busy. This
1046+
*avoids any possibility of messages being inserted within other
1047+
*messages. The only known trouble case arises if SIGQUIT occurs
1048+
*during a pqcomm.c routine --- quickdie() will try to send a warning
1049+
*message, and the most reasonable approach seems to be to drop it.
1050+
*
9911051
*returns 0 if OK, EOF if trouble
9921052
* --------------------------------
9931053
*/
9941054
int
9951055
pq_putmessage(charmsgtype,constchar*s,size_tlen)
9961056
{
997-
if (DoingCopyOut)
1057+
if (DoingCopyOut||PqCommBusy)
9981058
return0;
1059+
PqCommBusy= true;
9991060
if (msgtype)
1000-
if (pq_putbytes(&msgtype,1))
1001-
returnEOF;
1061+
if (internal_putbytes(&msgtype,1))
1062+
gotofail;
10021063
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >=3)
10031064
{
10041065
uint32n32;
10051066

10061067
n32=htonl((uint32) (len+4));
1007-
if (pq_putbytes((char*)&n32,4))
1008-
returnEOF;
1068+
if (internal_putbytes((char*)&n32,4))
1069+
gotofail;
10091070
}
1010-
returnpq_putbytes(s,len);
1071+
if (internal_putbytes(s,len))
1072+
gotofail;
1073+
PqCommBusy= false;
1074+
return0;
1075+
1076+
fail:
1077+
PqCommBusy= false;
1078+
returnEOF;
10111079
}
10121080

10131081
/* --------------------------------
@@ -1036,8 +1104,8 @@ pq_endcopyout(bool errorAbort)
10361104
{
10371105
if (!DoingCopyOut)
10381106
return;
1039-
DoingCopyOut= false;
10401107
if (errorAbort)
10411108
pq_putbytes("\n\n\\.\n",5);
10421109
/* in non-error case, copy.c will have emitted the terminator line */
1110+
DoingCopyOut= false;
10431111
}

‎src/backend/tcop/postgres.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.432 2004/09/13 20:07:05 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.433 2004/09/26 00:26:25 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -2811,6 +2811,9 @@ PostgresMain(int argc, char *argv[], const char *username)
28112811
DisableNotifyInterrupt();
28122812
DisableCatchupInterrupt();
28132813

2814+
/* Make sure libpq is in a good state */
2815+
pq_comm_reset();
2816+
28142817
/* Report the error to the client and/or server log */
28152818
EmitErrorReport();
28162819

‎src/include/libpq/libpq.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/libpq/libpq.h,v 1.62 2004/08/29 04:13:07 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/libpq/libpq.h,v 1.63 2004/09/26 00:26:28 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -52,6 +52,7 @@ extern intStreamConnection(int server_fd, Port *port);
5252
externvoidStreamClose(intsock);
5353
externvoidTouchSocketFile(void);
5454
externvoidpq_init(void);
55+
externvoidpq_comm_reset(void);
5556
externintpq_getbytes(char*s,size_tlen);
5657
externintpq_getstring(StringInfos);
5758
externintpq_getmessage(StringInfos,intmaxlen);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp