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

Commit9e09e3b

Browse files
committed
Fix single-user mode so that interrupts (particularly SIGTERM and
SIGQUIT) will be recognized and processed while waiting for input,rather than only after something has been typed. Also make SIGQUITdo the same thing as SIGTERM in single-user mode, ie, do a normalshutdown and exit. Since it's relatively easy to provoke SIGQUITfrom the keyboard, people may try that instead of control-D, and we'drather this leads to orderly shutdown. Per report from Leon Mergenand subsequent discussion.
1 parent9b61967 commit9e09e3b

File tree

1 file changed

+77
-49
lines changed

1 file changed

+77
-49
lines changed

‎src/backend/tcop/postgres.c

Lines changed: 77 additions & 49 deletions
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.535 2007/06/29 17:07:39 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.536 2007/07/09 01:15:14 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -164,6 +164,7 @@ static intUseNewLine = 0;/* Use EOF as query delimiters */
164164
* ----------------------------------------------------------------
165165
*/
166166
staticintInteractiveBackend(StringInfoinBuf);
167+
staticintinteractive_getc(void);
167168
staticintSocketBackend(StringInfoinBuf);
168169
staticintReadCommand(StringInfoinBuf);
169170
staticList*pg_rewrite_query(Query*query);
@@ -210,64 +211,61 @@ InteractiveBackend(StringInfo inBuf)
210211

211212
resetStringInfo(inBuf);
212213

213-
for (;;)
214+
if (UseNewLine)
214215
{
215-
if (UseNewLine)
216+
/*
217+
* if we are using \n as a delimiter, then read characters until
218+
* the \n.
219+
*/
220+
while ((c=interactive_getc())!=EOF)
216221
{
217-
/*
218-
* if we are using \n as a delimiter, then read characters until
219-
* the \n.
220-
*/
221-
while ((c=getc(stdin))!=EOF)
222+
if (c=='\n')
222223
{
223-
if (c=='\n')
224+
if (backslashSeen)
224225
{
225-
if (backslashSeen)
226-
{
227-
/* discard backslash from inBuf */
228-
inBuf->data[--inBuf->len]='\0';
229-
backslashSeen= false;
230-
continue;
231-
}
232-
else
233-
{
234-
/* keep the newline character */
235-
appendStringInfoChar(inBuf,'\n');
236-
break;
237-
}
226+
/* discard backslash from inBuf */
227+
inBuf->data[--inBuf->len]='\0';
228+
backslashSeen= false;
229+
continue;
238230
}
239-
elseif (c=='\\')
240-
backslashSeen= true;
241231
else
242-
backslashSeen= false;
243-
244-
appendStringInfoChar(inBuf, (char)c);
232+
{
233+
/* keep the newline character */
234+
appendStringInfoChar(inBuf,'\n');
235+
break;
236+
}
245237
}
238+
elseif (c=='\\')
239+
backslashSeen= true;
240+
else
241+
backslashSeen= false;
246242

247-
if (c==EOF)
248-
end= true;
249-
}
250-
else
251-
{
252-
/*
253-
* otherwise read characters until EOF.
254-
*/
255-
while ((c=getc(stdin))!=EOF)
256-
appendStringInfoChar(inBuf, (char)c);
257-
258-
if (inBuf->len==0)
259-
end= true;
243+
appendStringInfoChar(inBuf, (char)c);
260244
}
261245

262-
if (end)
263-
returnEOF;
264-
246+
if (c==EOF)
247+
end= true;
248+
}
249+
else
250+
{
265251
/*
266-
* otherwisewe have a user query so process it.
252+
* otherwiseread characters until EOF.
267253
*/
268-
break;
254+
while ((c=interactive_getc())!=EOF)
255+
appendStringInfoChar(inBuf, (char)c);
256+
257+
/* No input before EOF signal means time to quit. */
258+
if (inBuf->len==0)
259+
end= true;
269260
}
270261

262+
if (end)
263+
returnEOF;
264+
265+
/*
266+
* otherwise we have a user query so process it.
267+
*/
268+
271269
/* Add '\0' to make it look the same as message case. */
272270
appendStringInfoChar(inBuf, (char)'\0');
273271

@@ -281,6 +279,24 @@ InteractiveBackend(StringInfo inBuf)
281279
return'Q';
282280
}
283281

282+
/*
283+
* interactive_getc -- collect one character from stdin
284+
*
285+
* Even though we are not reading from a "client" process, we still want to
286+
* respond to signals, particularly SIGTERM/SIGQUIT. Hence we must use
287+
* prepare_for_client_read and client_read_ended.
288+
*/
289+
staticint
290+
interactive_getc(void)
291+
{
292+
intc;
293+
294+
prepare_for_client_read();
295+
c=getc(stdin);
296+
client_read_ended();
297+
returnc;
298+
}
299+
284300
/* ----------------
285301
*SocketBackend()Is called for frontend-backend connections
286302
*
@@ -3092,7 +3108,16 @@ PostgresMain(int argc, char *argv[], const char *username)
30923108
pqsignal(SIGHUP,SigHupHandler);/* set flag to read config file */
30933109
pqsignal(SIGINT,StatementCancelHandler);/* cancel current query */
30943110
pqsignal(SIGTERM,die);/* cancel current query and exit */
3095-
pqsignal(SIGQUIT,quickdie);/* hard crash time */
3111+
3112+
/*
3113+
* In a standalone backend, SIGQUIT can be generated from the keyboard
3114+
* easily, while SIGTERM cannot, so we make both signals do die() rather
3115+
* than quickdie().
3116+
*/
3117+
if (IsUnderPostmaster)
3118+
pqsignal(SIGQUIT,quickdie);/* hard crash time */
3119+
else
3120+
pqsignal(SIGQUIT,die);/* cancel current query and exit */
30963121
pqsignal(SIGALRM,handle_sig_alarm);/* timeout conditions */
30973122

30983123
/*
@@ -3113,12 +3138,15 @@ PostgresMain(int argc, char *argv[], const char *username)
31133138

31143139
pqinitmask();
31153140

3116-
/* We allow SIGQUIT (quickdie) at all times */
3141+
if (IsUnderPostmaster)
3142+
{
3143+
/* We allow SIGQUIT (quickdie) at all times */
31173144
#ifdefHAVE_SIGPROCMASK
3118-
sigdelset(&BlockSig,SIGQUIT);
3145+
sigdelset(&BlockSig,SIGQUIT);
31193146
#else
3120-
BlockSig &= ~(sigmask(SIGQUIT));
3147+
BlockSig &= ~(sigmask(SIGQUIT));
31213148
#endif
3149+
}
31223150

31233151
PG_SETMASK(&BlockSig);/* block everything except SIGQUIT */
31243152

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp