aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/async.c12
-rw-r--r--src/backend/libpq/auth.c72
-rw-r--r--src/backend/libpq/pqcomm.c80
-rw-r--r--src/backend/libpq/pqpacket.c18
-rw-r--r--src/backend/postmaster/postmaster.c124
-rw-r--r--src/backend/tcop/postgres.c40
-rw-r--r--src/backend/utils/init/globals.c4
7 files changed, 193 insertions, 157 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index b4b354cfc52..b80cbb8f345 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.34 1998/06/27 04:53:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.35 1998/07/09 03:28:44 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,11 +21,11 @@
* 2.a If the process is the same as the backend process that issued
* notification (we are notifying something that we are listening),
* signal the corresponding frontend over the comm channel.
- * 2.b For all other listening processes, we send kill(2) to wake up
+ * 2.b For all other listening processes, we send kill(SIGUSR2) to wake up
* the listening backend.
- * 3. Upon receiving a kill(2) signal from another backend process notifying
- * that one of the relation that we are listening is being notified,
- * we can be in either of two following states:
+ * 3. Upon receiving a kill(SIGUSR2) signal from another backend process
+ * notifying that one of the relation that we are listening is being
+ * notified, we can be in either of two following states:
* 3.a We are sleeping, wake up and signal our frontend.
* 3.b We are in middle of another transaction, wait until the end of
* of the current transaction and signal our frontend.
@@ -46,7 +46,7 @@
* (which takes place after commit) to all listeners on this relation.
*
* 3. Async. notification results in all backends listening on relation
- * to be woken up, by a process signal kill(2), with name of relation
+ * to be woken up, by a process signal kill(SIGUSR2), with name of relation
* passed in shared memory.
*
* 4. Each backend notifies its respective frontend over the comm
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 4aee9b9197a..c1cc08f4c79 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.28 1998/06/13 04:27:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.29 1998/07/09 03:28:45 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,13 +40,13 @@
#include <libpq/crypt.h>
-static void sendAuthRequest(Port *port, AuthRequest areq, void (*handler) ());
-static void handle_done_auth(Port *port);
-static void handle_krb4_auth(Port *port);
-static void handle_krb5_auth(Port *port);
-static void handle_password_auth(Port *port);
-static void readPasswordPacket(char *arg, PacketLen len, char *pkt);
-static void pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt);
+static void sendAuthRequest(Port *port, AuthRequest areq, PacketDoneProc handler);
+static int handle_done_auth(void *arg, PacketLen len, void *pkt);
+static int handle_krb4_auth(void *arg, PacketLen len, void *pkt);
+static int handle_krb5_auth(void *arg, PacketLen len, void *pkt);
+static int handle_password_auth(void *arg, PacketLen len, void *pkt);
+static int readPasswordPacket(void *arg, PacketLen len, void *pkt);
+static int pg_passwordv0_recvauth(void *arg, PacketLen len, void *pkt);
static int checkPassword(Port *port, char *user, char *password);
static int old_be_recvauth(Port *port);
static int map_old_to_new(Port *port, UserAuth old, int status);
@@ -327,8 +327,8 @@ pg_krb5_recvauth(Port *port)
* Handle a v0 password packet.
*/
-static void
-pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
+static int
+pg_passwordv0_recvauth(void *arg, PacketLen len, void *pkt)
{
Port *port;
PasswordPacketV0 *pp;
@@ -393,6 +393,8 @@ pg_passwordv0_recvauth(char *arg, PacketLen len, char *pkt)
if (map_old_to_new(port, uaPassword, status) != STATUS_OK)
auth_failed(port);
}
+
+ return (STATUS_OK); /* don't close the connection yet */
}
@@ -433,7 +435,7 @@ be_recvauth(Port *port)
else
{
AuthRequest areq;
- void (*auth_handler) ();
+ PacketDoneProc auth_handler;
/* Keep the compiler quiet. */
@@ -499,7 +501,7 @@ be_recvauth(Port *port)
*/
static void
-sendAuthRequest(Port *port, AuthRequest areq, void (*handler) ())
+sendAuthRequest(Port *port, AuthRequest areq, PacketDoneProc handler)
{
char *dp,
*sp;
@@ -527,7 +529,7 @@ sendAuthRequest(Port *port, AuthRequest areq, void (*handler) ())
i += 2;
}
- PacketSendSetup(&port->pktInfo, i, handler, (char *) port);
+ PacketSendSetup(&port->pktInfo, i, handler, (void *) port);
}
@@ -535,8 +537,8 @@ sendAuthRequest(Port *port, AuthRequest areq, void (*handler) ())
* Called when we have told the front end that it is authorised.
*/
-static void
-handle_done_auth(Port *port)
+static int
+handle_done_auth(void *arg, PacketLen len, void *pkt)
{
/*
@@ -544,7 +546,7 @@ handle_done_auth(Port *port)
* start.
*/
- return;
+ return STATUS_OK;
}
@@ -553,13 +555,17 @@ handle_done_auth(Port *port)
* authentication.
*/
-static void
-handle_krb4_auth(Port *port)
+static int
+handle_krb4_auth(void *arg, PacketLen len, void *pkt)
{
+ Port *port = (Port *) arg;
+
if (pg_krb4_recvauth(port) != STATUS_OK)
auth_failed(port);
else
sendAuthRequest(port, AUTH_REQ_OK, handle_done_auth);
+
+ return STATUS_OK;
}
@@ -568,13 +574,17 @@ handle_krb4_auth(Port *port)
* authentication.
*/
-static void
-handle_krb5_auth(Port *port)
+static int
+handle_krb5_auth(void *arg, PacketLen len, void *pkt)
{
+ Port *port = (Port *) arg;
+
if (pg_krb5_recvauth(port) != STATUS_OK)
auth_failed(port);
else
sendAuthRequest(port, AUTH_REQ_OK, handle_done_auth);
+
+ return STATUS_OK;
}
@@ -583,12 +593,16 @@ handle_krb5_auth(Port *port)
* authentication.
*/
-static void
-handle_password_auth(Port *port)
+static int
+handle_password_auth(void *arg, PacketLen len, void *pkt)
{
+ Port *port = (Port *) arg;
+
/* Set up the read of the password packet. */
- PacketReceiveSetup(&port->pktInfo, readPasswordPacket, (char *) port);
+ PacketReceiveSetup(&port->pktInfo, readPasswordPacket, (void *) port);
+
+ return STATUS_OK;
}
@@ -596,13 +610,11 @@ handle_password_auth(Port *port)
* Called when we have received the password packet.
*/
-static void
-readPasswordPacket(char *arg, PacketLen len, char *pkt)
+static int
+readPasswordPacket(void *arg, PacketLen len, void *pkt)
{
char password[sizeof(PasswordPacket) + 1];
- Port *port;
-
- port = (Port *) arg;
+ Port *port = (Port *) arg;
/* Silently truncate a password that is too big. */
@@ -615,6 +627,8 @@ readPasswordPacket(char *arg, PacketLen len, char *pkt)
auth_failed(port);
else
sendAuthRequest(port, AUTH_REQ_OK, handle_done_auth);
+
+ return (STATUS_OK); /* don't close the connection yet */
}
@@ -662,7 +676,7 @@ old_be_recvauth(Port *port)
case STARTUP_PASSWORD_MSG:
PacketReceiveSetup(&port->pktInfo, pg_passwordv0_recvauth,
- (char *) port);
+ (void *) port);
return STATUS_OK;
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index a70bbc22e9c..4c5b85b248b 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.47 1998/06/27 04:53:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.48 1998/07/09 03:28:46 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,7 +30,6 @@
* pq_getinserv - initialize address from host and service name
* pq_connect - create remote input / output connection
* pq_accept - accept remote input / output connection
- * pq_async_notify - receive notification from backend.
*
* NOTES
* These functions are used by both frontend applications and
@@ -79,7 +78,6 @@
FILE *Pfout,
*Pfin;
FILE *Pfdebug; /* debugging libpq */
-int PQAsyncNotifyWaiting; /* for async. notification */
/* --------------------------------
* pq_init - open portal file descriptors
@@ -160,9 +158,7 @@ pq_close()
fclose(Pfout);
Pfout = NULL;
}
- PQAsyncNotifyWaiting = 0;
PQnotifies_init();
- pq_unregoob();
}
/* --------------------------------
@@ -418,29 +414,6 @@ pq_putint(int i, int b)
}
}
-/* ---
- * pq_sendoob - send a string over the out-of-band channel
- * pq_recvoob - receive a string over the oob channel
- * NB: Fortunately, the out-of-band channel doesn't conflict with
- * buffered I/O because it is separate from regular com. channel.
- * ---
- */
-int
-pq_sendoob(char *msg, int len)
-{
- int fd = fileno(Pfout);
-
- return send(fd, msg, len, MSG_OOB);
-}
-
-int
-pq_recvoob(char *msgPtr, int len)
-{
- int fd = fileno(Pfout);
-
- return recv(fd, msgPtr, len, MSG_OOB);
-}
-
/* --------------------------------
* pq_getinaddr - initialize address from host and port number
* --------------------------------
@@ -508,55 +481,6 @@ pq_getinserv(struct sockaddr_in * sin, char *host, char *serv)
}
/*
- * register an out-of-band listener proc--at most one allowed.
- * This is used for receiving async. notification from the backend.
- */
-void
-pq_regoob(void (*fptr) ())
-{
- int fd = fileno(Pfout);
-
-#if defined(hpux)
- ioctl(fd, FIOSSAIOOWN, MyProcPid);
-#elif defined(sco)
- ioctl(fd, SIOCSPGRP, MyProcPid);
-#else
- fcntl(fd, F_SETOWN, MyProcPid);
-#endif /* hpux */
- pqsignal(SIGURG, fptr);
-}
-
-void
-pq_unregoob()
-{
- pqsignal(SIGURG, SIG_DFL);
-}
-
-
-void
-pq_async_notify()
-{
- char msg[20];
-
- /* int len = sizeof(msg); */
- int len = 20;
-
- if (pq_recvoob(msg, len) >= 0)
- {
- /* debugging */
- printf("received notification: %s\n", msg);
- PQAsyncNotifyWaiting = 1;
- /* PQappendNotify(msg+1); */
- }
- else
- {
- extern int errno;
-
- printf("SIGURG but no data: len = %d, err=%d\n", len, errno);
- }
-}
-
-/*
* Streams -- wrapper around Unix socket system calls
*
*
@@ -620,7 +544,7 @@ StreamServerPort(char *hostName, short portName, int *fdP)
pqdebug("%s", PQerrormsg);
return (STATUS_ERROR);
}
- bzero(&saddr, sizeof(saddr));
+ MemSet((char *) &saddr, 0, sizeof(saddr));
saddr.sa.sa_family = family;
if (family == AF_UNIX)
{
diff --git a/src/backend/libpq/pqpacket.c b/src/backend/libpq/pqpacket.c
index 97caae952ac..631af78ce29 100644
--- a/src/backend/libpq/pqpacket.c
+++ b/src/backend/libpq/pqpacket.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.15 1998/02/26 04:31:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.16 1998/07/09 03:28:46 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,7 +33,7 @@
* Set up a packet read for the postmaster event loop.
*/
-void PacketReceiveSetup(Packet *pkt, void (*iodone) (), char *arg)
+void PacketReceiveSetup(Packet *pkt, PacketDoneProc iodone, void *arg)
{
pkt->nrtodo = sizeof(pkt->len);
pkt->ptr = (char *) &pkt->len;
@@ -94,8 +94,8 @@ PacketReceiveFragment(Packet *pkt, int sock)
if (pkt->iodone == NULL)
return STATUS_ERROR;
- (*pkt->iodone) (pkt->arg, pkt->len - sizeof(pkt->len),
- (char *) &pkt->pkt);
+ return (*pkt->iodone) (pkt->arg, pkt->len - sizeof(pkt->len),
+ (void *) &pkt->pkt);
}
return STATUS_OK;
@@ -107,7 +107,7 @@ PacketReceiveFragment(Packet *pkt, int sock)
if (errno == EINTR)
return STATUS_OK;
- fprintf(stderr, "read() system call failed\n");
+ perror("PacketReceiveFragment: read() failed");
return STATUS_ERROR;
}
@@ -117,8 +117,9 @@ PacketReceiveFragment(Packet *pkt, int sock)
* Set up a packet write for the postmaster event loop.
*/
-void PacketSendSetup(Packet *pkt, int nbytes, void (*iodone) (), char *arg)
+void PacketSendSetup(Packet *pkt, int nbytes, PacketDoneProc iodone, void *arg)
{
+ pkt->len = (PacketLen) nbytes;
pkt->nrtodo = nbytes;
pkt->ptr = (char *) &pkt->pkt;
pkt->iodone = iodone;
@@ -153,7 +154,8 @@ PacketSendFragment(Packet *pkt, int sock)
if (pkt->iodone == NULL)
return STATUS_ERROR;
- (*pkt->iodone) (pkt->arg);
+ return (*pkt->iodone) (pkt->arg, pkt->len,
+ (void *) &pkt->pkt);
}
return STATUS_OK;
@@ -165,7 +167,7 @@ PacketSendFragment(Packet *pkt, int sock)
if (errno == EINTR)
return STATUS_OK;
- fprintf(stderr, "write() system call failed\n");
+ perror("PacketSendFragment: write() failed");
return STATUS_ERROR;
}
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 60d998814d1..7f33dfedba3 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.92 1998/06/27 14:06:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.93 1998/07/09 03:28:47 scrappy Exp $
*
* NOTES
*
@@ -206,7 +206,6 @@ static int orgsigmask = sigblock(0);
*/
static unsigned int random_seed = 0;
-long MyCancelKey = 0;
extern char *optarg;
extern int optind,
@@ -228,7 +227,8 @@ static void ExitPostmaster(int status);
static void usage(const char *);
static int ServerLoop(void);
static int BackendStartup(Port *port);
-static void readStartupPacket(char *arg, PacketLen len, char *pkt);
+static int readStartupPacket(void *arg, PacketLen len, void *pkt);
+static int processCancelRequest(Port *port, PacketLen len, void *pkt);
static int initMasks(fd_set *rmask, fd_set *wmask);
static long PostmasterRandom(void);
static void RandomSalt(char *salt);
@@ -518,6 +518,10 @@ PostmasterMain(int argc, char *argv[])
if (silentflag)
pmdaemonize();
+ /*
+ * Set up signal handlers for the postmaster process.
+ */
+
pqsignal(SIGINT, pmdie);
pqsignal(SIGCHLD, reaper);
pqsignal(SIGTTIN, SIG_IGN);
@@ -657,14 +661,14 @@ ServerLoop(void)
(port = ConnCreate(ServerSock_UNIX)) != NULL)
PacketReceiveSetup(&port->pktInfo,
readStartupPacket,
- (char *) port);
+ (void *) port);
if (ServerSock_INET != INVALID_SOCK &&
FD_ISSET(ServerSock_INET, &rmask) &&
(port = ConnCreate(ServerSock_INET)) != NULL)
PacketReceiveSetup(&port->pktInfo,
readStartupPacket,
- (char *) port);
+ (void *) port);
/* Build up new masks for select(). */
@@ -790,8 +794,8 @@ initMasks(fd_set *rmask, fd_set *wmask)
* Called when the startup packet has been read.
*/
-static void
-readStartupPacket(char *arg, PacketLen len, char *pkt)
+static int
+readStartupPacket(void *arg, PacketLen len, void *pkt)
{
Port *port;
StartupPacket *si;
@@ -799,6 +803,28 @@ readStartupPacket(char *arg, PacketLen len, char *pkt)
port = (Port *) arg;
si = (StartupPacket *) pkt;
+ /* The first field is either a protocol version number or
+ * a special request code.
+ */
+
+ port->proto = ntohl(si->protoVersion);
+
+ if (port->proto == CANCEL_REQUEST_CODE)
+ return processCancelRequest(port, len, pkt);
+
+ /* Could add additional special packet types here */
+
+ /* Check we can handle the protocol the frontend is using. */
+
+ if (PG_PROTOCOL_MAJOR(port->proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) ||
+ PG_PROTOCOL_MAJOR(port->proto) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST) ||
+ (PG_PROTOCOL_MAJOR(port->proto) == PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST) &&
+ PG_PROTOCOL_MINOR(port->proto) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)))
+ {
+ PacketSendError(&port->pktInfo, "Unsupported frontend protocol.");
+ return STATUS_OK; /* don't close the connection yet */
+ }
+
/*
* Get the parameters from the startup packet as C strings. The
* packet destination was cleared first so a short packet has zeros
@@ -815,31 +841,74 @@ readStartupPacket(char *arg, PacketLen len, char *pkt)
if (port->database[0] == '\0')
StrNCpy(port->database, si->user, sizeof(port->database) - 1);
- /* Check we can handle the protocol the frontend is using. */
-
- port->proto = ntohl(si->protoVersion);
-
- if (PG_PROTOCOL_MAJOR(port->proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) ||
- PG_PROTOCOL_MAJOR(port->proto) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST) ||
- (PG_PROTOCOL_MAJOR(port->proto) == PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST) &&
- PG_PROTOCOL_MINOR(port->proto) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)))
- {
- PacketSendError(&port->pktInfo, "Unsupported frontend protocol.");
- return;
- }
-
/* Check a user name was given. */
if (port->user[0] == '\0')
{
PacketSendError(&port->pktInfo,
"No Postgres username specified in startup packet.");
- return;
+ return STATUS_OK; /* don't close the connection yet */
}
/* Start the authentication itself. */
be_recvauth(port);
+
+ return STATUS_OK; /* don't close the connection yet */
+}
+
+
+/*
+ * The client has sent a cancel request packet, not a normal
+ * start-a-new-backend packet. Perform the necessary processing.
+ * Note that in any case, we return STATUS_ERROR to close the
+ * connection immediately. Nothing is sent back to the client.
+ */
+
+static int
+processCancelRequest(Port *port, PacketLen len, void *pkt)
+{
+ CancelRequestPacket *canc = (CancelRequestPacket *) pkt;
+ int backendPID;
+ long cancelAuthCode;
+ Dlelem *curr;
+ Backend *bp;
+
+ backendPID = (int) ntohl(canc->backendPID);
+ cancelAuthCode = (long) ntohl(canc->cancelAuthCode);
+
+ /* See if we have a matching backend */
+
+ for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr))
+ {
+ bp = (Backend *) DLE_VAL(curr);
+ if (bp->pid == backendPID)
+ {
+ if (bp->cancel_key == cancelAuthCode)
+ {
+ /* Found a match; signal that backend to cancel current op */
+ if (DebugLvl)
+ fprintf(stderr, "%s: processCancelRequest: sending SIGINT to process %d\n",
+ progname, bp->pid);
+ kill(bp->pid, SIGINT);
+ }
+ else
+ {
+ /* Right PID, wrong key: no way, Jose */
+ if (DebugLvl)
+ fprintf(stderr, "%s: processCancelRequest: bad key in cancel request for process %d\n",
+ progname, bp->pid);
+ }
+ return STATUS_ERROR;
+ }
+ }
+
+ /* No matching backend */
+ if (DebugLvl)
+ fprintf(stderr, "%s: processCancelRequest: bad PID in cancel request for process %d\n",
+ progname, backendPID);
+
+ return STATUS_ERROR;
}
@@ -1221,6 +1290,8 @@ DoBackend(Port *port)
char dbbuf[ARGV_SIZE + 1];
int ac = 0;
int i;
+ struct timeval now;
+ struct timezone tz;
/*
* Let's clean up ourselves as the postmaster child
@@ -1254,7 +1325,16 @@ DoBackend(Port *port)
if (NetServer)
StreamClose(ServerSock_INET);
StreamClose(ServerSock_UNIX);
-
+
+ /*
+ * Don't want backend to be able to see the postmaster random number
+ * generator state. We have to clobber the static random_seed *and*
+ * start a new random sequence in the random() library function.
+ */
+ random_seed = 0;
+ gettimeofday(&now, &tz);
+ srandom(now.tv_usec);
+
/* Now, on to standard postgres stuff */
MyProcPid = getpid();
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 97ac571d2c6..0a7408a7b94 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.78 1998/06/27 04:53:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.79 1998/07/09 03:28:48 scrappy Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -724,7 +724,7 @@ pg_exec_query_dest(char *query_string, /* string to execute */
/* --------------------------------
* signal handler routines used in PostgresMain()
*
- * handle_warn() is used to catch kill(getpid(),1) which
+ * handle_warn() is used to catch kill(getpid(), SIGHUP) which
* occurs when elog(ERROR) is called.
*
* quickdie() occurs when signalled by the postmaster.
@@ -777,7 +777,7 @@ FloatExceptionHandler(SIGNAL_ARGS)
}
-/* signal handler for query cancel */
+/* signal handler for query cancel signal from postmaster */
static void
QueryCancelHandler(SIGNAL_ARGS)
{
@@ -787,12 +787,9 @@ QueryCancelHandler(SIGNAL_ARGS)
void
CancelQuery(void)
{
- char dummy;
-
- /* throw it away */
- while (pq_recvoob(&dummy, 1) > 0)
- ;
- /* QueryCancel reset in longjump after elog() call */
+ /* QueryCancel flag will be reset in main loop, which we reach by
+ * longjmp from elog().
+ */
elog(ERROR, "Query was cancelled.");
}
@@ -1261,7 +1258,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
}
pq_init(Portfd);
whereToSendOutput = Remote;
- pq_regoob(QueryCancelHandler); /* we do it here so the backend it connected */
}
else
whereToSendOutput = Debug;
@@ -1288,13 +1284,31 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
#endif
/* ----------------
+ * Set up handler for cancel-request signal, and
+ * send this backend's cancellation info to the frontend.
+ * This should not be done until we are sure startup is successful.
+ * ----------------
+ */
+
+ pqsignal(SIGINT, QueryCancelHandler);
+
+ if (whereToSendOutput == Remote &&
+ PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
+ {
+ pq_putnchar("K", 1);
+ pq_putint((int32) MyProcPid, sizeof(int32));
+ pq_putint((int32) MyCancelKey, sizeof(int32));
+ /* Need not flush since ReadyForQuery will do it. */
+ }
+
+ /* ----------------
* if an exception is encountered, processing resumes here
* so we abort the current transaction and start a new one.
* This must be done after we initialize the slave backends
* so that the slaves signal the master to abort the transaction
* rather than calling AbortCurrentTransaction() themselves.
*
- * Note: elog(ERROR) causes a kill(getpid(),1) to occur sending
+ * Note: elog(ERROR) causes a kill(getpid(), SIGHUP) to occur sending
* us back here.
* ----------------
*/
@@ -1325,7 +1339,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface");
- puts("$Revision: 1.78 $ $Date: 1998/06/27 04:53:43 $");
+ puts("$Revision: 1.79 $ $Date: 1998/07/09 03:28:48 $");
}
/* ----------------
@@ -1431,7 +1445,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
break;
default:
- elog(ERROR, "unknown frontend message was recieved");
+ elog(ERROR, "unknown frontend message was received");
}
/* ----------------
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 2deec81de00..585471d37f6 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.23 1998/05/29 17:00:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.24 1998/07/09 03:28:51 scrappy Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
@@ -44,6 +44,8 @@ bool QueryCancel = false;
int MyProcPid;
+long MyCancelKey;
+
char *DataDir;
/*