diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
new file mode 100644
index b05364c..377984d
*** a/src/backend/libpq/be-secure-openssl.c
--- b/src/backend/libpq/be-secure-openssl.c
*************** rloop:
*** 543,550 ****
  					 errmsg("SSL error: %s", SSLerrmessage())));
  			/* fall through */
  		case SSL_ERROR_ZERO_RETURN:
! 			errno = ECONNRESET;
! 			n = -1;
  			break;
  		default:
  			ereport(COMMERROR,
--- 543,553 ----
  					 errmsg("SSL error: %s", SSLerrmessage())));
  			/* fall through */
  		case SSL_ERROR_ZERO_RETURN:
! 			if (!IdleTransactionCancelPending) /* HACK */
! 			{
! 				errno = ECONNRESET;
! 				n = -1;
! 			}
  			break;
  		default:
  			ereport(COMMERROR,
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
new file mode 100644
index 41ec1ad..44079ff
*** a/src/backend/libpq/be-secure.c
--- b/src/backend/libpq/be-secure.c
*************** secure_raw_read(Port *port, void *ptr, s
*** 145,155 ****
  {
  	ssize_t		n;
  
! 	prepare_for_client_read();
  
! 	n = recv(port->sock, ptr, len, 0);
  
! 	client_read_ended();
  
  	return n;
  }
--- 145,160 ----
  {
  	ssize_t		n;
  
! 	if (IdleTransactionCancelPending)
! 		n = 0; /* simulate EOF */
! 	else
! 	{
! 		prepare_for_client_read();
  
! 		n = recv(port->sock, ptr, len, 0);
  
! 		client_read_ended();
! 	}
  
  	return n;
  }
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
new file mode 100644
index cc62b2c..37437fc
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
*************** interactive_getc(void)
*** 310,318 ****
  {
  	int			c;
  
! 	prepare_for_client_read();
! 	c = getc(stdin);
! 	client_read_ended();
  	return c;
  }
  
--- 310,323 ----
  {
  	int			c;
  
! 	if (IdleTransactionCancelPending)
! 		c = EOF;
! 	else
! 	{
! 		prepare_for_client_read();
! 		c = getc(stdin);
! 		client_read_ended();
! 	}
  	return c;
  }
  
*************** StatementCancelHandler(SIGNAL_ARGS)
*** 2629,2642 ****
  	if (!proc_exit_inprogress)
  	{
  		InterruptPending = true;
! 		QueryCancelPending = true;
  
  		/*
  		 * If it's safe to interrupt, and we're waiting for input or a lock,
  		 * service the interrupt immediately
  		 */
  		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
! 			CritSectionCount == 0)
  		{
  			/* bump holdoff count to make ProcessInterrupts() a no-op */
  			/* until we are done getting ready for it */
--- 2634,2655 ----
  	if (!proc_exit_inprogress)
  	{
  		InterruptPending = true;
! 
! 		if (!DoingCommandRead)
! 			QueryCancelPending = true;
! 		else if (IsTransactionOrTransactionBlock())
! 			IdleTransactionCancelPending = true;
  
  		/*
  		 * If it's safe to interrupt, and we're waiting for input or a lock,
  		 * service the interrupt immediately
  		 */
  		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
! 			CritSectionCount == 0 && QueryCancelPending)
! 			/*
! 			 * ProcessInterrupts() does nothing in case of
! 			 * IdleTransactionCancelPending, it is handled in PostgresMain
! 			 */
  		{
  			/* bump holdoff count to make ProcessInterrupts() a no-op */
  			/* until we are done getting ready for it */
*************** PostgresMain(int argc, char *argv[],
*** 4216,4221 ****
--- 4229,4247 ----
  				 */
  			case 'X':
  			case EOF:
+ 				if (IdleTransactionCancelPending)
+ 				{
+ 					IdleTransactionCancelPending = false;
+ 
+ 					ereport(NOTICE,
+ 							(errcode(ERRCODE_QUERY_CANCELED),
+ 							 errmsg("canceling idle transaction due to administrator request")));
+ 
+ 					/*AbortTransactionAndAnySubtransactions();*/
+ 					/* ... */
+ 
+ 					break; /* live on */
+ 				}
  
  				/*
  				 * Reset whereToSendOutput to prevent ereport from attempting
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
new file mode 100644
index be74835..fba92b2
*** a/src/backend/utils/init/globals.c
--- b/src/backend/utils/init/globals.c
*************** ProtocolVersion FrontendProtocol;
*** 28,33 ****
--- 28,34 ----
  
  volatile bool InterruptPending = false;
  volatile bool QueryCancelPending = false;
+ volatile bool IdleTransactionCancelPending = false;
  volatile bool ProcDiePending = false;
  volatile bool ClientConnectionLost = false;
  volatile bool ImmediateInterruptOK = false;
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
new file mode 100644
index 1558a75..ec1047c
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
***************
*** 75,80 ****
--- 75,81 ----
  /* these are marked volatile because they are set by signal handlers: */
  extern PGDLLIMPORT volatile bool InterruptPending;
  extern PGDLLIMPORT volatile bool QueryCancelPending;
+ extern PGDLLIMPORT volatile bool IdleTransactionCancelPending;
  extern PGDLLIMPORT volatile bool ProcDiePending;
  
  extern volatile bool ClientConnectionLost;
