diff options
author | Bruce Momjian <bruce@momjian.us> | 1998-05-06 23:51:16 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1998-05-06 23:51:16 +0000 |
commit | edbd51395c425795b3ccacbc9d26044beb1a1277 (patch) | |
tree | 3933022b5410589db1a4d1273174b5daa7a66931 /src/bin/psql/psql.c | |
parent | 2e12331d42610e6489de85b5ca18644c0bf11f14 (diff) | |
download | postgresql-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.c | 50 |
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)); |