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

Commit2aa64f7

Browse files
committed
Plug several holes in backend's ability to cope with
unexpected loss of connection to frontend.
1 parent991b82e commit2aa64f7

File tree

3 files changed

+84
-48
lines changed

3 files changed

+84
-48
lines changed

‎src/backend/commands/copy.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.85 1999/07/17 20:16:51 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.86 1999/07/22 02:40:06 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -54,15 +54,19 @@ static void GetIndexRelations(Oid main_relation_oid,
5454
#ifdefCOPY_PATCH
5555
staticvoidCopyReadNewline(FILE*fp,int*newline);
5656
staticchar*CopyReadAttribute(FILE*fp,bool*isnull,char*delim,int*newline);
57-
5857
#else
5958
staticchar*CopyReadAttribute(FILE*fp,bool*isnull,char*delim);
60-
6159
#endif
60+
6261
staticvoidCopyAttributeOut(FILE*fp,char*string,char*delim,intis_array);
6362
staticintCountTuples(Relationrelation);
6463

64+
/*
65+
* Static communication variables ... pretty grotty, but COPY has
66+
* never been reentrant...
67+
*/
6568
staticintlineno;
69+
staticboolfe_eof;
6670

6771
/*
6872
* Internal communications functions
@@ -90,7 +94,10 @@ static void
9094
CopySendData(void*databuf,intdatasize,FILE*fp)
9195
{
9296
if (!fp)
93-
pq_putbytes((char*)databuf,datasize);
97+
{
98+
if (pq_putbytes((char*)databuf,datasize))
99+
fe_eof= true;
100+
}
94101
else
95102
fwrite(databuf,datasize,1,fp);
96103
}
@@ -121,7 +128,10 @@ static void
121128
CopyGetData(void*databuf,intdatasize,FILE*fp)
122129
{
123130
if (!fp)
124-
pq_getbytes((char*)databuf,datasize);
131+
{
132+
if (pq_getbytes((char*)databuf,datasize))
133+
fe_eof= true;
134+
}
125135
else
126136
fread(databuf,datasize,1,fp);
127137
}
@@ -134,7 +144,10 @@ CopyGetChar(FILE *fp)
134144
unsignedcharch;
135145

136146
if (pq_getbytes((char*)&ch,1))
147+
{
148+
fe_eof= true;
137149
returnEOF;
150+
}
138151
returnch;
139152
}
140153
else
@@ -145,24 +158,28 @@ static int
145158
CopyGetEof(FILE*fp)
146159
{
147160
if (!fp)
148-
return0;/* Never return EOF when talking to
149-
* frontend ? */
161+
returnfe_eof;
150162
else
151163
returnfeof(fp);
152164
}
153165

154166
/*
155167
* CopyPeekChar reads a byte in "peekable" mode.
156168
* after each call to CopyPeekChar, a call to CopyDonePeek _must_
157-
* follow.
169+
* follow, unless EOF was returned.
158170
* CopyDonePeek will either take the peeked char off the steam
159171
* (if pickup is != 0) or leave it on the stream (if pickup == 0)
160172
*/
161173
staticint
162174
CopyPeekChar(FILE*fp)
163175
{
164176
if (!fp)
165-
returnpq_peekbyte();
177+
{
178+
intch=pq_peekbyte();
179+
if (ch==EOF)
180+
fe_eof= true;
181+
returnch;
182+
}
166183
else
167184
returngetc(fp);
168185
}
@@ -668,6 +685,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
668685
}
669686

670687
lineno=0;
688+
fe_eof= false;
689+
671690
while (!done)
672691
{
673692
if (!binary)
@@ -1193,10 +1212,7 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
11931212
else
11941213
{
11951214
if (CopyGetEof(fp))
1196-
{
1197-
CopyDonePeek(fp,c,1);/* pick up */
11981215
returnNULL;
1199-
}
12001216
CopyDonePeek(fp,c,0);/* Return to stream! */
12011217
}
12021218
}

