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

Commite6311b4

Browse files
committed
The attached patch implements some changes that were discussed acouple weeks ago on the hackers and interfaces lists:1. When the backend sends a NOTICE message and closes the connection (typically, because it was told to by the postmaster after another backend coredumped), libpq will now print the notice and close the connection cleanly. Formerly, the frontend app would usually terminate ungracefully due to a SIGPIPE. (I am not sure if 6.3.2 behaved that way, but the current cvs sources do...)2. libpq's various printouts to stderr are now fed through a single "notice processor" routine, which can be overridden by the application to direct notices someplace else. This should ease porting libpq to Windows.I also noticed and fixed a problem in PQprint: when sending outputto a pager subprocess, it would disable SIGPIPE in case the pagerterminates early (this is good) --- but afterwards it reset SIGPIPEto SIG_DFL, rather than restoring the application's prior setting(bad).regards, tom lane
1 parente46df2f commite6311b4

File tree

7 files changed

+219
-258
lines changed

7 files changed

+219
-258
lines changed

‎src/interfaces/libpq/fe-auth.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.20 1998/07/20 16:57:13 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.21 1998/08/09 02:59:25 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -445,8 +445,6 @@ pg_krb5_sendauth(const char *PQerrormsg, int sock,
445445
(void)sprintf(PQerrormsg,
446446
"pg_krb5_sendauth: authentication rejected: \"%*s\"\n",
447447
error->text.length,error->text.data);
448-
fputs(PQerrormsg,stderr);
449-
pqdebug("%s",PQerrormsg);
450448
}
451449
else
452450
{

‎src/interfaces/libpq/fe-connect.c

Lines changed: 43 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.77 1998/07/26 04:31:36 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.78 1998/08/09 02:59:26 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -29,7 +29,6 @@
2929
#include<ctype.h>
3030
#include<string.h>
3131
#include<errno.h>
32-
#include<signal.h>
3332
#include<ctype.h>/* for isspace() */
3433

3534
#include"postgres.h"
@@ -55,6 +54,7 @@ static void closePGconn(PGconn *conn);
5554
staticintconninfo_parse(constchar*conninfo,char*errorMessage);
5655
staticchar*conninfo_getval(char*keyword);
5756
staticvoidconninfo_free(void);
57+
staticvoiddefaultNoticeProcessor(void*arg,constchar*message);
5858
/* XXX Why is this not static? */
5959
voidPQsetenv(PGconn*conn);
6060

@@ -181,11 +181,7 @@ PQconnectdb(const char *conninfo)
181181
*/
182182
conn=makeEmptyPGconn();
183183
if (conn==NULL)
184-
{
185-
fprintf(stderr,
186-
"FATAL: PQconnectdb() -- unable to allocate memory for a PGconn");
187184
return (PGconn*)NULL;
188-
}
189185

190186
/* ----------
191187
* Parse the conninfo string and save settings in conn structure
@@ -297,11 +293,7 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, cons
297293

298294
conn=makeEmptyPGconn();
299295
if (conn==NULL)
300-
{
301-
fprintf(stderr,
302-
"FATAL: PQsetdbLogin() -- unable to allocate memory for a PGconn");
303296
return (PGconn*)NULL;
304-
}
305297

306298
if ((pghost==NULL)||pghost[0]=='\0')
307299
{
@@ -856,6 +848,7 @@ makeEmptyPGconn(void)
856848
/* Zero all pointers */
857849
MemSet((char*)conn,0,sizeof(PGconn));
858850

851+
conn->noticeHook=defaultNoticeProcessor;
859852
conn->status=CONNECTION_BAD;
860853
conn->asyncStatus=PGASYNC_IDLE;
861854
conn->notifyList=DLNewList();
@@ -925,35 +918,20 @@ closePGconn(PGconn *conn)
925918
if (conn->sock >=0)
926919
{
927920
/*
928-
* Try to send close message.
929-
* If connection is already gone, that's cool. No reason for kernel
930-
* to kill us when we try to write to it. So ignore SIGPIPE signals.
921+
* Try to send "close connection" message to backend.
922+
* BUT: backend might have already closed connection.
923+
* To avoid being killed by SIGPIPE, we need to detect this before
924+
* writing. Check for "read ready" condition which indicates EOF.
931925
*/
932-
#ifndefWIN32
933-
#if defined(USE_POSIX_SIGNALS)
934-
structsigactionignore_action;
935-
structsigactionoldaction;
936-
937-
ignore_action.sa_handler=SIG_IGN;
938-
sigemptyset(&ignore_action.sa_mask);
939-
ignore_action.sa_flags=0;
940-
sigaction(SIGPIPE, (structsigaction*)&ignore_action,&oldaction);
941-
942-
(void)pqPuts("X",conn);
943-
(void)pqFlush(conn);
944-
945-
sigaction(SIGPIPE,&oldaction,NULL);
946-
#else
947-
void (*oldsignal)(int);
948-
949-
oldsignal=signal(SIGPIPE,SIG_IGN);
950-
951-
(void)pqPuts("X",conn);
952-
(void)pqFlush(conn);
953-
954-
signal(SIGPIPE,oldsignal);
955-
#endif
956-
#endif/* Win32 uses no signals at all */
926+
while (pqReadReady(conn)) {
927+
if (pqReadData(conn)<0)
928+
break;
929+
}
930+
if (conn->sock >=0) {
931+
/* Should be safe now... */
932+
(void)pqPuts("X",conn);
933+
(void)pqFlush(conn);
934+
}
957935
}
958936

959937
/*
@@ -987,9 +965,7 @@ closePGconn(PGconn *conn)
987965
void
988966
PQfinish(PGconn*conn)
989967
{
990-
if (!conn)
991-
fprintf(stderr,"PQfinish() -- pointer to PGconn is null\n");
992-
else
968+
if (conn)
993969
{
994970
closePGconn(conn);
995971
freePGconn(conn);
@@ -1003,9 +979,7 @@ PQfinish(PGconn *conn)
1003979
void
1004980
PQreset(PGconn*conn)
1005981
{
1006-
if (!conn)
1007-
fprintf(stderr,"PQreset() -- pointer to PGconn is null\n");
1008-
else
982+
if (conn)
1009983
{
1010984
closePGconn(conn);
1011985
conn->status=connectDB(conn);
@@ -1383,99 +1357,72 @@ char *
13831357
PQdb(PGconn*conn)
13841358
{
13851359
if (!conn)
1386-
{
1387-
fprintf(stderr,"PQdb() -- pointer to PGconn is null\n");
13881360
return (char*)NULL;
1389-
}
13901361
returnconn->dbName;
13911362
}
13921363

13931364
char*
13941365
PQuser(PGconn*conn)
13951366
{
13961367
if (!conn)
1397-
{
1398-
fprintf(stderr,"PQuser() -- pointer to PGconn is null\n");
13991368
return (char*)NULL;
1400-
}
14011369
returnconn->pguser;
14021370
}
14031371

14041372
char*
14051373
PQhost(PGconn*conn)
14061374
{
14071375
if (!conn)
1408-
{
1409-
fprintf(stderr,"PQhost() -- pointer to PGconn is null\n");
14101376
return (char*)NULL;
1411-
}
1412-
14131377
returnconn->pghost;
14141378
}
14151379

14161380
char*
14171381
PQoptions(PGconn*conn)
14181382
{
14191383
if (!conn)
1420-
{
1421-
fprintf(stderr,"PQoptions() -- pointer to PGconn is null\n");
14221384
return (char*)NULL;
1423-
}
14241385
returnconn->pgoptions;
14251386
}
14261387

14271388
char*
14281389
PQtty(PGconn*conn)
14291390
{
14301391
if (!conn)
1431-
{
1432-
fprintf(stderr,"PQtty() -- pointer to PGconn is null\n");
14331392
return (char*)NULL;
1434-
}
14351393
returnconn->pgtty;
14361394
}
14371395

14381396
char*
14391397
PQport(PGconn*conn)
14401398
{
14411399
if (!conn)
1442-
{
1443-
fprintf(stderr,"PQport() -- pointer to PGconn is null\n");
14441400
return (char*)NULL;
1445-
}
14461401
returnconn->pgport;
14471402
}
14481403

14491404
ConnStatusType
14501405
PQstatus(PGconn*conn)
14511406
{
14521407
if (!conn)
1453-
{
1454-
fprintf(stderr,"PQstatus() -- pointer to PGconn is null\n");
14551408
returnCONNECTION_BAD;
1456-
}
14571409
returnconn->status;
14581410
}
14591411

14601412
char*
14611413
PQerrorMessage(PGconn*conn)
14621414
{
1415+
staticcharnoConn[]="PQerrorMessage: conn pointer is NULL\n";
14631416
if (!conn)
1464-
{
1465-
fprintf(stderr,"PQerrorMessage() -- pointer to PGconn is null\n");
1466-
return (char*)NULL;
1467-
}
1417+
returnnoConn;
14681418
returnconn->errorMessage;
14691419
}
14701420

14711421
int
14721422
PQsocket(PGconn*conn)
14731423
{
14741424
if (!conn)
1475-
{
1476-
fprintf(stderr,"PQsocket() -- pointer to PGconn is null\n");
14771425
return-1;
1478-
}
14791426
returnconn->sock;
14801427
}
14811428

@@ -1501,3 +1448,26 @@ PQuntrace(PGconn *conn)
15011448
conn->Pfdebug=NULL;
15021449
}
15031450
}
1451+
1452+
void
1453+
PQsetNoticeProcessor (PGconn*conn,PQnoticeProcessorproc,void*arg)
1454+
{
1455+
if (conn==NULL)
1456+
return;
1457+
conn->noticeHook=proc;
1458+
conn->noticeArg=arg;
1459+
}
1460+
1461+
/*
1462+
* The default notice/error message processor just prints the
1463+
* message on stderr. Applications can override this if they
1464+
* want the messages to go elsewhere (a window, for example).
1465+
* Note that simply discarding notices is probably a bad idea.
1466+
*/
1467+
1468+
staticvoid
1469+
defaultNoticeProcessor(void*arg,constchar*message)
1470+
{
1471+
/* Note: we expect the supplied string to end with a newline already. */
1472+
fprintf(stderr,"%s",message);
1473+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp