diff -cpr head/src/bin/scripts/clusterdb.c working/src/bin/scripts/clusterdb.c
*** head/src/bin/scripts/clusterdb.c	2007-02-14 03:06:18.000000000 +0900
--- working/src/bin/scripts/clusterdb.c	2007-03-19 10:08:40.000000000 +0900
*************** main(int argc, char *argv[])
*** 111,116 ****
--- 111,118 ----
  			exit(1);
  	}
  
+ 	setup_cancel_handler();
+ 
  	if (alldb)
  	{
  		if (dbname)
*************** cluster_one_database(const char *dbname,
*** 159,165 ****
  	PQExpBufferData sql;
  
  	PGconn	   *conn;
- 	PGresult   *result;
  
  	initPQExpBuffer(&sql);
  
--- 161,166 ----
*************** cluster_one_database(const char *dbname,
*** 169,180 ****
  	appendPQExpBuffer(&sql, ";\n");
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
! 
! 	if (echo)
! 		printf("%s", sql.data);
! 	result = PQexec(conn, sql.data);
! 
! 	if (PQresultStatus(result) != PGRES_COMMAND_OK)
  	{
  		if (table)
  			fprintf(stderr, _("%s: clustering of table \"%s\" in database \"%s\" failed: %s"),
--- 170,176 ----
  	appendPQExpBuffer(&sql, ";\n");
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
! 	if (!executeMaintenance(conn, sql.data, echo))
  	{
  		if (table)
  			fprintf(stderr, _("%s: clustering of table \"%s\" in database \"%s\" failed: %s"),
*************** cluster_one_database(const char *dbname,
*** 185,192 ****
  		PQfinish(conn);
  		exit(1);
  	}
- 
- 	PQclear(result);
  	PQfinish(conn);
  	termPQExpBuffer(&sql);
  
--- 181,186 ----
diff -cpr head/src/bin/scripts/common.c working/src/bin/scripts/common.c
*** head/src/bin/scripts/common.c	2007-01-06 07:19:50.000000000 +0900
--- working/src/bin/scripts/common.c	2007-03-19 10:08:00.000000000 +0900
***************
*** 15,28 ****
--- 15,38 ----
  #include "postgres_fe.h"
  
  #include <pwd.h>
+ #include <signal.h>
  #include <unistd.h>
  
  #include "common.h"
+ #include "libpq/pqsignal.h"
+ 
+ static void SetCancelConn(PGconn *conn);
+ static void ResetCancelConn(void);
  
  #ifndef HAVE_INT_OPTRESET
  int			optreset;
  #endif
  
+ static PGcancel *volatile cancelConn = NULL;
+ 
+ #ifdef WIN32
+ static CRITICAL_SECTION cancelConnLock;
+ #endif
  
  /*
   * Returns the current user name.
*************** executeCommand(PGconn *conn, const char 
*** 195,200 ****
--- 205,231 ----
  
  
  /*
+  * As above for a SQL command (returns succeeded status).
+  */
+ bool
+ executeMaintenance(PGconn *conn, const char *query, bool echo)
+ {
+ 	PGresult   *res;
+ 	bool		r;
+ 
+ 	if (echo)
+ 		printf("%s\n", query);
+ 
+ 	SetCancelConn(conn);
+ 	res = PQexec(conn, query);
+ 	ResetCancelConn();
+ 	r = (res && PQresultStatus(res) == PGRES_COMMAND_OK);
+ 	PQclear(res);
+ 	return r;
+ }
+ 
+ 
+ /*
   * Check yes/no answer in a localized way.	1=yes, 0=no, -1=neither.
   */
  
*************** yesno_prompt(const char *question)
*** 237,239 ****
--- 268,396 ----
  			   _(PG_YESLETTER), _(PG_NOLETTER));
  	}
  }
+ 
+ 
+ /*
+  * SetCancelConn
+  *
+  * Set cancelConn to point to the current database connection.
+  */
+ static void
+ SetCancelConn(PGconn *conn)
+ {
+ 	PGcancel   *oldCancelConn;
+ 
+ #ifdef WIN32
+ 	EnterCriticalSection(&cancelConnLock);
+ #endif
+ 
+ 	/* Free the old one if we have one */
+ 	oldCancelConn = cancelConn;
+ 	/* be sure handle_sigint doesn't use pointer while freeing */
+ 	cancelConn = NULL;
+ 
+ 	if (oldCancelConn != NULL)
+ 		PQfreeCancel(oldCancelConn);
+ 
+ 	cancelConn = PQgetCancel(conn);
+ 
+ #ifdef WIN32
+ 	LeaveCriticalSection(&cancelConnLock);
+ #endif
+ }
+ 
+ /*
+  * ResetCancelConn
+  *
+  * Free the current cancel connection, if any, and set to NULL.
+  */
+ static void
+ ResetCancelConn(void)
+ {
+ 	PGcancel   *oldCancelConn;
+ 
+ #ifdef WIN32
+ 	EnterCriticalSection(&cancelConnLock);
+ #endif
+ 
+ 	oldCancelConn = cancelConn;
+ 	/* be sure handle_sigint doesn't use pointer while freeing */
+ 	cancelConn = NULL;
+ 
+ 	if (oldCancelConn != NULL)
+ 		PQfreeCancel(oldCancelConn);
+ 
+ #ifdef WIN32
+ 	LeaveCriticalSection(&cancelConnLock);
+ #endif
+ }
+ 
+ #ifndef WIN32
+ 
+ static void
+ handle_sigint(SIGNAL_ARGS)
+ {
+ 	int			save_errno = errno;
+ 	char		errbuf[256];
+ 
+ 	/* Send QueryCancel if we are processing a database query */
+ 	if (cancelConn != NULL)
+ 	{
+ 		if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
+ 			fprintf(stderr, _("Cancel request sent\n"));
+ 		else
+ 		{
+ 			fprintf(stderr, _("Could not send cancel request: "));
+ 			fprintf(stderr, errbuf);
+ 		}
+ 	}
+ 
+ 	errno = save_errno;			/* just in case the write changed it */
+ }
+ 
+ void
+ setup_cancel_handler(void)
+ {
+ 	pqsignal(SIGINT, handle_sigint);
+ }
+ 
+ #else							/* WIN32 */
+ 
+ static BOOL WINAPI
+ consoleHandler(DWORD dwCtrlType)
+ {
+ 	char		errbuf[256];
+ 
+ 	if (dwCtrlType == CTRL_C_EVENT ||
+ 		dwCtrlType == CTRL_BREAK_EVENT)
+ 	{
+ 		/* Send QueryCancel if we are processing a database query */
+ 		EnterCriticalSection(&cancelConnLock);
+ 		if (cancelConn != NULL)
+ 		{
+ 			if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
+ 				fprintf(stderr, _("Cancel request sent\n"));
+ 			else
+ 			{
+ 				fprintf(stderr, _("Could not send cancel request: "));
+ 				fprintf(stderr, errbuf);
+ 			}
+ 		}
+ 		LeaveCriticalSection(&cancelConnLock);
+ 
+ 		return TRUE;
+ 	}
+ 	else
+ 		/* Return FALSE for any signals not being handled */
+ 		return FALSE;
+ }
+ 
+ void
+ setup_cancel_handler(void)
+ {
+ 	InitializeCriticalSection(&cancelConnLock);
+ 
+ 	SetConsoleCtrlHandler(consoleHandler, TRUE);
+ }
+ 
+ #endif   /* WIN32 */
diff -cpr head/src/bin/scripts/common.h working/src/bin/scripts/common.h
*** head/src/bin/scripts/common.h	2007-01-06 07:19:50.000000000 +0900
--- working/src/bin/scripts/common.h	2007-03-19 10:02:27.000000000 +0900
***************
*** 17,22 ****
--- 17,24 ----
  extern int	optreset;
  #endif
  
+ extern bool cancel_pressed;
+ 
  typedef void (*help_handler) (const char *progname);
  
  extern const char *get_user_name(const char *progname);
*************** extern PGresult *executeQuery(PGconn *co
*** 35,40 ****
--- 37,47 ----
  extern void executeCommand(PGconn *conn, const char *query,
  			   const char *progname, bool echo);
  
+ extern bool executeMaintenance(PGconn *conn, const char *query,
+ 							   bool echo);
+ 
  extern bool yesno_prompt(const char *question);
  
+ extern void setup_cancel_handler(void);
+ 
  #endif   /* COMMON_H */
diff -cpr head/src/bin/scripts/reindexdb.c working/src/bin/scripts/reindexdb.c
*** head/src/bin/scripts/reindexdb.c	2007-02-14 03:06:18.000000000 +0900
--- working/src/bin/scripts/reindexdb.c	2007-03-19 10:09:05.000000000 +0900
*************** main(int argc, char *argv[])
*** 126,131 ****
--- 126,133 ----
  			exit(1);
  	}
  
+ 	setup_cancel_handler();
+ 
  	if (alldb)
  	{
  		if (dbname)
*************** reindex_one_database(const char *name, c
*** 214,220 ****
  	PQExpBufferData sql;
  
  	PGconn	   *conn;
- 	PGresult   *result;
  
  	initPQExpBuffer(&sql);
  
--- 216,221 ----
*************** reindex_one_database(const char *name, c
*** 229,239 ****
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
  
! 	if (echo)
! 		printf("%s", sql.data);
! 	result = PQexec(conn, sql.data);
! 
! 	if (PQresultStatus(result) != PGRES_COMMAND_OK)
  	{
  		if (strcmp(type, "TABLE") == 0)
  			fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"),
--- 230,236 ----
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
  
! 	if (!executeMaintenance(conn, sql.data, echo))
  	{
  		if (strcmp(type, "TABLE") == 0)
  			fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"),
*************** reindex_one_database(const char *name, c
*** 248,254 ****
  		exit(1);
  	}
  
- 	PQclear(result);
  	PQfinish(conn);
  	termPQExpBuffer(&sql);
  
--- 245,250 ----
*************** reindex_system_catalogs(const char *dbna
*** 294,320 ****
  	PQExpBufferData sql;
  
  	PGconn	   *conn;
- 	PGresult   *result;
  
  	initPQExpBuffer(&sql);
  
  	appendPQExpBuffer(&sql, "REINDEX SYSTEM %s;\n", dbname);
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
! 
! 	if (echo)
! 		printf("%s", sql.data);
! 	result = PQexec(conn, sql.data);
! 
! 	if (PQresultStatus(result) != PGRES_COMMAND_OK)
  	{
  		fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),
  				progname, PQerrorMessage(conn));
  		PQfinish(conn);
  		exit(1);
  	}
- 
- 	PQclear(result);
  	PQfinish(conn);
  	termPQExpBuffer(&sql);
  
--- 290,308 ----
  	PQExpBufferData sql;
  
  	PGconn	   *conn;
  
  	initPQExpBuffer(&sql);
  
  	appendPQExpBuffer(&sql, "REINDEX SYSTEM %s;\n", dbname);
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
! 	if (!executeMaintenance(conn, sql.data, echo))
  	{
  		fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),
  				progname, PQerrorMessage(conn));
  		PQfinish(conn);
  		exit(1);
  	}
  	PQfinish(conn);
  	termPQExpBuffer(&sql);
  
diff -cpr head/src/bin/scripts/vacuumdb.c working/src/bin/scripts/vacuumdb.c
*** head/src/bin/scripts/vacuumdb.c	2007-02-14 02:39:39.000000000 +0900
--- working/src/bin/scripts/vacuumdb.c	2007-03-19 10:08:21.000000000 +0900
*************** main(int argc, char *argv[])
*** 128,133 ****
--- 128,135 ----
  			exit(1);
  	}
  
+ 	setup_cancel_handler();
+ 
  	if (alldb)
  	{
  		if (dbname)
*************** vacuum_one_database(const char *dbname, 
*** 178,184 ****
  	PQExpBufferData sql;
  
  	PGconn	   *conn;
- 	PGresult   *result;
  
  	initPQExpBuffer(&sql);
  
--- 180,185 ----
*************** vacuum_one_database(const char *dbname, 
*** 194,205 ****
  	appendPQExpBuffer(&sql, ";\n");
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
! 
! 	if (echo)
! 		printf("%s", sql.data);
! 	result = PQexec(conn, sql.data);
! 
! 	if (PQresultStatus(result) != PGRES_COMMAND_OK)
  	{
  		if (table)
  			fprintf(stderr, _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
--- 195,201 ----
  	appendPQExpBuffer(&sql, ";\n");
  
  	conn = connectDatabase(dbname, host, port, username, password, progname);
! 	if (!executeMaintenance(conn, sql.data, echo))
  	{
  		if (table)
  			fprintf(stderr, _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
*************** vacuum_one_database(const char *dbname, 
*** 210,217 ****
  		PQfinish(conn);
  		exit(1);
  	}
- 
- 	PQclear(result);
  	PQfinish(conn);
  	termPQExpBuffer(&sql);
  
--- 206,211 ----