‎src/backend/tcop/fastpath.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.29 1999/07/17 20:17:50 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.30 1999/07/22 02:40:07 tgl Exp $
1111
*
1212
* NOTES
1313
* This cruft is the server side of PQfn.
@@ -265,8 +265,11 @@ update_fp_info(Oid func_id, struct fp_info * fip)
265265
* This corresponds to the libpq protocol symbol "F".
266266
*
267267
* RETURNS:
268-
*nothing of significance.
269-
*All errors result in elog(ERROR,...).
268+
*0 if successful completion, EOF if frontend connection lost.
269+
*
270+
* Note: All ordinary errors result in elog(ERROR,...). However,
271+
* if we lose the frontend connection there is no one to elog to,
272+
* and no use in proceeding...
270273
*/
271274
int
272275
HandleFunctionRequest()
@@ -282,9 +285,11 @@ HandleFunctionRequest()
282285
char*p;
283286
structfp_info*fip;
284287

285-
pq_getint(&tmp,4);/* function oid */
288+
if (pq_getint(&tmp,4))/* function oid */
289+
returnEOF;
286290
fid= (Oid)tmp;
287-
pq_getint(&nargs,4);/* # of arguments */
291+
if (pq_getint(&nargs,4))/* # of arguments */
292+
returnEOF;
288293

