aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/psql.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1998-05-06 23:51:16 +0000
committerBruce Momjian <bruce@momjian.us>1998-05-06 23:51:16 +0000
commitedbd51395c425795b3ccacbc9d26044beb1a1277 (patch)
tree3933022b5410589db1a4d1273174b5daa7a66931 /src/bin/psql/psql.c
parent2e12331d42610e6489de85b5ca18644c0bf11f14 (diff)
downloadpostgresql-edbd51395c425795b3ccacbc9d26044beb1a1277.tar.gz
postgresql-edbd51395c425795b3ccacbc9d26044beb1a1277.zip
What I've done:
1. Rewritten libpq to allow asynchronous clients. 2. Implemented client side of cancel protocol in library, and patched psql.c to send a cancel request upon SIGINT. The backend doesn't notice it yet :-( 3. Implemented 'Z' protocol message addition and renaming of copy in/out start messages. These are implemented conditionally, ie, the client protocol version is checked; so the code should still work with 1.0 clients. 4. Revised protocol and libpq sgml documents (don't have an SGML compiler, though, so there may be some markup glitches here). What remains to be done: 1. Implement addition of atttypmod field to RowDescriptor messages. The client-side code is there but ifdef'd out. I have no idea what to change on the backend side. The field should be sent only if protocol >= 2.0, of course. 2. Implement backend response to cancel requests received as OOB messages. (This prolly need not be conditional on protocol version; just do it if you get SIGURG.) 3. Update libpq.3. (I'm hoping this can be generated mechanically from libpq.sgml... if not, will do it by hand.) Is there any other doco to fix? 4. Update non-libpq interfaces as necessary. I patched libpgtcl so that it would compile, but haven't tested it. Dunno what needs to be done with the other interfaces. Have at it! Tom Lane
Diffstat (limited to 'src/bin/psql/psql.c')
-rw-r--r--src/bin/psql/psql.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/bin/psql/psql.c b/src/bin/psql/psql.c
index ad2b93e93dd..1864475dd3e 100644
--- a/src/bin/psql/psql.c
+++ b/src/bin/psql/psql.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.139 1998/05/04 02:02:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.140 1998/05/06 23:50:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -284,6 +284,38 @@ PSQLexec(PsqlSettings *pset, char *query)
}
/*
+ * Code to support command cancellation.
+ * If interactive, we enable a SIGINT signal catcher that sends
+ * a cancel request to the backend.
+ * Note that sending the cancel directly from the signal handler
+ * is safe only because the cancel is sent as an OOB message.
+ * If it were inline data, then we'd risk inserting it into the
+ * middle of a normal data message by doing this.
+ * (It's probably not too cool to write on stderr, for that matter...
+ * but for debugging purposes we'll risk that.)
+ */
+
+static PGconn * cancelConn = NULL; /* connection to try cancel on */
+
+static void
+handle_sigint (SIGNAL_ARGS)
+{
+ if (cancelConn == NULL)
+ exit(1); /* accept signal if no connection */
+ /* Try to send cancel request */
+ if (PQrequestCancel(cancelConn))
+ {
+ fprintf(stderr, "\nCANCEL request sent\n");
+ }
+ else
+ {
+ fprintf(stderr, "\nCannot send cancel request:\n%s\n",
+ PQerrorMessage(cancelConn));
+ }
+}
+
+
+/*
* listAllDbs
*
* list all the databases in the system returns 0 if all went well
@@ -1099,8 +1131,7 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
exit(2); /* we are out'ta here */
}
/* check for asynchronous returns */
- notify = PQnotifies(pset->db);
- if (notify)
+ while ((notify = PQnotifies(pset->db)) != NULL)
{
fprintf(stderr,
"ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
@@ -1416,6 +1447,7 @@ do_connect(const char *new_dbname,
}
else
{
+ cancelConn = pset->db; /* redirect sigint's loving attentions */
PQfinish(olddb);
free(pset->prompt);
pset->prompt = malloc(strlen(PQdb(pset->db)) + 10);
@@ -2462,11 +2494,18 @@ main(int argc, char **argv)
settings.opt.fieldSep = strdup(DEFAULT_FIELD_SEP);
settings.opt.pager = 1;
if (!isatty(0) || !isatty(1))
+ {
+ /* Noninteractive defaults */
settings.notty = 1;
-#ifdef USE_READLINE
+ }
else
+ {
+ /* Interactive defaults */
+ pqsignal(SIGINT, handle_sigint); /* control-C => cancel */
+#ifdef USE_READLINE
settings.useReadline = 1;
#endif
+ }
#ifdef PSQL_ALWAYS_GET_PASSWORDS
settings.getPassword = 1;
#else
@@ -2580,6 +2619,9 @@ main(int argc, char **argv)
PQfinish(settings.db);
exit(1);
}
+
+ cancelConn = settings.db; /* enable SIGINT to send cancel */
+
if (listDatabases)
{
exit(listAllDbs(&settings));