289294
/*
290295
* This is where the one-back caching is done. If you want to save
@@ -294,6 +299,13 @@ HandleFunctionRequest()
294299
if (!valid_fp_info(fid,fip))
295300
update_fp_info(fid,fip);
296301

302+
/*
303+
* XXX FIXME: elog() here means we lose sync with the frontend,
304+
* since we have not swallowed all of its input message. What
305+
* should happen is we absorb all of the input message per protocol
306+
* syntax, and *then* do error checking and elog if appropriate.
307+
*/
308+
297309
if (fip->nargs!=nargs)
298310
{
299311
elog(ERROR,"HandleFunctionRequest: actual arguments (%d) != registered arguments (%d)",
@@ -311,13 +323,15 @@ HandleFunctionRequest()
311323
arg[i]= (char*)NULL;
312324
else
313325
{
314-
pq_getint(&argsize,4);
326+
if (pq_getint(&argsize,4))
327+
returnEOF;
315328

316329
Assert(argsize>0);
317330
if (fip->argbyval[i])
318331
{/* by-value */
319332
Assert(argsize <=4);
320-
pq_getint(&tmp,argsize);
333+
if (pq_getint(&tmp,argsize))
334+
returnEOF;
321335
arg[i]= (char*)tmp;
322336
}
323337
else
@@ -329,14 +343,16 @@ HandleFunctionRequest()
329343
* 98 Jan 6 */
330344
elog(ERROR,"HandleFunctionRequest: palloc failed");
331345
VARSIZE(p)=argsize+VARHDRSZ;
332-
pq_getbytes(VARDATA(p),argsize);
346+
if (pq_getbytes(VARDATA(p),argsize))
347+
returnEOF;
333348
}
334349
else
335350
{/* ... fixed */
336351
/* XXX cross our fingers and trust "argsize" */
337352
if (!(p=palloc(argsize+1)))
338353
elog(ERROR,"HandleFunctionRequest: palloc failed");
339-
pq_getbytes(p,argsize);
354+
if (pq_getbytes(p,argsize))
355+
returnEOF;
340356
}
341357
palloced |= (1 <<i);
342358
arg[i]=p;
@@ -374,7 +390,5 @@ HandleFunctionRequest()
374390
if (!fip->retbyval)
375391
pfree(retval);
376392

377-
378-
379393
return0;
380394
}

‎src/backend/tcop/postgres.c

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.126 1999/07/19 02:27:06 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.127 1999/07/22 02:40:07 tgl Exp $
1111
*
1212
* NOTES
1313
* this is the "main" module of the postgres backend and
@@ -158,9 +158,9 @@ int_exec_repeat_ = 1;
158158
*decls for routines only used in this file
159159
* ----------------------------------------------------------------
160160
*/
161-
staticcharInteractiveBackend(char*inBuf);
162-
staticcharSocketBackend(char*inBuf);
163-
staticcharReadCommand(char*inBuf);
161+
staticintInteractiveBackend(char*inBuf);
162+
staticintSocketBackend(char*inBuf);
163+
staticintReadCommand(char*inBuf);
164164
staticvoidpg_exec_query(char*query_string);
165165

166166

@@ -172,10 +172,12 @@ static void pg_exec_query(char *query_string);
172172
/* ----------------
173173
*InteractiveBackend() is called for user interactive connections
174174
*the string entered by the user is placed in its parameter inBuf.
175+
*
176+
* EOF is returned if end-of-file input is seen; time to shut down.
175177
* ----------------
176178
*/
177179

178-
staticchar
180+
staticint
179181
InteractiveBackend(char*inBuf)
180182
{
181183
char*stuff=inBuf;/* current place in input buffer */
@@ -244,8 +246,7 @@ InteractiveBackend(char *inBuf)
244246
{
245247
if (Verbose)
246248
puts("EOF");
247-
IsEmptyQuery= true;
248-
proc_exit(0);
249+
returnEOF;
249250
}
250251

251252
/* ----------------
@@ -274,11 +275,13 @@ InteractiveBackend(char *inBuf)
274275
*
275276
*If the input is a fastpath function call (case 'F') then
276277
*the function call is processed in HandleFunctionRequest().
277-
*(now called from PostgresMain())
278+
*(now called from PostgresMain()).
279+
*
280+
* EOF is returned if the connection is lost.
278281
* ----------------
279282
*/
280283

281-
staticchar
284+
staticint
282285
SocketBackend(char*inBuf)
283286
{
284287
charqtype;
@@ -290,13 +293,7 @@ SocketBackend(char *inBuf)
290293
*/
291294
qtype='?';
292295
if (pq_getbytes(&qtype,1)==EOF)
293-
{
294-
/* ------------
295-
*when front-end applications quits/dies
296-
* ------------
297-
*/
298-
proc_exit(0);
299-
}
296+
returnEOF;
300297

301298
switch (qtype)
302299
{
@@ -305,7 +302,8 @@ SocketBackend(char *inBuf)
305302
* ----------------
306303
*/
307304
case'Q':
308-
pq_getstr(inBuf,MAX_PARSE_BUFFER);
305+
if (pq_getstr(inBuf,MAX_PARSE_BUFFER))
306+
returnEOF;
309307
result='Q';
310308
break;
311309

@@ -314,8 +312,8 @@ SocketBackend(char *inBuf)
314312
* ----------------
315313
*/
316314
case'F':
317-
pq_getstr(inBuf,MAX_PARSE_BUFFER);/* ignore the rest of the
318-
* line */
315+
if (pq_getstr(inBuf,MAX_PARSE_BUFFER))
316+
returnEOF;/* ignore "string" at start of F message */
319317
result='F';
320318
break;
321319

@@ -345,10 +343,10 @@ SocketBackend(char *inBuf)
345343
*ReadCommand reads a command from either the frontend or
346344
*standard input, places it in inBuf, and returns a char
347345
*representing whether the string is a 'Q'uery or a 'F'astpath
348-
*call.
346+
*call. EOF is returned if end of file.
349347
* ----------------
350348
*/
351-
staticchar
349+
staticint
352350
ReadCommand(char*inBuf)
353351
{
354352
if (IsUnderPostmaster)
@@ -890,7 +888,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
890888
boolsecure= true;
891889
interrs=0;
892890

893-
charfirstchar;
891+
intfirstchar;
894892
charparser_input[MAX_PARSE_BUFFER];
895893
char*userName;
896894

@@ -1494,7 +1492,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
14941492
if (!IsUnderPostmaster)
14951493
{
14961494
puts("\nPOSTGRES backend interactive interface ");
1497-
puts("$Revision: 1.126 $ $Date: 1999/07/19 02:27:06 $\n");
1495+
puts("$Revision: 1.127 $ $Date: 1999/07/22 02:40:07 $\n");
14981496
}
14991497

15001498
/* ----------------
@@ -1581,7 +1579,12 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
15811579
TPRINTF(TRACE_VERBOSE,"StartTransactionCommand");
15821580
StartTransactionCommand();
15831581

1584-
HandleFunctionRequest();
1582+
if (HandleFunctionRequest()==EOF)
1583+
{
1584+
/* lost frontend connection during F message input */
1585+
pq_close();
1586+
proc_exit(0);
1587+
}
15851588
break;
15861589

15871590
/* ----------------
@@ -1621,10 +1624,13 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
16211624
break;
16221625

16231626
/* ----------------
1624-
*'X' means that the frontend is closing down the socket
1627+
*'X' means that the frontend is closing down the socket.
1628+
*EOF means unexpected loss of frontend connection.
1629+
*Either way, perform normal shutdown.
16251630
* ----------------
16261631
*/
16271632
case'X':
1633+
caseEOF:
16281634
pq_close();
16291635
proc_exit(0);
16301636
break;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp